Commit 1acba85b by Johannes Singler Committed by Johannes Singler

algobase.h: Uglify internal identifiers.

2009-09-16  Johannes Singler  <singler@ira.uka.de>

        * include/parallel/algobase.h: Uglify internal identifiers.
        * include/parallel/algo.h: Likewise.
        * include/parallel/algorithmfwd.h: Likewise.
        * include/parallel/balanced_quicksort.h: Likewise.
        * include/parallel/base.h: Likewise.
        * include/parallel/checkers.h: Likewise.
        * include/parallel/compatibility.h: Likewise.
        * include/parallel/compiletime_settings.: Likewise.
        * include/parallel/equally_split.h: Likewise.
        * include/parallel/features.h: Likewise.
        * include/parallel/find.h: Likewise.
        * include/parallel/find_selectors.h: Likewise.
        * include/parallel/for_each.h: Likewise.
        * include/parallel/for_each_selectors.h: Likewise.
        * include/parallel/iterator.h: Likewise.
        * include/parallel/list_partition.h: Likewise.
        * include/parallel/losertree.h: Likewise.
        * include/parallel/merge.h: Likewise.
        * include/parallel/multiseq_selection.h: Likewise.
        * include/parallel/multiway_merge.h: Likewise.
        * include/parallel/multiway_mergesort.h: Likewise.
        * include/parallel/numeric: Likewise.
        * include/parallel/numericfwd.h: Likewise.
        * include/parallel/omp_loop.h: Likewise.
        * include/parallel/omp_loop_static.h: Likewise.
        * include/parallel/par_loop.h: Likewise.
        * include/parallel/partial_sum.h: Likewise.
        * include/parallel/partition.h: Likewise.
        * include/parallel/queue.h: Likewise.
        * include/parallel/quicksort.h: Likewise.
        * include/parallel/random_number.h: Likewise.
        * include/parallel/random_shuffle.h: Likewise.
        * include/parallel/search.h: Likewise.
        * include/parallel/set_operations.h: Likewise.
        * include/parallel/settings.h: Likewise.
        * include/parallel/sort.h: Likewise.
        * include/parallel/tags.h: Likewise.
        * include/parallel/types.h: Likewise.
        * include/parallel/unique_copy.h: Likewise.
        * include/parallel/workstealing.h: Likewise.

From-SVN: r151741
parent 4075e7e8
2009-09-16 Johannes Singler <singler@ira.uka.de>
* include/parallel/algobase.h: Uglify internal identifiers.
* include/parallel/algo.h: Likewise.
* include/parallel/algorithm: Likewise.
* include/parallel/algorithmfwd.h: Likewise.
* include/parallel/balanced_quicksort.h: Likewise.
* include/parallel/base.h: Likewise.
* include/parallel/basic_iterator.h: Likewise.
* include/parallel/checkers.h: Likewise.
* include/parallel/compatibility.h: Likewise.
* include/parallel/compiletime_settings.: Likewise.
* include/parallel/equally_split.h: Likewise.
* include/parallel/features.h: Likewise.
* include/parallel/find.h: Likewise.
* include/parallel/find_selectors.h: Likewise.
* include/parallel/for_each.h: Likewise.
* include/parallel/for_each_selectors.h: Likewise.
* include/parallel/iterator.h: Likewise.
* include/parallel/list_partition.h: Likewise.
* include/parallel/losertree.h: Likewise.
* include/parallel/merge.h: Likewise.
* include/parallel/multiseq_selection.h: Likewise.
* include/parallel/multiway_merge.h: Likewise.
* include/parallel/multiway_mergesort.h: Likewise.
* include/parallel/numeric: Likewise.
* include/parallel/numericfwd.h: Likewise.
* include/parallel/omp_loop.h: Likewise.
* include/parallel/omp_loop_static.h: Likewise.
* include/parallel/parallel.h: Likewise.
* include/parallel/par_loop.h: Likewise.
* include/parallel/partial_sum.h: Likewise.
* include/parallel/partition.h: Likewise.
* include/parallel/queue.h: Likewise.
* include/parallel/quicksort.h: Likewise.
* include/parallel/random_number.h: Likewise.
* include/parallel/random_shuffle.h: Likewise.
* include/parallel/search.h: Likewise.
* include/parallel/set_operations.h: Likewise.
* include/parallel/settings.h: Likewise.
* include/parallel/sort.h: Likewise.
* include/parallel/tags.h: Likewise.
* include/parallel/types.h: Likewise.
* include/parallel/unique_copy.h: Likewise.
* include/parallel/workstealing.h: Likewise.
2009-09-14 Paolo Carlini <paolo.carlini@oracle.com> 2009-09-14 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/41037 PR libstdc++/41037
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -50,230 +50,230 @@ namespace __parallel ...@@ -50,230 +50,230 @@ namespace __parallel
// NB: equal and lexicographical_compare require mismatch. // NB: equal and lexicographical_compare require mismatch.
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline pair<InputIterator1, InputIterator2> inline pair<_IIter1, _IIter2>
mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2); } { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2); }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline pair<InputIterator1, InputIterator2> inline pair<_IIter1, _IIter2>
mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
Predicate pred, __gnu_parallel::sequential_tag) _Predicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred); } { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
// Sequential fallback for input iterator case // Sequential fallback for input iterator case
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate, typename IteratorTag1, typename IteratorTag2> typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
inline pair<InputIterator1, InputIterator2> inline pair<_IIter1, _IIter2>
mismatch_switch(InputIterator1 begin1, InputIterator1 end1, __mismatch_switch(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, Predicate pred, IteratorTag1, _IIter2 __begin2, _Predicate __pred, _IteratorTag1,
IteratorTag2) _IteratorTag2)
{ return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred); } { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
// Parallel mismatch for random access iterators // Parallel mismatch for random access iterators
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Predicate> typename _Predicate>
pair<RandomAccessIterator1, RandomAccessIterator2> pair<_RAIter1, _RAIter2>
mismatch_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Predicate pred, _RAIter2 __begin2, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag) random_access_iterator_tag, random_access_iterator_tag)
{ {
if (_GLIBCXX_PARALLEL_CONDITION(true)) if (_GLIBCXX_PARALLEL_CONDITION(true))
{ {
RandomAccessIterator1 res = _RAIter1 __res =
__gnu_parallel::find_template(begin1, end1, begin2, pred, __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
__gnu_parallel:: __gnu_parallel::
mismatch_selector()).first; __mismatch_selector()).first;
return make_pair(res , begin2 + (res - begin1)); return make_pair(__res , __begin2 + (__res - __begin1));
} }
else else
return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred); return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred);
} }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline pair<InputIterator1, InputIterator2> inline pair<_IIter1, _IIter2>
mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2) mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
{ {
typedef std::iterator_traits<InputIterator1> iterator1_traits; typedef std::iterator_traits<_IIter1> iterator1_traits;
typedef std::iterator_traits<InputIterator2> iterator2_traits; typedef std::iterator_traits<_IIter2> iterator2_traits;
typedef typename iterator1_traits::value_type value1_type; typedef typename iterator1_traits::value_type _ValueType1;
typedef typename iterator2_traits::value_type value2_type; typedef typename iterator2_traits::value_type _ValueType2;
typedef typename iterator1_traits::iterator_category iterator1_category; typedef typename iterator1_traits::iterator_category _IteratorCategory1;
typedef typename iterator2_traits::iterator_category iterator2_category; typedef typename iterator2_traits::iterator_category _IteratorCategory2;
typedef __gnu_parallel::equal_to<value1_type, value2_type> equal_to_type; typedef __gnu_parallel::equal_to<_ValueType1, _ValueType2> equal_to_type;
return mismatch_switch(begin1, end1, begin2, equal_to_type(), return __mismatch_switch(__begin1, __end1, __begin2, equal_to_type(),
iterator1_category(), iterator2_category()); _IteratorCategory1(), _IteratorCategory2());
} }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline pair<InputIterator1, InputIterator2> inline pair<_IIter1, _IIter2>
mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
Predicate pred) _Predicate __pred)
{ {
typedef std::iterator_traits<InputIterator1> iterator1_traits; typedef std::iterator_traits<_IIter1> iterator1_traits;
typedef std::iterator_traits<InputIterator2> iterator2_traits; typedef std::iterator_traits<_IIter2> iterator2_traits;
typedef typename iterator1_traits::iterator_category iterator1_category; typedef typename iterator1_traits::iterator_category _IteratorCategory1;
typedef typename iterator2_traits::iterator_category iterator2_category; typedef typename iterator2_traits::iterator_category _IteratorCategory2;
return mismatch_switch(begin1, end1, begin2, pred, iterator1_category(), return __mismatch_switch(__begin1, __end1, __begin2, __pred, _IteratorCategory1(),
iterator2_category()); _IteratorCategory2());
} }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline bool inline bool
equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::equal(begin1, end1, begin2); } { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2); }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline bool inline bool
equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
Predicate pred, __gnu_parallel::sequential_tag) _Predicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::equal(begin1, end1, begin2, pred); } { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2, __pred); }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline bool inline bool
equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2) equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
{ return mismatch(begin1, end1, begin2).first == end1; } { return mismatch(__begin1, __end1, __begin2).first == __end1; }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline bool inline bool
equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
Predicate pred) _Predicate __pred)
{ return mismatch(begin1, end1, begin2, pred).first == end1; } { return mismatch(__begin1, __end1, __begin2, __pred).first == __end1; }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline bool inline bool
lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, InputIterator2 end2, _IIter2 __begin2, _IIter2 __end2,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1, { return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
begin2, end2); } __begin2, __end2); }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline bool inline bool
lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, InputIterator2 end2, _IIter2 __begin2, _IIter2 __end2,
Predicate pred, __gnu_parallel::sequential_tag) _Predicate __pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1, { return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
begin2, end2, pred); } __begin2, __end2, __pred); }
// Sequential fallback for input iterator case // Sequential fallback for input iterator case
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate, typename IteratorTag1, typename IteratorTag2> typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
inline bool inline bool
lexicographical_compare_switch(InputIterator1 begin1, InputIterator1 end1, __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, InputIterator2 end2, _IIter2 __begin2, _IIter2 __end2,
Predicate pred, IteratorTag1, IteratorTag2) _Predicate __pred, _IteratorTag1, _IteratorTag2)
{ return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1, { return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
begin2, end2, pred); } __begin2, __end2, __pred); }
// Parallel lexicographical_compare for random access iterators // Parallel lexicographical_compare for random access iterators
// Limitation: Both valuetypes must be the same // Limitation: Both valuetypes must be the same
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Predicate> typename _Predicate>
bool bool
lexicographical_compare_switch(RandomAccessIterator1 begin1, __lexicographical_compare_switch(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, _RAIter2 __begin2,
RandomAccessIterator2 end2, Predicate pred, _RAIter2 __end2, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag) random_access_iterator_tag)
{ {
if (_GLIBCXX_PARALLEL_CONDITION(true)) if (_GLIBCXX_PARALLEL_CONDITION(true))
{ {
typedef iterator_traits<RandomAccessIterator1> traits1_type; typedef iterator_traits<_RAIter1> _TraitsType1;
typedef typename traits1_type::value_type value1_type; typedef typename _TraitsType1::value_type _ValueType1;
typedef iterator_traits<RandomAccessIterator2> traits2_type; typedef iterator_traits<_RAIter2> _TraitsType2;
typedef typename traits2_type::value_type value2_type; typedef typename _TraitsType2::value_type _ValueType2;
typedef __gnu_parallel::equal_from_less<Predicate, value1_type, typedef __gnu_parallel::_EqualFromLess<_Predicate, _ValueType1,
value2_type> equal_type; _ValueType2> _EqualFromLessCompare;
// Longer sequence in first place. // Longer sequence in first place.
if ((end1 - begin1) < (end2 - begin2)) if ((__end1 - __begin1) < (__end2 - __begin2))
{ {
typedef pair<RandomAccessIterator1, RandomAccessIterator2> typedef pair<_RAIter1, _RAIter2>
pair_type; _SpotType;
pair_type mm = mismatch_switch(begin1, end1, begin2, _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
equal_type(pred), _EqualFromLessCompare(__pred),
random_access_iterator_tag(), random_access_iterator_tag(),
random_access_iterator_tag()); random_access_iterator_tag());
return (mm.first == end1) || bool(pred(*mm.first, *mm.second)); return (__mm.first == __end1) || bool(__pred(*__mm.first, *__mm.second));
} }
else else
{ {
typedef pair<RandomAccessIterator2, RandomAccessIterator1> typedef pair<_RAIter2, _RAIter1>
pair_type; _SpotType;
pair_type mm = mismatch_switch(begin2, end2, begin1, _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
equal_type(pred), _EqualFromLessCompare(__pred),
random_access_iterator_tag(), random_access_iterator_tag(),
random_access_iterator_tag()); random_access_iterator_tag());
return (mm.first != end2) && bool(pred(*mm.second, *mm.first)); return (__mm.first != __end2) && bool(__pred(*__mm.second, *__mm.first));
} }
} }
else else
return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1, return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
begin2, end2, pred); __begin2, __end2, __pred);
} }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2> template<typename _IIter1, typename _IIter2>
inline bool inline bool
lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, InputIterator2 end2) _IIter2 __begin2, _IIter2 __end2)
{ {
typedef iterator_traits<InputIterator1> traits1_type; typedef iterator_traits<_IIter1> _TraitsType1;
typedef typename traits1_type::value_type value1_type; typedef typename _TraitsType1::value_type _ValueType1;
typedef typename traits1_type::iterator_category iterator1_category; typedef typename _TraitsType1::iterator_category _IteratorCategory1;
typedef iterator_traits<InputIterator2> traits2_type; typedef iterator_traits<_IIter2> _TraitsType2;
typedef typename traits2_type::value_type value2_type; typedef typename _TraitsType2::value_type _ValueType2;
typedef typename traits2_type::iterator_category iterator2_category; typedef typename _TraitsType2::iterator_category _IteratorCategory2;
typedef __gnu_parallel::less<value1_type, value2_type> less_type; typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
return lexicographical_compare_switch(begin1, end1, begin2, end2, return __lexicographical_compare_switch(__begin1, __end1, __begin2, __end2,
less_type(), iterator1_category(), _LessType(), _IteratorCategory1(),
iterator2_category()); _IteratorCategory2());
} }
// Public interface // Public interface
template<typename InputIterator1, typename InputIterator2, template<typename _IIter1, typename _IIter2,
typename Predicate> typename _Predicate>
inline bool inline bool
lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
InputIterator2 begin2, InputIterator2 end2, _IIter2 __begin2, _IIter2 __end2,
Predicate pred) _Predicate __pred)
{ {
typedef iterator_traits<InputIterator1> traits1_type; typedef iterator_traits<_IIter1> _TraitsType1;
typedef typename traits1_type::iterator_category iterator1_category; typedef typename _TraitsType1::iterator_category _IteratorCategory1;
typedef iterator_traits<InputIterator2> traits2_type; typedef iterator_traits<_IIter2> _TraitsType2;
typedef typename traits2_type::iterator_category iterator2_category; typedef typename _TraitsType2::iterator_category _IteratorCategory2;
return lexicographical_compare_switch(begin1, end1, begin2, end2, pred, return __lexicographical_compare_switch(__begin1, __end1, __begin2, __end2, __pred,
iterator1_category(), _IteratorCategory1(),
iterator2_category()); _IteratorCategory2());
} }
} // end namespace } // end namespace
} // end namespace } // end namespace
......
...@@ -48,11 +48,11 @@ namespace __parallel ...@@ -48,11 +48,11 @@ namespace __parallel
template<typename _FIter, typename _IterTag> template<typename _FIter, typename _IterTag>
_FIter _FIter
adjacent_find_switch(_FIter, _FIter, _IterTag); __adjacent_find_switch(_FIter, _FIter, _IterTag);
template<typename _RAIter> template<typename _RAIter>
_RAIter _RAIter
adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag); __adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag);
template<typename _FIter, typename _BiPredicate> template<typename _FIter, typename _BiPredicate>
...@@ -66,11 +66,11 @@ namespace __parallel ...@@ -66,11 +66,11 @@ namespace __parallel
template<typename _FIter, typename _BiPredicate, typename _IterTag> template<typename _FIter, typename _BiPredicate, typename _IterTag>
_FIter _FIter
adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag); __adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag);
template<typename _RAIter, typename _BiPredicate> template<typename _RAIter, typename _BiPredicate>
_RAIter _RAIter
adjacent_find_switch(_RAIter, _RAIter, _BiPredicate, __adjacent_find_switch(_RAIter, _RAIter, _BiPredicate,
random_access_iterator_tag); random_access_iterator_tag);
...@@ -88,12 +88,12 @@ namespace __parallel ...@@ -88,12 +88,12 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _IterTag> template<typename _IIter, typename _Tp, typename _IterTag>
typename iterator_traits<_IIter>::difference_type typename iterator_traits<_IIter>::difference_type
count_switch(_IIter, _IIter, const _Tp&, _IterTag); __count_switch(_IIter, _IIter, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp> template<typename _RAIter, typename _Tp>
typename iterator_traits<_RAIter>::difference_type typename iterator_traits<_RAIter>::difference_type
count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag, __count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_unbalanced); = __gnu_parallel::parallel_unbalanced);
...@@ -111,12 +111,12 @@ namespace __parallel ...@@ -111,12 +111,12 @@ namespace __parallel
template<typename _IIter, typename _Predicate, typename _IterTag> template<typename _IIter, typename _Predicate, typename _IterTag>
typename iterator_traits<_IIter>::difference_type typename iterator_traits<_IIter>::difference_type
count_if_switch(_IIter, _IIter, _Predicate, _IterTag); __count_if_switch(_IIter, _IIter, _Predicate, _IterTag);
template<typename _RAIter, typename _Predicate> template<typename _RAIter, typename _Predicate>
typename iterator_traits<_RAIter>::difference_type typename iterator_traits<_RAIter>::difference_type
count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag, __count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_unbalanced); = __gnu_parallel::parallel_unbalanced);
// algobase.h // algobase.h
...@@ -124,18 +124,18 @@ namespace __parallel ...@@ -124,18 +124,18 @@ namespace __parallel
bool bool
equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename Predicate> template<typename _IIter1, typename _IIter2, typename _Predicate>
bool bool
equal(_IIter1, _IIter1, _IIter2, Predicate, equal(_IIter1, _IIter1, _IIter2, _Predicate,
__gnu_parallel::sequential_tag); __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2> template<typename _IIter1, typename _IIter2>
bool bool
equal(_IIter1, _IIter1, _IIter2); equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename Predicate> template<typename _IIter1, typename _IIter2, typename _Predicate>
bool bool
equal(_IIter1, _IIter1, _IIter2, Predicate); equal(_IIter1, _IIter1, _IIter2, _Predicate);
template<typename _IIter, typename _Tp> template<typename _IIter, typename _Tp>
_IIter _IIter
...@@ -143,15 +143,15 @@ namespace __parallel ...@@ -143,15 +143,15 @@ namespace __parallel
template<typename _IIter, typename _Tp> template<typename _IIter, typename _Tp>
_IIter _IIter
find(_IIter, _IIter, const _Tp& val); find(_IIter, _IIter, const _Tp& __val);
template<typename _IIter, typename _Tp, typename _IterTag> template<typename _IIter, typename _Tp, typename _IterTag>
_IIter _IIter
find_switch(_IIter, _IIter, const _Tp&, _IterTag); __find_switch(_IIter, _IIter, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp> template<typename _RAIter, typename _Tp>
_RAIter _RAIter
find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag); __find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag);
template<typename _IIter, typename _Predicate> template<typename _IIter, typename _Predicate>
_IIter _IIter
...@@ -163,11 +163,11 @@ namespace __parallel ...@@ -163,11 +163,11 @@ namespace __parallel
template<typename _IIter, typename _Predicate, typename _IterTag> template<typename _IIter, typename _Predicate, typename _IterTag>
_IIter _IIter
find_if_switch(_IIter, _IIter, _Predicate, _IterTag); __find_if_switch(_IIter, _IIter, _Predicate, _IterTag);
template<typename _RAIter, typename _Predicate> template<typename _RAIter, typename _Predicate>
_RAIter _RAIter
find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag); __find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag);
template<typename _IIter, typename _FIter> template<typename _IIter, typename _FIter>
_IIter _IIter
...@@ -190,18 +190,18 @@ namespace __parallel ...@@ -190,18 +190,18 @@ namespace __parallel
template<typename _IIter, typename _FIter, template<typename _IIter, typename _FIter,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
_IIter _IIter
find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2); __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2);
template<typename _RAIter, typename _FIter, typename _BiPredicate, template<typename _RAIter, typename _FIter, typename _BiPredicate,
typename _IterTag> typename _IterTag>
_RAIter _RAIter
find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate, __find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate,
random_access_iterator_tag, _IterTag); random_access_iterator_tag, _IterTag);
template<typename _IIter, typename _FIter, typename _BiPredicate, template<typename _IIter, typename _FIter, typename _BiPredicate,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
_IIter _IIter
find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate, __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate,
_IterTag1, _IterTag2); _IterTag1, _IterTag2);
...@@ -219,12 +219,12 @@ namespace __parallel ...@@ -219,12 +219,12 @@ namespace __parallel
template<typename _IIter, typename _Function, typename _IterTag> template<typename _IIter, typename _Function, typename _IterTag>
_Function _Function
for_each_switch(_IIter, _IIter, _Function, _IterTag); __for_each_switch(_IIter, _IIter, _Function, _IterTag);
template<typename _RAIter, typename _Function> template<typename _RAIter, typename _Function>
_Function _Function
for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag, __for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
...@@ -242,12 +242,12 @@ namespace __parallel ...@@ -242,12 +242,12 @@ namespace __parallel
template<typename _FIter, typename _Generator, typename _IterTag> template<typename _FIter, typename _Generator, typename _IterTag>
void void
generate_switch(_FIter, _FIter, _Generator, _IterTag); __generate_switch(_FIter, _FIter, _Generator, _IterTag);
template<typename _RAIter, typename _Generator> template<typename _RAIter, typename _Generator>
void void
generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag, __generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
template<typename _OIter, typename _Size, typename _Generator> template<typename _OIter, typename _Size, typename _Generator>
...@@ -265,12 +265,12 @@ namespace __parallel ...@@ -265,12 +265,12 @@ namespace __parallel
template<typename _OIter, typename _Size, typename _Generator, template<typename _OIter, typename _Size, typename _Generator,
typename _IterTag> typename _IterTag>
_OIter _OIter
generate_n_switch(_OIter, _Size, _Generator, _IterTag); __generate_n_switch(_OIter, _Size, _Generator, _IterTag);
template<typename _RAIter, typename _Size, typename _Generator> template<typename _RAIter, typename _Size, typename _Generator>
_RAIter _RAIter
generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag, __generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2> template<typename _IIter1, typename _IIter2>
...@@ -294,12 +294,12 @@ namespace __parallel ...@@ -294,12 +294,12 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, template<typename _IIter1, typename _IIter2,
typename _Predicate, typename _IterTag1, typename _IterTag2> typename _Predicate, typename _IterTag1, typename _IterTag2>
bool bool
lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, __lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2,
_Predicate, _IterTag1, _IterTag2); _Predicate, _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _Predicate> template<typename _RAIter1, typename _RAIter2, typename _Predicate>
bool bool
lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, __lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
_Predicate, random_access_iterator_tag, _Predicate, random_access_iterator_tag,
random_access_iterator_tag); random_access_iterator_tag);
...@@ -324,12 +324,12 @@ namespace __parallel ...@@ -324,12 +324,12 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, typename _Predicate, template<typename _IIter1, typename _IIter2, typename _Predicate,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
pair<_IIter1, _IIter2> pair<_IIter1, _IIter2>
mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate, __mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate,
_IterTag1, _IterTag2); _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _Predicate> template<typename _RAIter1, typename _RAIter2, typename _Predicate>
pair<_RAIter1, _RAIter2> pair<_RAIter1, _RAIter2>
mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate, __mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2> template<typename _FIter1, typename _FIter2>
...@@ -351,23 +351,23 @@ namespace __parallel ...@@ -351,23 +351,23 @@ namespace __parallel
template<typename _RAIter1, typename _RAIter2> template<typename _RAIter1, typename _RAIter2>
_RAIter1 _RAIter1
search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2, typename _IterTag1, template<typename _FIter1, typename _FIter2, typename _IterTag1,
typename _IterTag2> typename _IterTag2>
_FIter1 _FIter1
search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2); __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _BiPredicate> template<typename _RAIter1, typename _RAIter2, typename _BiPredicate>
_RAIter1 _RAIter1
search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate, __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2, typename _BiPredicate, template<typename _FIter1, typename _FIter2, typename _BiPredicate,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
_FIter1 _FIter1
search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate,
_IterTag1, _IterTag2); _IterTag1, _IterTag2);
template<typename _FIter, typename _Integer, typename _Tp> template<typename _FIter, typename _Integer, typename _Tp>
...@@ -393,42 +393,42 @@ namespace __parallel ...@@ -393,42 +393,42 @@ namespace __parallel
template<typename _RAIter, typename _Integer, typename _Tp, template<typename _RAIter, typename _Integer, typename _Tp,
typename _BiPredicate> typename _BiPredicate>
_RAIter _RAIter
search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&, __search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&,
_BiPredicate, random_access_iterator_tag); _BiPredicate, random_access_iterator_tag);
template<typename _FIter, typename _Integer, typename _Tp, template<typename _FIter, typename _Integer, typename _Tp,
typename _BiPredicate, typename _IterTag> typename _BiPredicate, typename _IterTag>
_FIter _FIter
search_n_switch(_FIter, _FIter, _Integer, const _Tp&, __search_n_switch(_FIter, _FIter, _Integer, const _Tp&,
_BiPredicate, _IterTag); _BiPredicate, _IterTag);
template<typename _IIter, typename _OIter, typename UnaryOperation> template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter _OIter
transform(_IIter, _IIter, _OIter, UnaryOperation); transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter, typename _OIter, typename UnaryOperation> template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter _OIter
transform(_IIter, _IIter, _OIter, UnaryOperation, transform(_IIter, _IIter, _OIter, _UnaryOperation,
__gnu_parallel::sequential_tag); __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename UnaryOperation> template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter _OIter
transform(_IIter, _IIter, _OIter, UnaryOperation, transform(_IIter, _IIter, _OIter, _UnaryOperation,
__gnu_parallel::_Parallelism); __gnu_parallel::_Parallelism);
template<typename _IIter, typename _OIter, typename UnaryOperation, template<typename _IIter, typename _OIter, typename _UnaryOperation,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
_OIter _OIter
transform1_switch(_IIter, _IIter, _OIter, UnaryOperation, __transform1_switch(_IIter, _IIter, _OIter, _UnaryOperation,
_IterTag1, _IterTag2); _IterTag1, _IterTag2);
template<typename _RAIIter, typename _RAOIter, typename UnaryOperation> template<typename _RAIIter, typename _RAOIter, typename _UnaryOperation>
_RAOIter _RAOIter
transform1_switch(_RAIIter, _RAIIter, _RAOIter, UnaryOperation, __transform1_switch(_RAIIter, _RAIIter, _RAOIter, _UnaryOperation,
random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
...@@ -452,17 +452,17 @@ namespace __parallel ...@@ -452,17 +452,17 @@ namespace __parallel
template<typename _RAIter1, typename _RAIter2, typename _RAIter3, template<typename _RAIter1, typename _RAIter2, typename _RAIter3,
typename _BiOperation> typename _BiOperation>
_RAIter3 _RAIter3
transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, __transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation,
random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2, typename _OIter, template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BiOperation, typename _Tag1, typename _BiOperation, typename _Tag1,
typename _Tag2, typename _Tag3> typename _Tag2, typename _Tag3>
_OIter _OIter
transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
_Tag1, _Tag2, _Tag3); _Tag1, _Tag2, _Tag3);
...@@ -482,11 +482,11 @@ namespace __parallel ...@@ -482,11 +482,11 @@ namespace __parallel
template<typename _FIter, typename _Tp, typename _IterTag> template<typename _FIter, typename _Tp, typename _IterTag>
void void
replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag); __replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp> template<typename _RAIter, typename _Tp>
void void
replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&, __replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&,
random_access_iterator_tag, __gnu_parallel::_Parallelism); random_access_iterator_tag, __gnu_parallel::_Parallelism);
...@@ -507,11 +507,11 @@ namespace __parallel ...@@ -507,11 +507,11 @@ namespace __parallel
template<typename _FIter, typename _Predicate, typename _Tp, template<typename _FIter, typename _Predicate, typename _Tp,
typename _IterTag> typename _IterTag>
void void
replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag); __replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag);
template<typename _RAIter, typename _Predicate, typename _Tp> template<typename _RAIter, typename _Predicate, typename _Tp>
void void
replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&, __replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism); __gnu_parallel::_Parallelism);
...@@ -542,12 +542,12 @@ namespace __parallel ...@@ -542,12 +542,12 @@ namespace __parallel
template<typename _FIter, typename _Compare, typename _IterTag> template<typename _FIter, typename _Compare, typename _IterTag>
_FIter _FIter
max_element_switch(_FIter, _FIter, _Compare, _IterTag); __max_element_switch(_FIter, _FIter, _Compare, _IterTag);
template<typename _RAIter, typename _Compare> template<typename _RAIter, typename _Compare>
_RAIter _RAIter
max_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag, __max_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
...@@ -575,13 +575,13 @@ namespace __parallel ...@@ -575,13 +575,13 @@ namespace __parallel
typename _Compare, typename _IterTag1, typename _IterTag2, typename _Compare, typename _IterTag1, typename _IterTag2,
typename _IterTag3> typename _IterTag3>
_OIter _OIter
merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
_IterTag1, _IterTag2, _IterTag3); _IterTag1, _IterTag2, _IterTag3);
template<typename _IIter1, typename _IIter2, typename _OIter, template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare> typename _Compare>
_OIter _OIter
merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag); random_access_iterator_tag);
...@@ -596,7 +596,7 @@ namespace __parallel ...@@ -596,7 +596,7 @@ namespace __parallel
template<typename _FIter> template<typename _FIter>
_FIter _FIter
min_element(_FIter, _FIter, __gnu_parallel::_Parallelism parallelism_tag); min_element(_FIter, _FIter, __gnu_parallel::_Parallelism __parallelism_tag);
template<typename _FIter, typename _Compare> template<typename _FIter, typename _Compare>
_FIter _FIter
...@@ -612,12 +612,12 @@ namespace __parallel ...@@ -612,12 +612,12 @@ namespace __parallel
template<typename _FIter, typename _Compare, typename _IterTag> template<typename _FIter, typename _Compare, typename _IterTag>
_FIter _FIter
min_element_switch(_FIter, _FIter, _Compare, _IterTag); __min_element_switch(_FIter, _FIter, _Compare, _IterTag);
template<typename _RAIter, typename _Compare> template<typename _RAIter, typename _Compare>
_RAIter _RAIter
min_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag, __min_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_balanced); = __gnu_parallel::parallel_balanced);
template<typename _RAIter> template<typename _RAIter>
...@@ -654,21 +654,21 @@ namespace __parallel ...@@ -654,21 +654,21 @@ namespace __parallel
void void
partial_sort(_RAIter, _RAIter, _RAIter); partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _FIter, typename Predicate> template<typename _FIter, typename _Predicate>
_FIter _FIter
partition(_FIter, _FIter, Predicate, __gnu_parallel::sequential_tag); partition(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag);
template<typename _FIter, typename Predicate> template<typename _FIter, typename _Predicate>
_FIter _FIter
partition(_FIter, _FIter, Predicate); partition(_FIter, _FIter, _Predicate);
template<typename _FIter, typename Predicate, typename _IterTag> template<typename _FIter, typename _Predicate, typename _IterTag>
_FIter _FIter
partition_switch(_FIter, _FIter, Predicate, _IterTag); __partition_switch(_FIter, _FIter, _Predicate, _IterTag);
template<typename _RAIter, typename Predicate> template<typename _RAIter, typename _Predicate>
_RAIter _RAIter
partition_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag); __partition_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag);
template<typename _RAIter> template<typename _RAIter>
void void
...@@ -693,9 +693,9 @@ namespace __parallel ...@@ -693,9 +693,9 @@ namespace __parallel
__gnu_parallel::sequential_tag); __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, template<typename _IIter1, typename _IIter2, typename _OIter,
typename Predicate> typename _Predicate>
_OIter _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate,
__gnu_parallel::sequential_tag); __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter> template<typename _IIter1, typename _IIter2, typename _OIter>
...@@ -711,13 +711,13 @@ namespace __parallel ...@@ -711,13 +711,13 @@ namespace __parallel
typename _OIter, typename _IterTag1, typename _IterTag2, typename _OIter, typename _IterTag1, typename _IterTag2,
typename _IterTag3> typename _IterTag3>
_OIter _OIter
set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
_Predicate, _IterTag1, _IterTag2, _IterTag3); _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
typename _Predicate> typename _Predicate>
_Output_RAIter _Output_RAIter
set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, __set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter,
_Predicate, random_access_iterator_tag, _Predicate, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
...@@ -745,13 +745,13 @@ namespace __parallel ...@@ -745,13 +745,13 @@ namespace __parallel
typename _OIter, typename _IterTag1, typename _IterTag2, typename _OIter, typename _IterTag1, typename _IterTag2,
typename _IterTag3> typename _IterTag3>
_OIter _OIter
set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
_Predicate, _IterTag1, _IterTag2, _IterTag3); _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
typename _Predicate> typename _Predicate>
_Output_RAIter _Output_RAIter
set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, __set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
_Output_RAIter, _Predicate, _Output_RAIter, _Predicate,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
...@@ -782,14 +782,14 @@ namespace __parallel ...@@ -782,14 +782,14 @@ namespace __parallel
typename _OIter, typename _IterTag1, typename _IterTag2, typename _OIter, typename _IterTag1, typename _IterTag2,
typename _IterTag3> typename _IterTag3>
_OIter _OIter
set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, __set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Predicate, _IterTag1, _IterTag2, _OIter, _Predicate, _IterTag1, _IterTag2,
_IterTag3); _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
typename _Predicate> typename _Predicate>
_Output_RAIter _Output_RAIter
set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, __set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
_Output_RAIter, _Predicate, _Output_RAIter, _Predicate,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
...@@ -820,13 +820,13 @@ namespace __parallel ...@@ -820,13 +820,13 @@ namespace __parallel
typename _OIter, typename _IterTag1, typename _IterTag2, typename _OIter, typename _IterTag1, typename _IterTag2,
typename _IterTag3> typename _IterTag3>
_OIter _OIter
set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
_Predicate, _IterTag1, _IterTag2, _IterTag3); _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
typename _Predicate> typename _Predicate>
_Output_RAIter _Output_RAIter
set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, __set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
_Output_RAIter, _Predicate, _Output_RAIter, _Predicate,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
...@@ -885,12 +885,12 @@ namespace __parallel ...@@ -885,12 +885,12 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _Predicate, template<typename _IIter, typename _OIter, typename _Predicate,
typename _IterTag1, typename _IterTag2> typename _IterTag1, typename _IterTag2>
_OIter _OIter
unique_copy_switch(_IIter, _IIter, _OIter, _Predicate, __unique_copy_switch(_IIter, _IIter, _OIter, _Predicate,
_IterTag1, _IterTag2); _IterTag1, _IterTag2);
template<typename _RAIter, typename _RandomAccess_OIter, typename _Predicate> template<typename _RAIter, typename _RandomAccess_OIter, typename _Predicate>
_RandomAccess_OIter _RandomAccess_OIter
unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate, __unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
} // end namespace __parallel } // end namespace __parallel
} // end namespace std } // end namespace std
......
...@@ -58,171 +58,171 @@ ...@@ -58,171 +58,171 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Information local to one thread in the parallel quicksort run. */ /** @brief Information local to one thread in the parallel quicksort run. */
template<typename RandomAccessIterator> template<typename _RAIter>
struct QSBThreadLocal struct _QSBThreadLocal
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
/** @brief Continuous part of the sequence, described by an /** @brief Continuous part of the sequence, described by an
iterator pair. */ iterator pair. */
typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece; typedef std::pair<_RAIter, _RAIter> _Piece;
/** @brief Initial piece to work on. */ /** @brief Initial piece to work on. */
Piece initial; _Piece _M_initial;
/** @brief Work-stealing queue. */ /** @brief Work-stealing queue. */
RestrictedBoundedConcurrentQueue<Piece> leftover_parts; _RestrictedBoundedConcurrentQueue<_Piece> _M_leftover_parts;
/** @brief Number of threads involved in this algorithm. */ /** @brief Number of threads involved in this algorithm. */
thread_index_t num_threads; _ThreadIndex __num_threads;
/** @brief Pointer to a counter of elements left over to sort. */ /** @brief Pointer to a counter of elements left over to sort. */
volatile difference_type* elements_leftover; volatile _DifferenceType* _M_elements_leftover;
/** @brief The complete sequence to sort. */ /** @brief The complete sequence to sort. */
Piece global; _Piece _M_global;
/** @brief Constructor. /** @brief Constructor.
* @param queue_size Size of the work-stealing queue. */ * @param __queue_size size of the work-stealing queue. */
QSBThreadLocal(int queue_size) : leftover_parts(queue_size) { } _QSBThreadLocal(int __queue_size) : _M_leftover_parts(__queue_size) { }
}; };
/** @brief Balanced quicksort divide step. /** @brief Balanced quicksort divide step.
* @param begin Begin iterator of subsequence. * @param __begin Begin iterator of subsequence.
* @param end End iterator of subsequence. * @param __end End iterator of subsequence.
* @param comp Comparator. * @param __comp Comparator.
* @param num_threads Number of threads that are allowed to work on * @param __num_threads Number of threads that are allowed to work on
* this part. * this part.
* @pre @c (end-begin)>=1 */ * @pre @__c (__end-__begin)>=1 */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
typename std::iterator_traits<RandomAccessIterator>::difference_type typename std::iterator_traits<_RAIter>::difference_type
qsb_divide(RandomAccessIterator begin, RandomAccessIterator end, __qsb_divide(_RAIter __begin, _RAIter __end,
Comparator comp, thread_index_t num_threads) _Compare __comp, _ThreadIndex __num_threads)
{ {
_GLIBCXX_PARALLEL_ASSERT(num_threads > 0); _GLIBCXX_PARALLEL_ASSERT(__num_threads > 0);
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
RandomAccessIterator pivot_pos = _RAIter __pivot_pos =
median_of_three_iterators(begin, begin + (end - begin) / 2, __median_of_three_iterators(__begin, __begin + (__end - __begin) / 2,
end - 1, comp); __end - 1, __comp);
#if defined(_GLIBCXX_ASSERTIONS) #if defined(_GLIBCXX_ASSERTIONS)
// Must be in between somewhere. // Must be in between somewhere.
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
_GLIBCXX_PARALLEL_ASSERT( _GLIBCXX_PARALLEL_ASSERT(
(!comp(*pivot_pos, *begin) && !comp(*(begin + n / 2), *pivot_pos)) (!__comp(*__pivot_pos, *__begin) && !__comp(*(__begin + __n / 2), *__pivot_pos))
|| (!comp(*pivot_pos, *begin) && !comp(*(end - 1), *pivot_pos)) || (!__comp(*__pivot_pos, *__begin) && !__comp(*(__end - 1), *__pivot_pos))
|| (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*begin, *pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*__begin, *__pivot_pos))
|| (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*(end - 1), *pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*(__end - 1), *__pivot_pos))
|| (!comp(*pivot_pos, *(end - 1)) && !comp(*begin, *pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*__begin, *__pivot_pos))
|| (!comp(*pivot_pos, *(end - 1)) && !comp(*(begin + n / 2), *pivot_pos))); || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*(__begin + __n / 2), *__pivot_pos)));
#endif #endif
// Swap pivot value to end. // Swap pivot value to end.
if (pivot_pos != (end - 1)) if (__pivot_pos != (__end - 1))
std::swap(*pivot_pos, *(end - 1)); std::swap(*__pivot_pos, *(__end - 1));
pivot_pos = end - 1; __pivot_pos = __end - 1;
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
pred(comp, *pivot_pos); __pred(__comp, *__pivot_pos);
// Divide, returning end - begin - 1 in the worst case. // Divide, returning __end - __begin - 1 in the worst case.
difference_type split_pos = parallel_partition( _DifferenceType __split_pos = __parallel_partition(
begin, end - 1, pred, num_threads); __begin, __end - 1, __pred, __num_threads);
// Swap back pivot to middle. // Swap back pivot to middle.
std::swap(*(begin + split_pos), *pivot_pos); std::swap(*(__begin + __split_pos), *__pivot_pos);
pivot_pos = begin + split_pos; __pivot_pos = __begin + __split_pos;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
RandomAccessIterator r; _RAIter __r;
for (r = begin; r != pivot_pos; ++r) for (__r = __begin; __r != __pivot_pos; ++__r)
_GLIBCXX_PARALLEL_ASSERT(comp(*r, *pivot_pos)); _GLIBCXX_PARALLEL_ASSERT(__comp(*__r, *__pivot_pos));
for (; r != end; ++r) for (; __r != __end; ++__r)
_GLIBCXX_PARALLEL_ASSERT(!comp(*r, *pivot_pos)); _GLIBCXX_PARALLEL_ASSERT(!__comp(*__r, *__pivot_pos));
#endif #endif
return split_pos; return __split_pos;
} }
/** @brief Quicksort conquer step. /** @brief Quicksort conquer step.
* @param tls Array of thread-local storages. * @param __tls Array of thread-local storages.
* @param begin Begin iterator of subsequence. * @param __begin Begin iterator of subsequence.
* @param end End iterator of subsequence. * @param __end End iterator of subsequence.
* @param comp Comparator. * @param __comp Comparator.
* @param iam Number of the thread processing this function. * @param __iam Number of the thread processing this function.
* @param num_threads * @param __num_threads
* Number of threads that are allowed to work on this part. */ * Number of threads that are allowed to work on this part. */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
qsb_conquer(QSBThreadLocal<RandomAccessIterator>** tls, __qsb_conquer(_QSBThreadLocal<_RAIter>** __tls,
RandomAccessIterator begin, RandomAccessIterator end, _RAIter __begin, _RAIter __end,
Comparator comp, _Compare __comp,
thread_index_t iam, thread_index_t num_threads, _ThreadIndex __iam, _ThreadIndex __num_threads,
bool parent_wait) bool __parent_wait)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
if (num_threads <= 1 || n <= 1) if (__num_threads <= 1 || __n <= 1)
{ {
tls[iam]->initial.first = begin; __tls[__iam]->_M_initial.first = __begin;
tls[iam]->initial.second = end; __tls[__iam]->_M_initial.second = __end;
qsb_local_sort_with_helping(tls, comp, iam, parent_wait); __qsb_local_sort_with_helping(__tls, __comp, __iam, __parent_wait);
return; return;
} }
// Divide step. // Divide step.
difference_type split_pos = qsb_divide(begin, end, comp, num_threads); _DifferenceType __split_pos = __qsb_divide(__begin, __end, __comp, __num_threads);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(0 <= split_pos && split_pos < (end - begin)); _GLIBCXX_PARALLEL_ASSERT(0 <= __split_pos && __split_pos < (__end - __begin));
#endif #endif
thread_index_t num_threads_leftside = _ThreadIndex __num_threads_leftside =
std::max<thread_index_t>(1, std::min<thread_index_t>( std::max<_ThreadIndex>(1, std::min<_ThreadIndex>(
num_threads - 1, split_pos * num_threads / n)); __num_threads - 1, __split_pos * __num_threads / __n));
# pragma omp atomic # pragma omp atomic
*tls[iam]->elements_leftover -= (difference_type)1; *__tls[__iam]->_M_elements_leftover -= (_DifferenceType)1;
// Conquer step. // Conquer step.
# pragma omp parallel num_threads(2) # pragma omp parallel num_threads(2)
{ {
bool wait; bool __wait;
if(omp_get_num_threads() < 2) if(omp_get_num_threads() < 2)
wait = false; __wait = false;
else else
wait = parent_wait; __wait = __parent_wait;
# pragma omp sections # pragma omp sections
{ {
# pragma omp section # pragma omp section
{ {
qsb_conquer(tls, begin, begin + split_pos, comp, __qsb_conquer(__tls, __begin, __begin + __split_pos, __comp,
iam, __iam,
num_threads_leftside, __num_threads_leftside,
wait); __wait);
wait = parent_wait; __wait = __parent_wait;
} }
// The pivot_pos is left in place, to ensure termination. // The pivot_pos is left in place, to ensure termination.
# pragma omp section # pragma omp section
{ {
qsb_conquer(tls, begin + split_pos + 1, end, comp, __qsb_conquer(__tls, __begin + __split_pos + 1, __end, __comp,
iam + num_threads_leftside, __iam + __num_threads_leftside,
num_threads - num_threads_leftside, __num_threads - __num_threads_leftside,
wait); __wait);
wait = parent_wait; __wait = __parent_wait;
} }
} }
} }
...@@ -230,175 +230,175 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -230,175 +230,175 @@ template<typename RandomAccessIterator, typename Comparator>
/** /**
* @brief Quicksort step doing load-balanced local sort. * @brief Quicksort step doing load-balanced local sort.
* @param tls Array of thread-local storages. * @param __tls Array of thread-local storages.
* @param comp Comparator. * @param __comp Comparator.
* @param iam Number of the thread processing this function. * @param __iam Number of the thread processing this function.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
qsb_local_sort_with_helping(QSBThreadLocal<RandomAccessIterator>** tls, __qsb_local_sort_with_helping(_QSBThreadLocal<_RAIter>** __tls,
Comparator& comp, int iam, bool wait) _Compare& __comp, int __iam, bool __wait)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece; typedef std::pair<_RAIter, _RAIter> _Piece;
QSBThreadLocal<RandomAccessIterator>& tl = *tls[iam]; _QSBThreadLocal<_RAIter>& __tl = *__tls[__iam];
difference_type base_case_n = _DifferenceType __base_case_n =
_Settings::get().sort_qsb_base_case_maximal_n; _Settings::get().sort_qsb_base_case_maximal_n;
if (base_case_n < 2) if (__base_case_n < 2)
base_case_n = 2; __base_case_n = 2;
thread_index_t num_threads = tl.num_threads; _ThreadIndex __num_threads = __tl.__num_threads;
// Every thread has its own random number generator. // Every thread has its own random number generator.
random_number rng(iam + 1); _RandomNumber __rng(__iam + 1);
Piece current = tl.initial; _Piece __current = __tl._M_initial;
difference_type elements_done = 0; _DifferenceType __elements_done = 0;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
difference_type total_elements_done = 0; _DifferenceType __total_elements_done = 0;
#endif #endif
for (;;) for (;;)
{ {
// Invariant: current must be a valid (maybe empty) range. // Invariant: __current must be a valid (maybe empty) range.
RandomAccessIterator begin = current.first, end = current.second; _RAIter __begin = __current.first, __end = __current.second;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
if (n > base_case_n) if (__n > __base_case_n)
{ {
// Divide. // Divide.
RandomAccessIterator pivot_pos = begin + rng(n); _RAIter __pivot_pos = __begin + __rng(__n);
// Swap pivot_pos value to end. // Swap __pivot_pos value to end.
if (pivot_pos != (end - 1)) if (__pivot_pos != (__end - 1))
std::swap(*pivot_pos, *(end - 1)); std::swap(*__pivot_pos, *(__end - 1));
pivot_pos = end - 1; __pivot_pos = __end - 1;
__gnu_parallel::binder2nd __gnu_parallel::binder2nd
<Comparator, value_type, value_type, bool> <_Compare, _ValueType, _ValueType, bool>
pred(comp, *pivot_pos); __pred(__comp, *__pivot_pos);
// Divide, leave pivot unchanged in last place. // Divide, leave pivot unchanged in last place.
RandomAccessIterator split_pos1, split_pos2; _RAIter __split_pos1, __split_pos2;
split_pos1 = __gnu_sequential::partition(begin, end - 1, pred); __split_pos1 = __gnu_sequential::partition(__begin, __end - 1, __pred);
// Left side: < pivot_pos; right side: >= pivot_pos. // Left side: < __pivot_pos; __right side: >= __pivot_pos.
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(begin <= split_pos1 && split_pos1 < end); _GLIBCXX_PARALLEL_ASSERT(__begin <= __split_pos1 && __split_pos1 < __end);
#endif #endif
// Swap pivot back to middle. // Swap pivot back to middle.
if (split_pos1 != pivot_pos) if (__split_pos1 != __pivot_pos)
std::swap(*split_pos1, *pivot_pos); std::swap(*__split_pos1, *__pivot_pos);
pivot_pos = split_pos1; __pivot_pos = __split_pos1;
// In case all elements are equal, split_pos1 == 0. // In case all elements are equal, __split_pos1 == 0.
if ((split_pos1 + 1 - begin) < (n >> 7) if ((__split_pos1 + 1 - __begin) < (__n >> 7)
|| (end - split_pos1) < (n >> 7)) || (__end - __split_pos1) < (__n >> 7))
{ {
// Very unequal split, one part smaller than one 128th // Very unequal split, one part smaller than one 128th
// elements not strictly larger than the pivot. // elements not strictly larger than the pivot.
__gnu_parallel::unary_negate<__gnu_parallel::binder1st __gnu_parallel::__unary_negate<__gnu_parallel::__binder1st
<Comparator, value_type, value_type, bool>, value_type> <_Compare, _ValueType, _ValueType, bool>, _ValueType>
pred(__gnu_parallel::binder1st __pred(__gnu_parallel::__binder1st
<Comparator, value_type, value_type, bool>(comp, <_Compare, _ValueType, _ValueType, bool>(__comp,
*pivot_pos)); *__pivot_pos));
// Find other end of pivot-equal range. // Find other end of pivot-equal range.
split_pos2 = __gnu_sequential::partition(split_pos1 + 1, __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1,
end, pred); __end, __pred);
} }
else else
// Only skip the pivot. // Only skip the pivot.
split_pos2 = split_pos1 + 1; __split_pos2 = __split_pos1 + 1;
// Elements equal to pivot are done. // Elements equal to pivot are done.
elements_done += (split_pos2 - split_pos1); __elements_done += (__split_pos2 - __split_pos1);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
total_elements_done += (split_pos2 - split_pos1); __total_elements_done += (__split_pos2 - __split_pos1);
#endif #endif
// Always push larger part onto stack. // Always push larger part onto stack.
if (((split_pos1 + 1) - begin) < (end - (split_pos2))) if (((__split_pos1 + 1) - __begin) < (__end - (__split_pos2)))
{ {
// Right side larger. // Right side larger.
if ((split_pos2) != end) if ((__split_pos2) != __end)
tl.leftover_parts.push_front(std::make_pair(split_pos2, __tl._M_leftover_parts.push_front(std::make_pair(__split_pos2,
end)); __end));
//current.first = begin; //already set anyway //__current.first = __begin; //already set anyway
current.second = split_pos1; __current.second = __split_pos1;
continue; continue;
} }
else else
{ {
// Left side larger. // Left side larger.
if (begin != split_pos1) if (__begin != __split_pos1)
tl.leftover_parts.push_front(std::make_pair(begin, __tl._M_leftover_parts.push_front(std::make_pair(__begin,
split_pos1)); __split_pos1));
current.first = split_pos2; __current.first = __split_pos2;
//current.second = end; //already set anyway //__current.second = __end; //already set anyway
continue; continue;
} }
} }
else else
{ {
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(__begin, __end, __comp);
elements_done += n; __elements_done += __n;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
total_elements_done += n; __total_elements_done += __n;
#endif #endif
// Prefer own stack, small pieces. // Prefer own stack, small pieces.
if (tl.leftover_parts.pop_front(current)) if (__tl._M_leftover_parts.pop_front(__current))
continue; continue;
# pragma omp atomic # pragma omp atomic
*tl.elements_leftover -= elements_done; *__tl._M_elements_leftover -= __elements_done;
elements_done = 0; __elements_done = 0;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
double search_start = omp_get_wtime(); double __search_start = omp_get_wtime();
#endif #endif
// Look for new work. // Look for new work.
bool successfully_stolen = false; bool __successfully_stolen = false;
while (wait && *tl.elements_leftover > 0 && !successfully_stolen while (__wait && *__tl._M_elements_leftover > 0 && !__successfully_stolen
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// Possible dead-lock. // Possible dead-lock.
&& (omp_get_wtime() < (search_start + 1.0)) && (omp_get_wtime() < (__search_start + 1.0))
#endif #endif
) )
{ {
thread_index_t victim; _ThreadIndex __victim;
victim = rng(num_threads); __victim = __rng(__num_threads);
// Large pieces. // Large pieces.
successfully_stolen = (victim != iam) __successfully_stolen = (__victim != __iam)
&& tls[victim]->leftover_parts.pop_back(current); && __tls[__victim]->_M_leftover_parts.pop_back(__current);
if (!successfully_stolen) if (!__successfully_stolen)
yield(); __yield();
#if !defined(__ICC) && !defined(__ECC) #if !defined(__ICC) && !defined(__ECC)
# pragma omp flush # pragma omp flush
#endif #endif
} }
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
if (omp_get_wtime() >= (search_start + 1.0)) if (omp_get_wtime() >= (__search_start + 1.0))
{ {
sleep(1); sleep(1);
_GLIBCXX_PARALLEL_ASSERT(omp_get_wtime() _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime()
< (search_start + 1.0)); < (__search_start + 1.0));
} }
#endif #endif
if (!successfully_stolen) if (!__successfully_stolen)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(*tl.elements_leftover == 0); _GLIBCXX_PARALLEL_ASSERT(*__tl._M_elements_leftover == 0);
#endif #endif
return; return;
} }
...@@ -407,70 +407,70 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -407,70 +407,70 @@ template<typename RandomAccessIterator, typename Comparator>
} }
/** @brief Top-level quicksort routine. /** @brief Top-level quicksort routine.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param comp Comparator. * @param __comp Comparator.
* @param num_threads Number of threads that are allowed to work on * @param __num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
parallel_sort_qsb(RandomAccessIterator begin, RandomAccessIterator end, __parallel_sort_qsb(_RAIter __begin, _RAIter __end,
Comparator comp, _Compare __comp,
thread_index_t num_threads) _ThreadIndex __num_threads)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece; typedef std::pair<_RAIter, _RAIter> _Piece;
typedef QSBThreadLocal<RandomAccessIterator> tls_type; typedef _QSBThreadLocal<_RAIter> _TLSType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
if (n <= 1) if (__n <= 1)
return; return;
// At least one element per processor. // At least one element per processor.
if (num_threads > n) if (__num_threads > __n)
num_threads = static_cast<thread_index_t>(n); __num_threads = static_cast<_ThreadIndex>(__n);
// Initialize thread local storage // Initialize thread local storage
tls_type** tls = new tls_type*[num_threads]; _TLSType** __tls = new _TLSType*[__num_threads];
difference_type queue_size = num_threads * (thread_index_t)(log2(n) + 1); _DifferenceType __queue_size = __num_threads * (_ThreadIndex)(log2(__n) + 1);
for (thread_index_t t = 0; t < num_threads; ++t) for (_ThreadIndex __t = 0; __t < __num_threads; ++__t)
tls[t] = new QSBThreadLocal<RandomAccessIterator>(queue_size); __tls[__t] = new _QSBThreadLocal<_RAIter>(__queue_size);
// There can never be more than ceil(log2(n)) ranges on the stack, because // There can never be more than ceil(log2(__n)) ranges on the stack, because
// 1. Only one processor pushes onto the stack // 1. Only one processor pushes onto the stack
// 2. The largest range has at most length n // 2. The largest range has at most length __n
// 3. Each range is larger than half of the range remaining // 3. Each range is larger than half of the range remaining
volatile difference_type elements_leftover = n; volatile _DifferenceType _M_elements_leftover = __n;
for (int i = 0; i < num_threads; ++i) for (int __i = 0; __i < __num_threads; ++__i)
{ {
tls[i]->elements_leftover = &elements_leftover; __tls[__i]->_M_elements_leftover = &_M_elements_leftover;
tls[i]->num_threads = num_threads; __tls[__i]->__num_threads = __num_threads;
tls[i]->global = std::make_pair(begin, end); __tls[__i]->_M_global = std::make_pair(__begin, __end);
// Just in case nothing is left to assign. // Just in case nothing is left to assign.
tls[i]->initial = std::make_pair(end, end); __tls[__i]->_M_initial = std::make_pair(__end, __end);
} }
// Main recursion call. // Main recursion call.
qsb_conquer(tls, begin, begin + n, comp, 0, num_threads, true); __qsb_conquer(__tls, __begin, __begin + __n, __comp, 0, __num_threads, true);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// All stack must be empty. // All stack must be empty.
Piece dummy; _Piece __dummy;
for (int i = 1; i < num_threads; ++i) for (int __i = 1; __i < __num_threads; ++__i)
_GLIBCXX_PARALLEL_ASSERT(!tls[i]->leftover_parts.pop_back(dummy)); _GLIBCXX_PARALLEL_ASSERT(!__tls[__i]->_M_leftover_parts.pop_back(__dummy));
#endif #endif
for (int i = 0; i < num_threads; ++i) for (int __i = 0; __i < __num_threads; ++__i)
delete tls[i]; delete __tls[__i];
delete[] tls; delete[] __tls;
} }
} // namespace __gnu_parallel } // namespace __gnu_parallel
......
...@@ -82,7 +82,7 @@ namespace __gnu_parallel ...@@ -82,7 +82,7 @@ namespace __gnu_parallel
// and active, which imples that the OpenMP runtime is actually // and active, which imples that the OpenMP runtime is actually
// going to be linked in. // going to be linked in.
inline int inline int
get_max_threads() __get_max_threads()
{ {
int __i = omp_get_max_threads(); int __i = omp_get_max_threads();
return __i > 1 ? __i : 1; return __i > 1 ? __i : 1;
...@@ -90,91 +90,91 @@ namespace __gnu_parallel ...@@ -90,91 +90,91 @@ namespace __gnu_parallel
inline bool inline bool
is_parallel(const _Parallelism __p) { return __p != sequential; } __is_parallel(const _Parallelism __p) { return __p != sequential; }
// XXX remove std::duplicates from here if possible, // XXX remove std::duplicates from here if possible,
// XXX but keep minimal dependencies. // XXX but keep minimal dependencies.
/** @brief Calculates the rounded-down logarithm of @c n for base 2. /** @brief Calculates the rounded-down logarithm of @__c __n for base 2.
* @param n Argument. * @param __n Argument.
* @return Returns 0 for any argument <1. * @return Returns 0 for any argument <1.
*/ */
template<typename Size> template<typename _Size>
inline Size inline _Size
__log2(Size n) __log2(_Size __n)
{ {
Size k; _Size __k;
for (k = 0; n > 1; n >>= 1) for (__k = 0; __n > 1; __n >>= 1)
++k; ++__k;
return k; return __k;
} }
/** @brief Encode two integers into one __gnu_parallel::lcas_t. /** @brief Encode two integers into one __gnu_parallel::_CASable.
* @param a First integer, to be encoded in the most-significant @c * @param __a First integer, to be encoded in the most-significant @__c
* lcas_t_bits/2 bits. * _CASable_bits/2 bits.
* @param b Second integer, to be encoded in the least-significant * @param __b Second integer, to be encoded in the least-significant
* @c lcas_t_bits/2 bits. * @__c _CASable_bits/2 bits.
* @return __gnu_parallel::lcas_t value encoding @c a and @c b. * @return __gnu_parallel::_CASable _M_value encoding @__c __a and @__c __b.
* @see decode2 * @see decode2
*/ */
inline lcas_t inline _CASable
encode2(int a, int b) //must all be non-negative, actually __encode2(int __a, int __b) //must all be non-negative, actually
{ {
return (((lcas_t)a) << (lcas_t_bits / 2)) | (((lcas_t)b) << 0); return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0);
} }
/** @brief Decode two integers from one __gnu_parallel::lcas_t. /** @brief Decode two integers from one __gnu_parallel::_CASable.
* @param x __gnu_parallel::lcas_t to decode integers from. * @param __x __gnu_parallel::_CASable to decode integers from.
* @param a First integer, to be decoded from the most-significant * @param __a First integer, to be decoded from the most-significant
* @c lcas_t_bits/2 bits of @c x. * @__c _CASable_bits/2 bits of @__c __x.
* @param b Second integer, to be encoded in the least-significant * @param __b Second integer, to be encoded in the least-significant
* @c lcas_t_bits/2 bits of @c x. * @__c _CASable_bits/2 bits of @__c __x.
* @see encode2 * @see __encode2
*/ */
inline void inline void
decode2(lcas_t x, int& a, int& b) decode2(_CASable __x, int& __a, int& __b)
{ {
a = (int)((x >> (lcas_t_bits / 2)) & lcas_t_mask); __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask);
b = (int)((x >> 0 ) & lcas_t_mask); __b = (int)((__x >> 0 ) & _CASable_mask);
} }
/** @brief Equivalent to std::min. */ /** @brief Equivalent to std::min. */
template<typename T> template<typename _Tp>
const T& const _Tp&
min(const T& a, const T& b) min(const _Tp& __a, const _Tp& __b)
{ return (a < b) ? a : b; } { return (__a < __b) ? __a : __b; }
/** @brief Equivalent to std::max. */ /** @brief Equivalent to std::max. */
template<typename T> template<typename _Tp>
const T& const _Tp&
max(const T& a, const T& b) max(const _Tp& __a, const _Tp& __b)
{ return (a > b) ? a : b; } { return (__a > __b) ? __a : __b; }
/** @brief Constructs predicate for equality from strict weak /** @brief Constructs predicate for equality from strict weak
* ordering predicate * ordering predicate
*/ */
// XXX comparator at the end, as per others // XXX comparator at the end, as per others
template<typename Comparator, typename T1, typename T2> template<typename _Compare, typename _T1, typename _T2>
class equal_from_less : public std::binary_function<T1, T2, bool> class _EqualFromLess : public std::binary_function<_T1, _T2, bool>
{ {
private: private:
Comparator& comp; _Compare& __comp;
public: public:
equal_from_less(Comparator& _comp) : comp(_comp) { } _EqualFromLess(_Compare& _comp) : __comp(_comp) { }
bool operator()(const T1& a, const T2& b) bool operator()(const _T1& __a, const _T2& __b)
{ {
return !comp(a, b) && !comp(b, a); return !__comp(__a, __b) && !__comp(__b, __a);
} }
}; };
/** @brief Similar to std::binder1st, /** @brief Similar to std::__binder1st,
* but giving the argument types explicitly. */ * but giving the argument types explicitly. */
template<typename _Predicate, typename argument_type> template<typename _Predicate, typename argument_type>
class unary_negate class __unary_negate
: public std::unary_function<argument_type, bool> : public std::unary_function<argument_type, bool>
{ {
protected: protected:
...@@ -182,93 +182,93 @@ template<typename _Predicate, typename argument_type> ...@@ -182,93 +182,93 @@ template<typename _Predicate, typename argument_type>
public: public:
explicit explicit
unary_negate(const _Predicate& __x) : _M_pred(__x) { } __unary_negate(const _Predicate& __x) : _M_pred(__x) { }
bool bool
operator()(const argument_type& __x) operator()(const argument_type& __x)
{ return !_M_pred(__x); } { return !_M_pred(__x); }
}; };
/** @brief Similar to std::binder1st, /** @brief Similar to std::__binder1st,
* but giving the argument types explicitly. */ * but giving the argument types explicitly. */
template<typename _Operation, typename first_argument_type, template<typename _Operation, typename _FirstArgumentType,
typename second_argument_type, typename result_type> typename _SecondArgumentType, typename _ResultType>
class binder1st class __binder1st
: public std::unary_function<second_argument_type, result_type> : public std::unary_function<_SecondArgumentType, _ResultType>
{ {
protected: protected:
_Operation op; _Operation _M_op;
first_argument_type value; _FirstArgumentType _M_value;
public: public:
binder1st(const _Operation& __x, __binder1st(const _Operation& __x,
const first_argument_type& __y) const _FirstArgumentType& __y)
: op(__x), value(__y) { } : _M_op(__x), _M_value(__y) { }
result_type _ResultType
operator()(const second_argument_type& __x) operator()(const _SecondArgumentType& __x)
{ return op(value, __x); } { return _M_op(_M_value, __x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements // 109. Missing binders for non-const __sequence __elements
result_type _ResultType
operator()(second_argument_type& __x) const operator()(_SecondArgumentType& __x) const
{ return op(value, __x); } { return _M_op(_M_value, __x); }
}; };
/** /**
* @brief Similar to std::binder2nd, but giving the argument types * @brief Similar to std::binder2nd, but giving the argument types
* explicitly. * explicitly.
*/ */
template<typename _Operation, typename first_argument_type, template<typename _Operation, typename _FirstArgumentType,
typename second_argument_type, typename result_type> typename _SecondArgumentType, typename _ResultType>
class binder2nd class binder2nd
: public std::unary_function<first_argument_type, result_type> : public std::unary_function<_FirstArgumentType, _ResultType>
{ {
protected: protected:
_Operation op; _Operation _M_op;
second_argument_type value; _SecondArgumentType _M_value;
public: public:
binder2nd(const _Operation& __x, binder2nd(const _Operation& __x,
const second_argument_type& __y) const _SecondArgumentType& __y)
: op(__x), value(__y) { } : _M_op(__x), _M_value(__y) { }
result_type _ResultType
operator()(const first_argument_type& __x) const operator()(const _FirstArgumentType& __x) const
{ return op(__x, value); } { return _M_op(__x, _M_value); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements // 109. Missing binders for non-const __sequence __elements
result_type _ResultType
operator()(first_argument_type& __x) operator()(_FirstArgumentType& __x)
{ return op(__x, value); } { return _M_op(__x, _M_value); }
}; };
/** @brief Similar to std::equal_to, but allows two different types. */ /** @brief Similar to std::equal_to, but allows two different types. */
template<typename T1, typename T2> template<typename _T1, typename _T2>
struct equal_to : std::binary_function<T1, T2, bool> struct equal_to : std::binary_function<_T1, _T2, bool>
{ {
bool operator()(const T1& t1, const T2& t2) const bool operator()(const _T1& __t1, const _T2& __t2) const
{ return t1 == t2; } { return __t1 == __t2; }
}; };
/** @brief Similar to std::less, but allows two different types. */ /** @brief Similar to std::less, but allows two different types. */
template<typename T1, typename T2> template<typename _T1, typename _T2>
struct less : std::binary_function<T1, T2, bool> struct _Less : std::binary_function<_T1, _T2, bool>
{ {
bool bool
operator()(const T1& t1, const T2& t2) const operator()(const _T1& __t1, const _T2& __t2) const
{ return t1 < t2; } { return __t1 < __t2; }
bool bool
operator()(const T2& t2, const T1& t1) const operator()(const _T2& __t2, const _T1& __t1) const
{ return t2 < t1; } { return __t2 < __t1; }
}; };
// Partial specialization for one type. Same as std::less. // Partial specialization for one type. Same as std::less.
template<typename _Tp> template<typename _Tp>
struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool> struct _Less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
{ {
bool bool
operator()(const _Tp& __x, const _Tp& __y) const operator()(const _Tp& __x, const _Tp& __y) const
...@@ -278,24 +278,24 @@ struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool> ...@@ -278,24 +278,24 @@ struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
/** @brief Similar to std::plus, but allows two different types. */ /** @brief Similar to std::plus, but allows two different types. */
template<typename _Tp1, typename _Tp2> template<typename _Tp1, typename _Tp2>
struct plus : public std::binary_function<_Tp1, _Tp2, _Tp1> struct _Plus : public std::binary_function<_Tp1, _Tp2, _Tp1>
{ {
typedef __typeof__(*static_cast<_Tp1*>(NULL) typedef __typeof__(*static_cast<_Tp1*>(NULL)
+ *static_cast<_Tp2*>(NULL)) result; + *static_cast<_Tp2*>(NULL)) __result;
result __result
operator()(const _Tp1& __x, const _Tp2& __y) const operator()(const _Tp1& __x, const _Tp2& __y) const
{ return __x + __y; } { return __x + __y; }
}; };
// Partial specialization for one type. Same as std::plus. // Partial specialization for one type. Same as std::plus.
template<typename _Tp> template<typename _Tp>
struct plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp> struct _Plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
{ {
typedef __typeof__(*static_cast<_Tp*>(NULL) typedef __typeof__(*static_cast<_Tp*>(NULL)
+ *static_cast<_Tp*>(NULL)) result; + *static_cast<_Tp*>(NULL)) __result;
result __result
operator()(const _Tp& __x, const _Tp& __y) const operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; } { return __x + __y; }
}; };
...@@ -303,164 +303,164 @@ template<typename _Tp> ...@@ -303,164 +303,164 @@ template<typename _Tp>
/** @brief Similar to std::multiplies, but allows two different types. */ /** @brief Similar to std::multiplies, but allows two different types. */
template<typename _Tp1, typename _Tp2> template<typename _Tp1, typename _Tp2>
struct multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1> struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1>
{ {
typedef __typeof__(*static_cast<_Tp1*>(NULL) typedef __typeof__(*static_cast<_Tp1*>(NULL)
* *static_cast<_Tp2*>(NULL)) result; * *static_cast<_Tp2*>(NULL)) __result;
result __result
operator()(const _Tp1& __x, const _Tp2& __y) const operator()(const _Tp1& __x, const _Tp2& __y) const
{ return __x * __y; } { return __x * __y; }
}; };
// Partial specialization for one type. Same as std::multiplies. // Partial specialization for one type. Same as std::multiplies.
template<typename _Tp> template<typename _Tp>
struct multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp> struct _Multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
{ {
typedef __typeof__(*static_cast<_Tp*>(NULL) typedef __typeof__(*static_cast<_Tp*>(NULL)
* *static_cast<_Tp*>(NULL)) result; * *static_cast<_Tp*>(NULL)) __result;
result __result
operator()(const _Tp& __x, const _Tp& __y) const operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; } { return __x * __y; }
}; };
template<typename T, typename _DifferenceTp> template<typename _Tp, typename _DifferenceTp>
class pseudo_sequence; class _PseudoSequence;
/** @brief Iterator associated with __gnu_parallel::pseudo_sequence. /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence.
* If features the usual random-access iterator functionality. * If features the usual random-access iterator functionality.
* @param T Sequence value type. * @param _Tp Sequence _M_value type.
* @param difference_type Sequence difference type. * @param _DifferenceType Sequence difference type.
*/ */
template<typename T, typename _DifferenceTp> template<typename _Tp, typename _DifferenceTp>
class pseudo_sequence_iterator class _PseudoSequenceIterator
{ {
public: public:
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
private: private:
typedef pseudo_sequence_iterator<T, _DifferenceTp> type; typedef _PseudoSequenceIterator<_Tp, _DifferenceTp> _Self;
const T& val; const _Tp& _M_val;
difference_type pos; _DifferenceType _M_pos;
public: public:
pseudo_sequence_iterator(const T& val, difference_type pos) _PseudoSequenceIterator(const _Tp& _M_val, _DifferenceType _M_pos)
: val(val), pos(pos) { } : _M_val(_M_val), _M_pos(_M_pos) { }
// Pre-increment operator. // Pre-increment operator.
type& _Self&
operator++() operator++()
{ {
++pos; ++_M_pos;
return *this; return *this;
} }
// Post-increment operator. // Post-increment operator.
const type const _Self
operator++(int) operator++(int)
{ return type(pos++); } { return _Self(_M_pos++); }
const T& const _Tp&
operator*() const operator*() const
{ return val; } { return _M_val; }
const T& const _Tp&
operator[](difference_type) const operator[](_DifferenceType) const
{ return val; } { return _M_val; }
bool bool
operator==(const type& i2) operator==(const _Self& __i2)
{ return pos == i2.pos; } { return _M_pos == __i2._M_pos; }
difference_type _DifferenceType
operator!=(const type& i2) operator!=(const _Self& __i2)
{ return pos != i2.pos; } { return _M_pos != __i2._M_pos; }
difference_type _DifferenceType
operator-(const type& i2) operator-(const _Self& __i2)
{ return pos - i2.pos; } { return _M_pos - __i2._M_pos; }
}; };
/** @brief Sequence that conceptually consists of multiple copies of /** @brief Sequence that conceptually consists of multiple copies of
the same element. the same element.
* The copies are not stored explicitly, of course. * The copies are not stored explicitly, of course.
* @param T Sequence value type. * @param _Tp Sequence _M_value type.
* @param difference_type Sequence difference type. * @param _DifferenceType Sequence difference type.
*/ */
template<typename T, typename _DifferenceTp> template<typename _Tp, typename _DifferenceTp>
class pseudo_sequence class _PseudoSequence
{ {
typedef pseudo_sequence<T, _DifferenceTp> type; typedef _PseudoSequence<_Tp, _DifferenceTp> _Self;
public: public:
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
// Better case down to uint64, than up to _DifferenceTp. // Better case down to uint64, than up to _DifferenceTp.
typedef pseudo_sequence_iterator<T, uint64> iterator; typedef _PseudoSequenceIterator<_Tp, uint64> iterator;
/** @brief Constructor. /** @brief Constructor.
* @param val Element of the sequence. * @param _M_val Element of the sequence.
* @param count Number of (virtual) copies. * @param __count Number of (virtual) copies.
*/ */
pseudo_sequence(const T& val, difference_type count) _PseudoSequence(const _Tp& _M_val, _DifferenceType __count)
: val(val), count(count) { } : _M_val(_M_val), __count(__count) { }
/** @brief Begin iterator. */ /** @brief Begin iterator. */
iterator iterator
begin() const begin() const
{ return iterator(val, 0); } { return iterator(_M_val, 0); }
/** @brief End iterator. */ /** @brief End iterator. */
iterator iterator
end() const end() const
{ return iterator(val, count); } { return iterator(_M_val, __count); }
private: private:
const T& val; const _Tp& _M_val;
difference_type count; _DifferenceType __count;
}; };
/** @brief Functor that does nothing */ /** @brief Functor that does nothing */
template<typename _ValueTp> template<typename _ValueTp>
class void_functor class _VoidFunctor
{ {
inline void inline void
operator()(const _ValueTp& v) const { } operator()(const _ValueTp& __v) const { }
}; };
/** @brief Compute the median of three referenced elements, /** @brief Compute the median of three referenced elements,
according to @c comp. according to @__c __comp.
* @param a First iterator. * @param __a First iterator.
* @param b Second iterator. * @param __b Second iterator.
* @param c Third iterator. * @param __c Third iterator.
* @param comp Comparator. * @param __comp Comparator.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
RandomAccessIterator _RAIter
median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b, __median_of_three_iterators(_RAIter __a, _RAIter __b,
RandomAccessIterator c, Comparator& comp) _RAIter __c, _Compare& __comp)
{ {
if (comp(*a, *b)) if (__comp(*__a, *__b))
if (comp(*b, *c)) if (__comp(*__b, *__c))
return b; return __b;
else else
if (comp(*a, *c)) if (__comp(*__a, *__c))
return c; return __c;
else else
return a; return __a;
else else
{ {
// Just swap a and b. // Just swap __a and __b.
if (comp(*a, *c)) if (__comp(*__a, *__c))
return a; return __a;
else else
if (comp(*b, *c)) if (__comp(*__b, *__c))
return c; return __c;
else else
return b; return __b;
} }
} }
......
...@@ -39,115 +39,115 @@ ...@@ -39,115 +39,115 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** /**
* @brief Check whether @c [begin, @c end) is sorted according to @c comp. * @brief Check whether @__c [__begin, @__c __end) is sorted according to @__c __comp.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param comp Comparator. * @param __comp Comparator.
* @return @c true if sorted, @c false otherwise. * @return @__c true if sorted, @__c false otherwise.
*/ */
// XXX Comparator default template argument // XXX Compare default template argument
template<typename InputIterator, typename Comparator> template<typename _IIter, typename _Compare>
bool bool
is_sorted(InputIterator begin, InputIterator end, __is_sorted(_IIter __begin, _IIter __end,
Comparator comp _Compare __comp
= std::less<typename std::iterator_traits<InputIterator>:: = std::less<typename std::iterator_traits<_IIter>::
value_type>()) _ValueType>())
{ {
if (begin == end) if (__begin == __end)
return true; return true;
InputIterator current(begin), recent(begin); _IIter __current(__begin), __recent(__begin);
unsigned long long position = 1; unsigned long long __position = 1;
for (current++; current != end; current++) for (__current++; __current != __end; __current++)
{ {
if (comp(*current, *recent)) if (__comp(*__current, *__recent))
{ {
printf("is_sorted: check failed before position %i.\n", printf("__is_sorted: check failed before position %__i.\n",
position); __position);
return false; return false;
} }
recent = current; __recent = __current;
position++; __position++;
} }
return true; return true;
} }
/** /**
* @brief Check whether @c [begin, @c end) is sorted according to @c comp. * @brief Check whether @__c [__begin, @__c __end) is sorted according to @__c __comp.
* Prints the position in case an unordered pair is found. * Prints the position in case an unordered pair is found.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param first_failure The first failure is returned in this variable. * @param __first_failure The first failure is returned in this variable.
* @param comp Comparator. * @param __comp Comparator.
* @return @c true if sorted, @c false otherwise. * @return @__c true if sorted, @__c false otherwise.
*/ */
// XXX Comparator default template argument // XXX Compare default template argument
template<typename InputIterator, typename Comparator> template<typename _IIter, typename _Compare>
bool bool
is_sorted_failure(InputIterator begin, InputIterator end, is_sorted_failure(_IIter __begin, _IIter __end,
InputIterator& first_failure, _IIter& __first_failure,
Comparator comp _Compare __comp
= std::less<typename std::iterator_traits<InputIterator>:: = std::less<typename std::iterator_traits<_IIter>::
value_type>()) _ValueType>())
{ {
if (begin == end) if (__begin == __end)
return true; return true;
InputIterator current(begin), recent(begin); _IIter __current(__begin), __recent(__begin);
unsigned long long position = 1; unsigned long long __position = 1;
for (current++; current != end; current++) for (__current++; __current != __end; __current++)
{ {
if (comp(*current, *recent)) if (__comp(*__current, *__recent))
{ {
first_failure = current; __first_failure = __current;
printf("is_sorted: check failed before position %lld.\n", printf("__is_sorted: check failed before position %lld.\n",
position); __position);
return false; return false;
} }
recent = current; __recent = __current;
position++; __position++;
} }
first_failure = end; __first_failure = __end;
return true; return true;
} }
/** /**
* @brief Check whether @c [begin, @c end) is sorted according to @c comp. * @brief Check whether @__c [__begin, @__c __end) is sorted according to @__c __comp.
* Prints all unordered pair, including the surrounding two elements. * Prints all unordered pair, including the surrounding two elements.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param comp Comparator. * @param __comp Comparator.
* @return @c true if sorted, @c false otherwise. * @return @__c true if sorted, @__c false otherwise.
*/ */
template<typename InputIterator, typename Comparator> template<typename _IIter, typename _Compare>
bool bool
// XXX Comparator default template argument // XXX Compare default template argument
is_sorted_print_failures(InputIterator begin, InputIterator end, is_sorted_print_failures(_IIter __begin, _IIter __end,
Comparator comp _Compare __comp
= std::less<typename std::iterator_traits = std::less<typename std::iterator_traits
<InputIterator>::value_type>()) <_IIter>::value_type>())
{ {
if (begin == end) if (__begin == __end)
return true; return true;
InputIterator recent(begin); _IIter __recent(__begin);
bool ok = true; bool __ok = true;
for (InputIterator pos(begin + 1); pos != end; pos++) for (_IIter __pos(__begin + 1); __pos != __end; __pos++)
{ {
if (comp(*pos, *recent)) if (__comp(*__pos, *__recent))
{ {
printf("%ld: %d %d %d %d\n", pos - begin, *(pos - 2), printf("%ld: %d %d %d %d\n", __pos - __begin, *(__pos - 2),
*(pos- 1), *pos, *(pos + 1)); *(__pos- 1), *__pos, *(__pos + 1));
ok = false; __ok = false;
} }
recent = pos; __recent = __pos;
} }
return ok; return __ok;
} }
} }
......
...@@ -61,24 +61,24 @@ __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long); ...@@ -61,24 +61,24 @@ __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long);
namespace __gnu_parallel namespace __gnu_parallel
{ {
#if defined(__ICC) #if defined(__ICC)
template<typename must_be_int = int> template<typename _MustBeInt = int>
int32 faa32(int32* x, int32 inc) int32 __faa32(int32* __x, int32 __inc)
{ {
asm volatile("lock xadd %0,%1" asm volatile("lock xadd %0,%1"
: "=r" (inc), "=m" (*x) : "=__r" (__inc), "=__m" (*__x)
: "0" (inc) : "0" (__inc)
: "memory"); : "memory");
return inc; return __inc;
} }
#if defined(__x86_64) #if defined(__x86_64)
template<typename must_be_int = int> template<typename _MustBeInt = int>
int64 faa64(int64* x, int64 inc) int64 __faa64(int64* __x, int64 __inc)
{ {
asm volatile("lock xadd %0,%1" asm volatile("lock xadd %0,%1"
: "=r" (inc), "=m" (*x) : "=__r" (__inc), "=__m" (*__x)
: "0" (inc) : "0" (__inc)
: "memory"); : "memory");
return inc; return __inc;
} }
#endif #endif
#endif #endif
...@@ -88,106 +88,106 @@ namespace __gnu_parallel ...@@ -88,106 +88,106 @@ namespace __gnu_parallel
/** @brief Add a value to a variable, atomically. /** @brief Add a value to a variable, atomically.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to a 32-bit signed integer. * @param __ptr Pointer to a 32-bit signed integer.
* @param addend Value to add. * @param __addend Value to add.
*/ */
inline int32 inline int32
fetch_and_add_32(volatile int32* ptr, int32 addend) __fetch_and_add_32(volatile int32* __ptr, int32 __addend)
{ {
#if defined(__ICC) //x86 version #if defined(__ICC) //x86 version
return _InterlockedExchangeAdd((void*)ptr, addend); return _InterlockedExchangeAdd((void*)__ptr, __addend);
#elif defined(__ECC) //IA-64 version #elif defined(__ECC) //IA-64 version
return _InterlockedExchangeAdd((void*)ptr, addend); return _InterlockedExchangeAdd((void*)__ptr, __addend);
#elif defined(__ICL) || defined(_MSC_VER) #elif defined(__ICL) || defined(_MSC_VER)
return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr), return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(__ptr),
addend); __addend);
#elif defined(__GNUC__) #elif defined(__GNUC__)
return __sync_fetch_and_add(ptr, addend); return __sync_fetch_and_add(__ptr, __addend);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
volatile int32 before, after; volatile int32 __before, __after;
do do
{ {
before = *ptr; __before = *__ptr;
after = before + addend; __after = __before + __addend;
} while (atomic_cas_32((volatile unsigned int*)ptr, before, } while (atomic_cas_32((volatile unsigned int*)__ptr, __before,
after) != before); __after) != __before);
return before; return __before;
#else //fallback, slow #else //fallback, slow
#pragma message("slow fetch_and_add_32") #pragma message("slow __fetch_and_add_32")
int32 res; int32 __res;
#pragma omp critical #pragma omp critical
{ {
res = *ptr; __res = *__ptr;
*(ptr) += addend; *(__ptr) += __addend;
} }
return res; return __res;
#endif #endif
} }
/** @brief Add a value to a variable, atomically. /** @brief Add a value to a variable, atomically.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to a 64-bit signed integer. * @param __ptr Pointer to a 64-bit signed integer.
* @param addend Value to add. * @param __addend Value to add.
*/ */
inline int64 inline int64
fetch_and_add_64(volatile int64* ptr, int64 addend) __fetch_and_add_64(volatile int64* __ptr, int64 __addend)
{ {
#if defined(__ICC) && defined(__x86_64) //x86 version #if defined(__ICC) && defined(__x86_64) //x86 version
return faa64<int>((int64*)ptr, addend); return __faa64<int>((int64*)__ptr, __addend);
#elif defined(__ECC) //IA-64 version #elif defined(__ECC) //IA-64 version
return _InterlockedExchangeAdd64((void*)ptr, addend); return _InterlockedExchangeAdd64((void*)__ptr, __addend);
#elif defined(__ICL) || defined(_MSC_VER) #elif defined(__ICL) || defined(_MSC_VER)
#ifndef _WIN64 #ifndef _WIN64
_GLIBCXX_PARALLEL_ASSERT(false); //not available in this case _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
return 0; return 0;
#else #else
return _InterlockedExchangeAdd64(ptr, addend); return _InterlockedExchangeAdd64(__ptr, __addend);
#endif #endif
#elif defined(__GNUC__) && defined(__x86_64) #elif defined(__GNUC__) && defined(__x86_64)
return __sync_fetch_and_add(ptr, addend); return __sync_fetch_and_add(__ptr, __addend);
#elif defined(__GNUC__) && defined(__i386) && \ #elif defined(__GNUC__) && defined(__i386) && \
(defined(__i686) || defined(__pentium4) || defined(__athlon)) (defined(__i686) || defined(__pentium4) || defined(__athlon))
return __sync_fetch_and_add(ptr, addend); return __sync_fetch_and_add(__ptr, __addend);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
volatile int64 before, after; volatile int64 __before, __after;
do do
{ {
before = *ptr; __before = *__ptr;
after = before + addend; __after = __before + __addend;
} while (atomic_cas_64((volatile unsigned long long*)ptr, before, } while (atomic_cas_64((volatile unsigned long long*)__ptr, __before,
after) != before); __after) != __before);
return before; return __before;
#else //fallback, slow #else //fallback, slow
#if defined(__GNUC__) && defined(__i386) #if defined(__GNUC__) && defined(__i386)
// XXX doesn't work with -march=native // XXX doesn'__t work with -march=native
//#warning "please compile with -march=i686 or better" //#warning "please compile with -march=i686 or better"
#endif #endif
#pragma message("slow fetch_and_add_64") #pragma message("slow __fetch_and_add_64")
int64 res; int64 __res;
#pragma omp critical #pragma omp critical
{ {
res = *ptr; __res = *__ptr;
*(ptr) += addend; *(__ptr) += __addend;
} }
return res; return __res;
#endif #endif
} }
/** @brief Add a value to a variable, atomically. /** @brief Add a value to a variable, atomically.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to a signed integer. * @param __ptr Pointer to a signed integer.
* @param addend Value to add. * @param __addend Value to add.
*/ */
template<typename T> template<typename _Tp>
inline T inline _Tp
fetch_and_add(volatile T* ptr, T addend) __fetch_and_add(volatile _Tp* __ptr, _Tp __addend)
{ {
if (sizeof(T) == sizeof(int32)) if (sizeof(_Tp) == sizeof(int32))
return (T)fetch_and_add_32((volatile int32*) ptr, (int32)addend); return (_Tp)__fetch_and_add_32((volatile int32*) __ptr, (int32)__addend);
else if (sizeof(T) == sizeof(int64)) else if (sizeof(_Tp) == sizeof(int64))
return (T)fetch_and_add_64((volatile int64*) ptr, (int64)addend); return (_Tp)__fetch_and_add_64((volatile int64*) __ptr, (int64)__addend);
else else
_GLIBCXX_PARALLEL_ASSERT(false); _GLIBCXX_PARALLEL_ASSERT(false);
} }
...@@ -195,141 +195,141 @@ namespace __gnu_parallel ...@@ -195,141 +195,141 @@ namespace __gnu_parallel
#if defined(__ICC) #if defined(__ICC)
template<typename must_be_int = int> template<typename _MustBeInt = int>
inline int32 inline int32
cas32(volatile int32* ptr, int32 old, int32 nw) __cas32(volatile int32* __ptr, int32 __old, int32 __nw)
{ {
int32 before; int32 __before;
__asm__ __volatile__("lock; cmpxchgl %1,%2" __asm__ __volatile__("lock; cmpxchgl %1,%2"
: "=a"(before) : "=a"(__before)
: "q"(nw), "m"(*(volatile long long*)(ptr)), "0"(old) : "q"(__nw), "__m"(*(volatile long long*)(__ptr)), "0"(__old)
: "memory"); : "memory");
return before; return __before;
} }
#if defined(__x86_64) #if defined(__x86_64)
template<typename must_be_int = int> template<typename _MustBeInt = int>
inline int64 inline int64
cas64(volatile int64 *ptr, int64 old, int64 nw) __cas64(volatile int64 *__ptr, int64 __old, int64 __nw)
{ {
int64 before; int64 __before;
__asm__ __volatile__("lock; cmpxchgq %1,%2" __asm__ __volatile__("lock; cmpxchgq %1,%2"
: "=a"(before) : "=a"(__before)
: "q"(nw), "m"(*(volatile long long*)(ptr)), "0"(old) : "q"(__nw), "__m"(*(volatile long long*)(__ptr)), "0"(__old)
: "memory"); : "memory");
return before; return __before;
} }
#endif #endif
#endif #endif
/** @brief Compare @c *ptr and @c comparand. If equal, let @c /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
* *ptr=replacement and return @c true, return @c false otherwise. * *__ptr=__replacement and return @__c true, return @__c false otherwise.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to 32-bit signed integer. * @param __ptr Pointer to 32-bit signed integer.
* @param comparand Compare value. * @param __comparand Compare value.
* @param replacement Replacement value. * @param __replacement Replacement value.
*/ */
inline bool inline bool
compare_and_swap_32(volatile int32* ptr, int32 comparand, int32 replacement) __compare_and_swap_32(volatile int32* __ptr, int32 __comparand, int32 __replacement)
{ {
#if defined(__ICC) //x86 version #if defined(__ICC) //x86 version
return _InterlockedCompareExchange((void*)ptr, replacement, return _InterlockedCompareExchange((void*)__ptr, __replacement,
comparand) == comparand; __comparand) == __comparand;
#elif defined(__ECC) //IA-64 version #elif defined(__ECC) //IA-64 version
return _InterlockedCompareExchange((void*)ptr, replacement, return _InterlockedCompareExchange((void*)__ptr, __replacement,
comparand) == comparand; __comparand) == __comparand;
#elif defined(__ICL) || defined(_MSC_VER) #elif defined(__ICL) || defined(_MSC_VER)
return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(__ptr),
replacement, comparand) == comparand; __replacement, __comparand) == __comparand;
#elif defined(__GNUC__) #elif defined(__GNUC__)
return __sync_bool_compare_and_swap(ptr, comparand, replacement); return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
return atomic_cas_32((volatile unsigned int*)ptr, comparand, return atomic_cas_32((volatile unsigned int*)__ptr, __comparand,
replacement) == comparand; __replacement) == __comparand;
#else #else
#pragma message("slow compare_and_swap_32") #pragma message("slow __compare_and_swap_32")
bool res = false; bool __res = false;
#pragma omp critical #pragma omp critical
{ {
if (*ptr == comparand) if (*__ptr == __comparand)
{ {
*ptr = replacement; *__ptr = __replacement;
res = true; __res = true;
} }
} }
return res; return __res;
#endif #endif
} }
/** @brief Compare @c *ptr and @c comparand. If equal, let @c /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
* *ptr=replacement and return @c true, return @c false otherwise. * *__ptr=__replacement and return @__c true, return @__c false otherwise.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to 64-bit signed integer. * @param __ptr Pointer to 64-bit signed integer.
* @param comparand Compare value. * @param __comparand Compare value.
* @param replacement Replacement value. * @param __replacement Replacement value.
*/ */
inline bool inline bool
compare_and_swap_64(volatile int64* ptr, int64 comparand, int64 replacement) __compare_and_swap_64(volatile int64* __ptr, int64 __comparand, int64 __replacement)
{ {
#if defined(__ICC) && defined(__x86_64) //x86 version #if defined(__ICC) && defined(__x86_64) //x86 version
return cas64<int>(ptr, comparand, replacement) == comparand; return __cas64<int>(__ptr, __comparand, __replacement) == __comparand;
#elif defined(__ECC) //IA-64 version #elif defined(__ECC) //IA-64 version
return _InterlockedCompareExchange64((void*)ptr, replacement, return _InterlockedCompareExchange64((void*)__ptr, __replacement,
comparand) == comparand; __comparand) == __comparand;
#elif defined(__ICL) || defined(_MSC_VER) #elif defined(__ICL) || defined(_MSC_VER)
#ifndef _WIN64 #ifndef _WIN64
_GLIBCXX_PARALLEL_ASSERT(false); //not available in this case _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
return 0; return 0;
#else #else
return _InterlockedCompareExchange64(ptr, replacement, return _InterlockedCompareExchange64(__ptr, __replacement,
comparand) == comparand; __comparand) == __comparand;
#endif #endif
#elif defined(__GNUC__) && defined(__x86_64) #elif defined(__GNUC__) && defined(__x86_64)
return __sync_bool_compare_and_swap(ptr, comparand, replacement); return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
#elif defined(__GNUC__) && defined(__i386) && \ #elif defined(__GNUC__) && defined(__i386) && \
(defined(__i686) || defined(__pentium4) || defined(__athlon)) (defined(__i686) || defined(__pentium4) || defined(__athlon))
return __sync_bool_compare_and_swap(ptr, comparand, replacement); return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
return atomic_cas_64((volatile unsigned long long*)ptr, return atomic_cas_64((volatile unsigned long long*)__ptr,
comparand, replacement) == comparand; __comparand, __replacement) == __comparand;
#else #else
#if defined(__GNUC__) && defined(__i386) #if defined(__GNUC__) && defined(__i386)
// XXX -march=native // XXX -march=native
//#warning "please compile with -march=i686 or better" //#warning "please compile with -march=i686 or better"
#endif #endif
#pragma message("slow compare_and_swap_64") #pragma message("slow __compare_and_swap_64")
bool res = false; bool __res = false;
#pragma omp critical #pragma omp critical
{ {
if (*ptr == comparand) if (*__ptr == __comparand)
{ {
*ptr = replacement; *__ptr = __replacement;
res = true; __res = true;
} }
} }
return res; return __res;
#endif #endif
} }
/** @brief Compare @c *ptr and @c comparand. If equal, let @c /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
* *ptr=replacement and return @c true, return @c false otherwise. * *__ptr=__replacement and return @__c true, return @__c false otherwise.
* *
* Implementation is heavily platform-dependent. * Implementation is heavily platform-dependent.
* @param ptr Pointer to signed integer. * @param __ptr Pointer to signed integer.
* @param comparand Compare value. * @param __comparand Compare value.
* @param replacement Replacement value. */ * @param __replacement Replacement value. */
template<typename T> template<typename _Tp>
inline bool inline bool
compare_and_swap(volatile T* ptr, T comparand, T replacement) __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement)
{ {
if (sizeof(T) == sizeof(int32)) if (sizeof(_Tp) == sizeof(int32))
return compare_and_swap_32((volatile int32*) ptr, (int32)comparand, (int32)replacement); return __compare_and_swap_32((volatile int32*) __ptr, (int32)__comparand, (int32)__replacement);
else if (sizeof(T) == sizeof(int64)) else if (sizeof(_Tp) == sizeof(int64))
return compare_and_swap_64((volatile int64*) ptr, (int64)comparand, (int64)replacement); return __compare_and_swap_64((volatile int64*) __ptr, (int64)__comparand, (int64)__replacement);
else else
_GLIBCXX_PARALLEL_ASSERT(false); _GLIBCXX_PARALLEL_ASSERT(false);
} }
...@@ -337,7 +337,7 @@ namespace __gnu_parallel ...@@ -337,7 +337,7 @@ namespace __gnu_parallel
/** @brief Yield the control to another thread, without waiting for /** @brief Yield the control to another thread, without waiting for
the end to the time slice. */ the end to the time slice. */
inline void inline void
yield() __yield()
{ {
#if defined (_WIN32) && !defined (__CYGWIN__) #if defined (_WIN32) && !defined (__CYGWIN__)
Sleep(0); Sleep(0);
......
...@@ -38,15 +38,15 @@ ...@@ -38,15 +38,15 @@
/** @def _GLIBCXX_CALL /** @def _GLIBCXX_CALL
* @brief Macro to produce log message when entering a function. * @brief Macro to produce log message when entering a function.
* @param n Input size. * @param __n Input size.
* @see _GLIBCXX_VERBOSE_LEVEL */ * @see _GLIBCXX_VERBOSE_LEVEL */
#if (_GLIBCXX_VERBOSE_LEVEL == 0) #if (_GLIBCXX_VERBOSE_LEVEL == 0)
#define _GLIBCXX_CALL(n) #define _GLIBCXX_CALL(__n)
#endif #endif
#if (_GLIBCXX_VERBOSE_LEVEL == 1) #if (_GLIBCXX_VERBOSE_LEVEL == 1)
#define _GLIBCXX_CALL(n) \ #define _GLIBCXX_CALL(__n) \
printf(" %s:\niam = %d, n = %ld, num_threads = %d\n", \ printf(" %__s:\niam = %d, __n = %ld, __num_threads = %d\n", \
__PRETTY_FUNCTION__, omp_get_thread_num(), (n), get_max_threads()); __PRETTY_FUNCTION__, omp_get_thread_num(), (__n), __get_max_threads());
#endif #endif
#ifndef _GLIBCXX_SCALE_DOWN_FPU #ifndef _GLIBCXX_SCALE_DOWN_FPU
...@@ -64,12 +64,12 @@ ...@@ -64,12 +64,12 @@
#ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
/** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
* Consider the size of the L1 cache for * Consider the size of the L1 cache for
* __gnu_parallel::parallel_random_shuffle(). */ * gnu_parallel::__parallel_random_shuffle(). */
#define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0 #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0
#endif #endif
#ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
/** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
* Consider the size of the TLB for * Consider the size of the TLB for
* __gnu_parallel::parallel_random_shuffle(). */ * gnu_parallel::__parallel_random_shuffle(). */
#define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0 #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0
#endif #endif
...@@ -33,54 +33,54 @@ ...@@ -33,54 +33,54 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Function to split a sequence into parts of almost equal size. /** @brief function to split a sequence into parts of almost equal size.
* *
* The resulting sequence s of length num_threads+1 contains the splitting * The resulting sequence __s of length __num_threads+1 contains the splitting
* positions when splitting the range [0,n) into parts of almost * positions when splitting the range [0,__n) into parts of almost
* equal size (plus minus 1). The first entry is 0, the last one * equal size (plus minus 1). The first entry is 0, the last one
* n. There may result empty parts. * n. There may result empty parts.
* @param n Number of elements * @param __n Number of elements
* @param num_threads Number of parts * @param __num_threads Number of parts
* @param s Splitters * @param __s Splitters
* @returns End of splitter sequence, i. e. @c s+num_threads+1 */ * @returns End of splitter sequence, i.e. @__c __s+__num_threads+1 */
template<typename difference_type, typename OutputIterator> template<typename _DifferenceType, typename _OutputIterator>
OutputIterator _OutputIterator
equally_split(difference_type n, thread_index_t num_threads, OutputIterator s) equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s)
{ {
difference_type chunk_length = n / num_threads; _DifferenceType __chunk_length = __n / __num_threads;
difference_type num_longer_chunks = n % num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads;
difference_type pos = 0; _DifferenceType __pos = 0;
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
{ {
*s++ = pos; *__s++ = __pos;
pos += (i < num_longer_chunks) ? (chunk_length + 1) : chunk_length; __pos += (__i < __num_longer_chunks) ? (__chunk_length + 1) : __chunk_length;
} }
*s++ = n; *__s++ = __n;
return s; return __s;
} }
/** @brief Function to split a sequence into parts of almost equal size. /** @brief function to split a sequence into parts of almost equal size.
* *
* Returns the position of the splitting point between * Returns the position of the splitting point between
* thread number thread_no (included) and * thread number __thread_no (included) and
* thread number thread_no+1 (excluded). * thread number __thread_no+1 (excluded).
* @param n Number of elements * @param __n Number of elements
* @param num_threads Number of parts * @param __num_threads Number of parts
* @returns _SplittingAlgorithm point */ * @returns splitting point */
template<typename difference_type> template<typename _DifferenceType>
difference_type _DifferenceType
equally_split_point(difference_type n, equally_split_point(_DifferenceType __n,
thread_index_t num_threads, _ThreadIndex __num_threads,
thread_index_t thread_no) _ThreadIndex __thread_no)
{ {
difference_type chunk_length = n / num_threads; _DifferenceType __chunk_length = __n / __num_threads;
difference_type num_longer_chunks = n % num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads;
if (thread_no < num_longer_chunks) if (__thread_no < __num_longer_chunks)
return thread_no * (chunk_length + 1); return __thread_no * (__chunk_length + 1);
else else
return num_longer_chunks * (chunk_length + 1) return __num_longer_chunks * (__chunk_length + 1)
+ (thread_no - num_longer_chunks) * chunk_length; + (__thread_no - __num_longer_chunks) * __chunk_length;
} }
} }
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
#ifndef _GLIBCXX_TREE_INITIAL_SPLITTING #ifndef _GLIBCXX_TREE_INITIAL_SPLITTING
/** @def _GLIBCXX_TREE_INITIAL_SPLITTING /** @def _GLIBCXX_TREE_INITIAL_SPLITTING
* @brief Include the initial splitting variant for * @brief Include the initial splitting variant for
* _Rb_tree::insert_unique(InputIterator beg, InputIterator end). * _Rb_tree::insert_unique(_IIter beg, _IIter __end).
* @see __gnu_parallel::_Rb_tree */ * @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_INITIAL_SPLITTING 1 #define _GLIBCXX_TREE_INITIAL_SPLITTING 1
#endif #endif
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
#ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING #ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING
/** @def _GLIBCXX_TREE_DYNAMIC_BALANCING /** @def _GLIBCXX_TREE_DYNAMIC_BALANCING
* @brief Include the dynamic balancing variant for * @brief Include the dynamic balancing variant for
* _Rb_tree::insert_unique(InputIterator beg, InputIterator end). * _Rb_tree::insert_unique(_IIter beg, _IIter __end).
* @see __gnu_parallel::_Rb_tree */ * @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_DYNAMIC_BALANCING 1 #define _GLIBCXX_TREE_DYNAMIC_BALANCING 1
#endif #endif
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
#ifndef _GLIBCXX_TREE_FULL_COPY #ifndef _GLIBCXX_TREE_FULL_COPY
/** @def _GLIBCXX_TREE_FULL_COPY /** @def _GLIBCXX_TREE_FULL_COPY
* @brief In order to sort the input sequence of * @brief In order to sort the input sequence of
* _Rb_tree::insert_unique(InputIterator beg, InputIterator end) a * _Rb_tree::insert_unique(_IIter beg, _IIter __end) a
* full copy of the input elements is done. * full copy of the input elements is done.
* @see __gnu_parallel::_Rb_tree */ * @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_FULL_COPY 1 #define _GLIBCXX_TREE_FULL_COPY 1
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/find.h /** @file parallel/find.h
* @brief Parallel implementation base for std::find(), std::equal() * @brief Parallel implementation __base for std::find(), std::equal()
* and related functions. * and related functions.
* This file is a GNU parallel extension to the Standard C++ Library. * This file is a GNU parallel extension to the Standard C++ Library.
*/ */
...@@ -44,36 +44,36 @@ namespace __gnu_parallel ...@@ -44,36 +44,36 @@ namespace __gnu_parallel
{ {
/** /**
* @brief Parallel std::find, switch for different algorithms. * @brief Parallel std::find, switch for different algorithms.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. Must have same * @param __begin2 Begin iterator of second sequence. Must have same
* length as first sequence. * length as first sequence.
* @param pred Find predicate. * @param __pred Find predicate.
* @param selector Functionality (e. g. std::find_if (), std::equal(),...) * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences. * @return Place of finding in both sequences.
*/ */
template<typename RandomAccessIterator1, template<typename _RAIter1,
typename RandomAccessIterator2, typename _RAIter2,
typename Pred, typename _Pred,
typename Selector> typename _Selector>
inline std::pair<RandomAccessIterator1, RandomAccessIterator2> inline std::pair<_RAIter1, _RAIter2>
find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, __find_template(_RAIter1 __begin1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred, Selector selector) _RAIter2 __begin2, _Pred __pred, _Selector __selector)
{ {
switch (_Settings::get().find_algorithm) switch (_Settings::get().find_algorithm)
{ {
case GROWING_BLOCKS: case GROWING_BLOCKS:
return find_template(begin1, end1, begin2, pred, selector, return __find_template(__begin1, __end1, __begin2, __pred, __selector,
growing_blocks_tag()); growing_blocks_tag());
case CONSTANT_SIZE_BLOCKS: case CONSTANT_SIZE_BLOCKS:
return find_template(begin1, end1, begin2, pred, selector, return __find_template(__begin1, __end1, __begin2, __pred, __selector,
constant_size_blocks_tag()); constant_size_blocks_tag());
case EQUAL_SPLIT: case EQUAL_SPLIT:
return find_template(begin1, end1, begin2, pred, selector, return __find_template(__begin1, __end1, __begin2, __pred, __selector,
equal_split_tag()); equal_split_tag());
default: default:
_GLIBCXX_PARALLEL_ASSERT(false); _GLIBCXX_PARALLEL_ASSERT(false);
return std::make_pair(begin1, begin2); return std::make_pair(__begin1, __begin2);
} }
} }
...@@ -81,80 +81,80 @@ template<typename RandomAccessIterator1, ...@@ -81,80 +81,80 @@ template<typename RandomAccessIterator1,
/** /**
* @brief Parallel std::find, equal splitting variant. * @brief Parallel std::find, equal splitting variant.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. Second sequence * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence. * must have same length as first sequence.
* @param pred Find predicate. * @param __pred Find predicate.
* @param selector Functionality (e. g. std::find_if (), std::equal(),...) * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences. * @return Place of finding in both sequences.
*/ */
template<typename RandomAccessIterator1, template<typename _RAIter1,
typename RandomAccessIterator2, typename _RAIter2,
typename Pred, typename _Pred,
typename Selector> typename _Selector>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
find_template(RandomAccessIterator1 begin1, __find_template(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, _RAIter2 __begin2,
Pred pred, _Pred __pred,
Selector selector, _Selector __selector,
equal_split_tag) equal_split_tag)
{ {
_GLIBCXX_CALL(end1 - begin1) _GLIBCXX_CALL(__end1 - __begin1)
typedef std::iterator_traits<RandomAccessIterator1> traits_type; typedef std::iterator_traits<_RAIter1> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
difference_type length = end1 - begin1; _DifferenceType __length = __end1 - __begin1;
difference_type result = length; _DifferenceType __result = __length;
difference_type* borders; _DifferenceType* __borders;
omp_lock_t result_lock; omp_lock_t __result_lock;
omp_init_lock(&result_lock); omp_init_lock(&__result_lock);
thread_index_t num_threads = get_max_threads(); _ThreadIndex __num_threads = __get_max_threads();
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
borders = new difference_type[num_threads + 1]; __borders = new _DifferenceType[__num_threads + 1];
equally_split(length, num_threads, borders); equally_split(__length, __num_threads, __borders);
} //single } //single
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type start = borders[iam], stop = borders[iam + 1]; _DifferenceType __start = __borders[__iam], __stop = __borders[__iam + 1];
RandomAccessIterator1 i1 = begin1 + start; _RAIter1 __i1 = __begin1 + __start;
RandomAccessIterator2 i2 = begin2 + start; _RAIter2 __i2 = __begin2 + __start;
for (difference_type pos = start; pos < stop; ++pos) for (_DifferenceType __pos = __start; __pos < __stop; ++__pos)
{ {
#pragma omp flush(result) #pragma omp flush(__result)
// Result has been set to something lower. // Result has been set to something lower.
if (result < pos) if (__result < __pos)
break; break;
if (selector(i1, i2, pred)) if (__selector(__i1, __i2, __pred))
{ {
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
if (pos < result) if (__pos < __result)
result = pos; __result = __pos;
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
break; break;
} }
++i1; ++__i1;
++i2; ++__i2;
} }
} //parallel } //parallel
omp_destroy_lock(&result_lock); omp_destroy_lock(&__result_lock);
delete[] borders; delete[] __borders;
return return
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, std::pair<_RAIter1, _RAIter2>(__begin1 + __result,
begin2 + result); __begin2 + __result);
} }
#endif #endif
...@@ -163,12 +163,12 @@ template<typename RandomAccessIterator1, ...@@ -163,12 +163,12 @@ template<typename RandomAccessIterator1,
/** /**
* @brief Parallel std::find, growing block size variant. * @brief Parallel std::find, growing block size variant.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. Second sequence * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence. * must have same length as first sequence.
* @param pred Find predicate. * @param __pred Find predicate.
* @param selector Functionality (e. g. std::find_if (), std::equal(),...) * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences. * @return Place of finding in both sequences.
* @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_sequential_search_size
* @see __gnu_parallel::_Settings::find_initial_block_size * @see __gnu_parallel::_Settings::find_initial_block_size
...@@ -183,105 +183,105 @@ template<typename RandomAccessIterator1, ...@@ -183,105 +183,105 @@ template<typename RandomAccessIterator1,
* for CSB, the blocks are allocated in a predetermined manner, * for CSB, the blocks are allocated in a predetermined manner,
* namely spacial round-robin. * namely spacial round-robin.
*/ */
template<typename RandomAccessIterator1, template<typename _RAIter1,
typename RandomAccessIterator2, typename _RAIter2,
typename Pred, typename _Pred,
typename Selector> typename _Selector>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, __find_template(_RAIter1 __begin1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred, Selector selector, _RAIter2 __begin2, _Pred __pred, _Selector __selector,
growing_blocks_tag) growing_blocks_tag)
{ {
_GLIBCXX_CALL(end1 - begin1) _GLIBCXX_CALL(__end1 - __begin1)
typedef std::iterator_traits<RandomAccessIterator1> traits_type; typedef std::iterator_traits<_RAIter1> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
difference_type length = end1 - begin1; _DifferenceType __length = __end1 - __begin1;
difference_type sequential_search_size = _DifferenceType __sequential_search_size =
std::min<difference_type>(length, __s.find_sequential_search_size); std::min<_DifferenceType>(__length, __s.find_sequential_search_size);
// Try it sequentially first. // Try it sequentially first.
std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result = std::pair<_RAIter1, _RAIter2> __find_seq_result =
selector.sequential_algorithm( __selector._M_sequential_algorithm(
begin1, begin1 + sequential_search_size, begin2, pred); __begin1, __begin1 + __sequential_search_size, __begin2, __pred);
if (find_seq_result.first != (begin1 + sequential_search_size)) if (__find_seq_result.first != (__begin1 + __sequential_search_size))
return find_seq_result; return __find_seq_result;
// Index of beginning of next free block (after sequential find). // Index of beginning of next free block (after sequential find).
difference_type next_block_start = sequential_search_size; _DifferenceType __next_block_start = __sequential_search_size;
difference_type result = length; _DifferenceType __result = __length;
omp_lock_t result_lock; omp_lock_t __result_lock;
omp_init_lock(&result_lock); omp_init_lock(&__result_lock);
thread_index_t num_threads = get_max_threads(); _ThreadIndex __num_threads = __get_max_threads();
# pragma omp parallel shared(result) num_threads(num_threads) # pragma omp parallel shared(__result) num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
// Not within first k elements -> start parallel. // Not within first __k __elements -> start parallel.
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type block_size = __s.find_initial_block_size; _DifferenceType __block_size = __s.find_initial_block_size;
difference_type start = _DifferenceType __start =
fetch_and_add<difference_type>(&next_block_start, block_size); __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size);
// Get new block, update pointer to next block. // Get new block, update pointer to next block.
difference_type stop = _DifferenceType __stop =
std::min<difference_type>(length, start + block_size); std::min<_DifferenceType>(__length, __start + __block_size);
std::pair<RandomAccessIterator1, RandomAccessIterator2> local_result; std::pair<_RAIter1, _RAIter2> __local_result;
while (start < length) while (__start < __length)
{ {
# pragma omp flush(result) # pragma omp flush(__result)
// Get new value of result. // Get new value of result.
if (result < start) if (__result < __start)
{ {
// No chance to find first element. // No chance to find first element.
break; break;
} }
local_result = selector.sequential_algorithm( __local_result = __selector._M_sequential_algorithm(
begin1 + start, begin1 + stop, begin2 + start, pred); __begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred);
if (local_result.first != (begin1 + stop)) if (__local_result.first != (__begin1 + __stop))
{ {
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
if ((local_result.first - begin1) < result) if ((__local_result.first - __begin1) < __result)
{ {
result = local_result.first - begin1; __result = __local_result.first - __begin1;
// Result cannot be in future blocks, stop algorithm. // Result cannot be in future blocks, stop algorithm.
fetch_and_add<difference_type>(&next_block_start, length); __fetch_and_add<_DifferenceType>(&__next_block_start, __length);
} }
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
} }
block_size = __block_size =
std::min<difference_type>(block_size * __s.find_increasing_factor, std::min<_DifferenceType>(__block_size * __s.find_increasing_factor,
__s.find_maximum_block_size); __s.find_maximum_block_size);
// Get new block, update pointer to next block. // Get new block, update pointer to next block.
start = __start =
fetch_and_add<difference_type>(&next_block_start, block_size); __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size);
stop = ((length < (start + block_size)) __stop = ((__length < (__start + __block_size))
? length : (start + block_size)); ? __length : (__start + __block_size));
} }
} //parallel } //parallel
omp_destroy_lock(&result_lock); omp_destroy_lock(&__result_lock);
// Return iterator on found element. // Return iterator on found element.
return return
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, std::pair<_RAIter1, _RAIter2>(__begin1 + __result,
begin2 + result); __begin2 + __result);
} }
#endif #endif
...@@ -290,12 +290,12 @@ template<typename RandomAccessIterator1, ...@@ -290,12 +290,12 @@ template<typename RandomAccessIterator1,
/** /**
* @brief Parallel std::find, constant block size variant. * @brief Parallel std::find, constant block size variant.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. Second sequence * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence. * must have same length as first sequence.
* @param pred Find predicate. * @param __pred Find predicate.
* @param selector Functionality (e. g. std::find_if (), std::equal(),...) * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences. * @return Place of finding in both sequences.
* @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_sequential_search_size
* @see __gnu_parallel::_Settings::find_block_size * @see __gnu_parallel::_Settings::find_block_size
...@@ -306,94 +306,94 @@ template<typename RandomAccessIterator1, ...@@ -306,94 +306,94 @@ template<typename RandomAccessIterator1,
* blocks are allocated in a predetermined manner, namely spacial * blocks are allocated in a predetermined manner, namely spacial
* round-robin. * round-robin.
*/ */
template<typename RandomAccessIterator1, template<typename _RAIter1,
typename RandomAccessIterator2, typename _RAIter2,
typename Pred, typename _Pred,
typename Selector> typename _Selector>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, __find_template(_RAIter1 __begin1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred, Selector selector, _RAIter2 __begin2, _Pred __pred, _Selector __selector,
constant_size_blocks_tag) constant_size_blocks_tag)
{ {
_GLIBCXX_CALL(end1 - begin1) _GLIBCXX_CALL(__end1 - __begin1)
typedef std::iterator_traits<RandomAccessIterator1> traits_type; typedef std::iterator_traits<_RAIter1> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
difference_type length = end1 - begin1; _DifferenceType __length = __end1 - __begin1;
difference_type sequential_search_size = std::min<difference_type>( _DifferenceType __sequential_search_size = std::min<_DifferenceType>(
length, __s.find_sequential_search_size); __length, __s.find_sequential_search_size);
// Try it sequentially first. // Try it sequentially first.
std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result = std::pair<_RAIter1, _RAIter2> __find_seq_result =
selector.sequential_algorithm(begin1, begin1 + sequential_search_size, __selector._M_sequential_algorithm(__begin1, __begin1 + __sequential_search_size,
begin2, pred); __begin2, __pred);
if (find_seq_result.first != (begin1 + sequential_search_size)) if (__find_seq_result.first != (__begin1 + __sequential_search_size))
return find_seq_result; return __find_seq_result;
difference_type result = length; _DifferenceType __result = __length;
omp_lock_t result_lock; omp_lock_t __result_lock;
omp_init_lock(&result_lock); omp_init_lock(&__result_lock);
// Not within first sequential_search_size elements -> start parallel. // Not within first __sequential_search_size elements -> start parallel.
thread_index_t num_threads = get_max_threads(); _ThreadIndex __num_threads = __get_max_threads();
# pragma omp parallel shared(result) num_threads(num_threads) # pragma omp parallel shared(__result) num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type block_size = __s.find_initial_block_size; _DifferenceType __block_size = __s.find_initial_block_size;
// First element of thread's current iteration. // First element of thread's current iteration.
difference_type iteration_start = sequential_search_size; _DifferenceType __iteration_start = __sequential_search_size;
// Where to work (initialization). // Where to work (initialization).
difference_type start = iteration_start + iam * block_size; _DifferenceType __start = __iteration_start + __iam * __block_size;
difference_type stop = _DifferenceType __stop =
std::min<difference_type>(length, start + block_size); std::min<_DifferenceType>(__length, __start + __block_size);
std::pair<RandomAccessIterator1, RandomAccessIterator2> local_result; std::pair<_RAIter1, _RAIter2> __local_result;
while (start < length) while (__start < __length)
{ {
// Get new value of result. // Get new value of result.
# pragma omp flush(result) # pragma omp flush(__result)
// No chance to find first element. // No chance to find first element.
if (result < start) if (__result < __start)
break; break;
local_result = selector.sequential_algorithm( __local_result = __selector._M_sequential_algorithm(
begin1 + start, begin1 + stop, __begin1 + __start, __begin1 + __stop,
begin2 + start, pred); __begin2 + __start, __pred);
if (local_result.first != (begin1 + stop)) if (__local_result.first != (__begin1 + __stop))
{ {
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
if ((local_result.first - begin1) < result) if ((__local_result.first - __begin1) < __result)
result = local_result.first - begin1; __result = __local_result.first - __begin1;
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
// Will not find better value in its interval. // Will not find better value in its interval.
break; break;
} }
iteration_start += num_threads * block_size; __iteration_start += __num_threads * __block_size;
// Where to work. // Where to work.
start = iteration_start + iam * block_size; __start = __iteration_start + __iam * __block_size;
stop = std::min<difference_type>(length, start + block_size); __stop = std::min<_DifferenceType>(__length, __start + __block_size);
} }
} //parallel } //parallel
omp_destroy_lock(&result_lock); omp_destroy_lock(&__result_lock);
// Return iterator on found element. // Return iterator on found element.
return return
std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, std::pair<_RAIter1, _RAIter2>(__begin1 + __result,
begin2 + result); __begin2 + __result);
} }
#endif #endif
} // end namespace } // end namespace
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/find_selectors.h /** @file parallel/find_selectors.h
* @brief Function objects representing different tasks to be plugged * @brief _Function objects representing different tasks to be plugged
* into the parallel find algorithm. * into the parallel find algorithm.
* This file is a GNU parallel extension to the Standard C++ Library. * This file is a GNU parallel extension to the Standard C++ Library.
*/ */
...@@ -39,153 +39,153 @@ ...@@ -39,153 +39,153 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Base class of all __gnu_parallel::find_template selectors. */ /** @brief Base class of all __gnu_parallel::__find_template selectors. */
struct generic_find_selector struct __generic_find_selector
{ }; { };
/** /**
* @brief Test predicate on a single element, used for std::find() * @brief Test predicate on a single element, used for std::find()
* and std::find_if (). * and std::find_if ().
*/ */
struct find_if_selector : public generic_find_selector struct __find_if_selector : public __generic_find_selector
{ {
/** @brief Test on one position. /** @brief Test on one __position.
* @param i1 Iterator on first sequence. * @param __i1 _Iterator on first sequence.
* @param i2 Iterator on second sequence (unused). * @param __i2 _Iterator on second sequence (unused).
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
bool bool
operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred) operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{ return pred(*i1); } { return __pred(*__i1); }
/** @brief Corresponding sequential algorithm on a sequence. /** @brief Corresponding sequential algorithm on a sequence.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
sequential_algorithm(RandomAccessIterator1 begin1, _M_sequential_algorithm(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred) _RAIter2 __begin2, _Pred __pred)
{ return std::make_pair(find_if(begin1, end1, pred, { return std::make_pair(find_if(__begin1, __end1, __pred,
sequential_tag()), begin2); } sequential_tag()), __begin2); }
}; };
/** @brief Test predicate on two adjacent elements. */ /** @brief Test predicate on two adjacent __elements. */
struct adjacent_find_selector : public generic_find_selector struct __adjacent_find_selector : public __generic_find_selector
{ {
/** @brief Test on one position. /** @brief Test on one __position.
* @param i1 Iterator on first sequence. * @param __i1 _Iterator on first sequence.
* @param i2 Iterator on second sequence (unused). * @param __i2 _Iterator on second sequence (unused).
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
bool bool
operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred) operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{ {
// Passed end iterator is one short. // Passed end iterator is one short.
return pred(*i1, *(i1 + 1)); return __pred(*__i1, *(__i1 + 1));
} }
/** @brief Corresponding sequential algorithm on a sequence. /** @brief Corresponding sequential algorithm on a sequence.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
sequential_algorithm(RandomAccessIterator1 begin1, _M_sequential_algorithm(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred) _RAIter2 __begin2, _Pred __pred)
{ {
// Passed end iterator is one short. // Passed end iterator is one short.
RandomAccessIterator1 spot = adjacent_find(begin1, end1 + 1, _RAIter1 spot = adjacent_find(__begin1, __end1 + 1,
pred, sequential_tag()); __pred, sequential_tag());
if (spot == (end1 + 1)) if (spot == (__end1 + 1))
spot = end1; spot = __end1;
return std::make_pair(spot, begin2); return std::make_pair(spot, __begin2);
} }
}; };
/** @brief Test inverted predicate on a single element. */ /** @brief Test inverted predicate on a single element. */
struct mismatch_selector : public generic_find_selector struct __mismatch_selector : public __generic_find_selector
{ {
/** /**
* @brief Test on one position. * @brief Test on one __position.
* @param i1 Iterator on first sequence. * @param __i1 _Iterator on first sequence.
* @param i2 Iterator on second sequence (unused). * @param __i2 _Iterator on second sequence (unused).
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
bool bool
operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred) operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{ return !pred(*i1, *i2); } { return !__pred(*__i1, *__i2); }
/** /**
* @brief Corresponding sequential algorithm on a sequence. * @brief Corresponding sequential algorithm on a sequence.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param pred Find predicate. * @param __pred Find predicate.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
sequential_algorithm(RandomAccessIterator1 begin1, _M_sequential_algorithm(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred) _RAIter2 __begin2, _Pred __pred)
{ return mismatch(begin1, end1, begin2, pred, sequential_tag()); } { return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag()); }
}; };
/** @brief Test predicate on several elements. */ /** @brief Test predicate on several __elements. */
template<typename ForwardIterator> template<typename _ForwardIterator>
struct find_first_of_selector : public generic_find_selector struct __find_first_of_selector : public __generic_find_selector
{ {
ForwardIterator begin; _ForwardIterator __begin;
ForwardIterator end; _ForwardIterator __end;
explicit find_first_of_selector(ForwardIterator begin, ForwardIterator end) explicit __find_first_of_selector(_ForwardIterator __begin, _ForwardIterator __end)
: begin(begin), end(end) { } : __begin(__begin), __end(__end) { }
/** @brief Test on one position. /** @brief Test on one __position.
* @param i1 Iterator on first sequence. * @param __i1 _Iterator on first sequence.
* @param i2 Iterator on second sequence (unused). * @param __i2 _Iterator on second sequence (unused).
* @param pred Find predicate. */ * @param __pred Find predicate. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
bool bool
operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred) operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{ {
for (ForwardIterator pos_in_candidates = begin; for (_ForwardIterator __pos_in_candidates = __begin;
pos_in_candidates != end; ++pos_in_candidates) __pos_in_candidates != __end; ++__pos_in_candidates)
if (pred(*i1, *pos_in_candidates)) if (__pred(*__i1, *__pos_in_candidates))
return true; return true;
return false; return false;
} }
/** @brief Corresponding sequential algorithm on a sequence. /** @brief Corresponding sequential algorithm on a sequence.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param pred Find predicate. */ * @param __pred Find predicate. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename Pred> typename _Pred>
std::pair<RandomAccessIterator1, RandomAccessIterator2> std::pair<_RAIter1, _RAIter2>
sequential_algorithm(RandomAccessIterator1 begin1, _M_sequential_algorithm(_RAIter1 __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2 begin2, Pred pred) _RAIter2 __begin2, _Pred __pred)
{ return std::make_pair(find_first_of(begin1, end1, begin, end, pred, { return std::make_pair(find_first_of(__begin1, __end1, __begin, __end, __pred,
sequential_tag()), begin2); } sequential_tag()), __begin2); }
}; };
} }
......
...@@ -42,55 +42,55 @@ ...@@ -42,55 +42,55 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Chose the desired algorithm by evaluating @c parallelism_tag. /** @brief Chose the desired algorithm by evaluating @__c __parallelism_tag.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param user_op A user-specified functor (comparator, predicate, * @param __user_op A user-specified functor (comparator, predicate,
* associative operator,...) * associative operator,...)
* @param functionality functor to "process" an element with * @param __functionality functor to "process" an element with
* user_op (depends on desired functionality, e. g. accumulate, * __user_op (depends on desired functionality, e. g. accumulate,
* for_each,... * for_each,...
* @param reduction Reduction functor. * @param __reduction Reduction functor.
* @param reduction_start Initial value for reduction. * @param __reduction_start Initial value for reduction.
* @param output Output iterator. * @param __output Output iterator.
* @param bound Maximum number of elements processed. * @param __bound Maximum number of elements processed.
* @param parallelism_tag Parallelization method */ * @param __parallelism_tag Parallelization method */
template<typename InputIterator, typename UserOp, template<typename _IIter, typename _UserOp,
typename Functionality, typename Red, typename Result> typename _Functionality, typename _Red, typename _Result>
UserOp _UserOp
for_each_template_random_access(InputIterator begin, InputIterator end, __for_each_template_random_access(_IIter __begin, _IIter __end,
UserOp user_op, _UserOp __user_op,
Functionality& functionality, _Functionality& __functionality,
Red reduction, Result reduction_start, _Red __reduction, _Result __reduction_start,
Result& output, typename _Result& __output, typename
std::iterator_traits<InputIterator>:: std::iterator_traits<_IIter>::
difference_type bound, difference_type __bound,
_Parallelism parallelism_tag) _Parallelism __parallelism_tag)
{ {
if (parallelism_tag == parallel_unbalanced) if (__parallelism_tag == parallel_unbalanced)
return for_each_template_random_access_ed(begin, end, user_op, return for_each_template_random_access_ed(__begin, __end, __user_op,
functionality, reduction, __functionality, __reduction,
reduction_start, __reduction_start,
output, bound); __output, __bound);
else if (parallelism_tag == parallel_omp_loop) else if (__parallelism_tag == parallel_omp_loop)
return for_each_template_random_access_omp_loop(begin, end, user_op, return for_each_template_random_access_omp_loop(__begin, __end, __user_op,
functionality, __functionality,
reduction, __reduction,
reduction_start, __reduction_start,
output, bound); __output, __bound);
else if (parallelism_tag == parallel_omp_loop_static) else if (__parallelism_tag == parallel_omp_loop_static)
return for_each_template_random_access_omp_loop(begin, end, user_op, return for_each_template_random_access_omp_loop(__begin, __end, __user_op,
functionality, __functionality,
reduction, __reduction,
reduction_start, __reduction_start,
output, bound); __output, __bound);
else //e. g. parallel_balanced else //e. g. parallel_balanced
return for_each_template_random_access_workstealing(begin, end, return for_each_template_random_access_workstealing(__begin, __end,
user_op, __user_op,
functionality, __functionality,
reduction, __reduction,
reduction_start, __reduction_start,
output, bound); __output, __bound);
} }
} }
......
...@@ -38,192 +38,192 @@ ...@@ -38,192 +38,192 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Generic selector for embarrassingly parallel functions. */ /** @brief Generic __selector for embarrassingly parallel functions. */
template<typename It> template<typename _It>
struct generic_for_each_selector struct __generic_for_each_selector
{ {
/** @brief Iterator on last element processed; needed for some /** @brief _Iterator on last element processed; needed for some
* algorithms (e. g. std::transform()). * algorithms (e. g. std::transform()).
*/ */
It finish_iterator; _It finish_iterator;
}; };
/** @brief std::for_each() selector. */ /** @brief std::for_each() selector. */
template<typename It> template<typename _It>
struct for_each_selector : public generic_for_each_selector<It> struct __for_each_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename Op> template<typename _Op>
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
o(*i); __o(*__i);
return true; return true;
} }
}; };
/** @brief std::generate() selector. */ /** @brief std::generate() selector. */
template<typename It> template<typename _It>
struct generate_selector : public generic_for_each_selector<It> struct __generate_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename Op> template<typename _Op>
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
*i = o(); *__i = __o();
return true; return true;
} }
}; };
/** @brief std::fill() selector. */ /** @brief std::fill() selector. */
template<typename It> template<typename _It>
struct fill_selector : public generic_for_each_selector<It> struct __fill_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param v Current value. * @param __v Current value.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename Val> template<typename Val>
bool bool
operator()(Val& v, It i) operator()(Val& __v, _It __i)
{ {
*i = v; *__i = __v;
return true; return true;
} }
}; };
/** @brief std::transform() selector, one input sequence variant. */ /** @brief std::transform() __selector, one input sequence variant. */
template<typename It> template<typename _It>
struct transform1_selector : public generic_for_each_selector<It> struct __transform1_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename Op> template<typename _Op>
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
*i.second = o(*i.first); *__i.second = __o(*__i.first);
return true; return true;
} }
}; };
/** @brief std::transform() selector, two input sequences variant. */ /** @brief std::transform() __selector, two input sequences variant. */
template<typename It> template<typename _It>
struct transform2_selector : public generic_for_each_selector<It> struct __transform2_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename Op> template<typename _Op>
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
*i.third = o(*i.first, *i.second); *__i.__third = __o(*__i.__first, *__i.__second);
return true; return true;
} }
}; };
/** @brief std::replace() selector. */ /** @brief std::replace() selector. */
template<typename It, typename T> template<typename _It, typename _Tp>
struct replace_selector : public generic_for_each_selector<It> struct __replace_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Value to replace with. */ /** @brief Value to replace with. */
const T& new_val; const _Tp& __new_val;
/** @brief Constructor /** @brief Constructor
* @param new_val Value to replace with. */ * @param __new_val Value to replace with. */
explicit explicit
replace_selector(const T &new_val) : new_val(new_val) {} __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {}
/** @brief Functor execution. /** @brief Functor execution.
* @param v Current value. * @param __v Current value.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
bool bool
operator()(T& v, It i) operator()(_Tp& __v, _It __i)
{ {
if (*i == v) if (*__i == __v)
*i = new_val; *__i = __new_val;
return true; return true;
} }
}; };
/** @brief std::replace() selector. */ /** @brief std::replace() selector. */
template<typename It, typename Op, typename T> template<typename _It, typename _Op, typename _Tp>
struct replace_if_selector : public generic_for_each_selector<It> struct __replace_if_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Value to replace with. */ /** @brief Value to replace with. */
const T& new_val; const _Tp& __new_val;
/** @brief Constructor. /** @brief Constructor.
* @param new_val Value to replace with. */ * @param __new_val Value to replace with. */
explicit explicit
replace_if_selector(const T &new_val) : new_val(new_val) { } __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { }
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
if (o(*i)) if (__o(*__i))
*i = new_val; *__i = __new_val;
return true; return true;
} }
}; };
/** @brief std::count() selector. */ /** @brief std::count() selector. */
template<typename It, typename Diff> template<typename _It, typename _Diff>
struct count_selector : public generic_for_each_selector<It> struct __count_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param v Current value. * @param __v Current value.
* @param i Iterator referencing object. * @param __i iterator referencing object.
* @return 1 if count, 0 if does not count. */ * @return 1 if count, 0 if does not count. */
template<typename Val> template<typename Val>
Diff _Diff
operator()(Val& v, It i) operator()(Val& __v, _It __i)
{ return (v == *i) ? 1 : 0; } { return (__v == *__i) ? 1 : 0; }
}; };
/** @brief std::count_if () selector. */ /** @brief std::count_if () selector. */
template<typename It, typename Diff> template<typename _It, typename _Diff>
struct count_if_selector : public generic_for_each_selector<It> struct __count_if_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator. * @param __o Operator.
* @param i Iterator referencing object. * @param __i iterator referencing object.
* @return 1 if count, 0 if does not count. */ * @return 1 if count, 0 if does not count. */
template<typename Op> template<typename _Op>
Diff _Diff
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ return (o(*i)) ? 1 : 0; } { return (__o(*__i)) ? 1 : 0; }
}; };
/** @brief std::accumulate() selector. */ /** @brief std::accumulate() selector. */
template<typename It> template<typename _It>
struct accumulate_selector : public generic_for_each_selector<It> struct __accumulate_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator (unused). * @param __o Operator (unused).
* @param i Iterator referencing object. * @param __i iterator referencing object.
* @return The current value. */ * @return The current value. */
template<typename Op> template<typename _Op>
typename std::iterator_traits<It>::value_type operator()(Op o, It i) typename std::iterator_traits<_It>::value_type operator()(_Op __o, _It __i)
{ return *i; } { return *__i; }
}; };
/** @brief std::inner_product() selector. */ /** @brief std::inner_product() selector. */
template<typename It, typename It2, typename T> template<typename _It, typename It2, typename _Tp>
struct inner_product_selector : public generic_for_each_selector<It> struct __inner_product_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Begin iterator of first sequence. */ /** @brief Begin iterator of first sequence. */
It begin1_iterator; _It __begin1_iterator;
/** @brief Begin iterator of second sequence. */ /** @brief Begin iterator of second sequence. */
It2 begin2_iterator; It2 begin2_iterator;
...@@ -232,50 +232,50 @@ namespace __gnu_parallel ...@@ -232,50 +232,50 @@ namespace __gnu_parallel
* @param b1 Begin iterator of first sequence. * @param b1 Begin iterator of first sequence.
* @param b2 Begin iterator of second sequence. */ * @param b2 Begin iterator of second sequence. */
explicit explicit
inner_product_selector(It b1, It2 b2) __inner_product_selector(_It b1, It2 b2)
: begin1_iterator(b1), begin2_iterator(b2) { } : __begin1_iterator(b1), begin2_iterator(b2) { }
/** @brief Functor execution. /** @brief Functor execution.
* @param mult Multiplication functor. * @param __mult Multiplication functor.
* @param current Iterator referencing object. * @param __current iterator referencing object.
* @return Inner product elemental result. */ * @return Inner product elemental __result. */
template<typename Op> template<typename _Op>
T _Tp
operator()(Op mult, It current) operator()(_Op __mult, _It __current)
{ {
typename std::iterator_traits<It>::difference_type position typename std::iterator_traits<_It>::difference_type __position
= current - begin1_iterator; = __current - __begin1_iterator;
return mult(*current, *(begin2_iterator + position)); return __mult(*__current, *(begin2_iterator + __position));
} }
}; };
/** @brief Selector that just returns the passed iterator. */ /** @brief Selector that just returns the passed iterator. */
template<typename It> template<typename _It>
struct identity_selector : public generic_for_each_selector<It> struct __identity_selector : public __generic_for_each_selector<_It>
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param o Operator (unused). * @param __o Operator (unused).
* @param i Iterator referencing object. * @param __i iterator referencing object.
* @return Passed iterator. */ * @return Passed iterator. */
template<typename Op> template<typename _Op>
It _It
operator()(Op o, It i) operator()(_Op __o, _It __i)
{ return i; } { return __i; }
}; };
/** @brief Selector that returns the difference between two adjacent /** @brief Selector that returns the difference between two adjacent
* elements. * __elements.
*/ */
template<typename It> template<typename _It>
struct adjacent_difference_selector : public generic_for_each_selector<It> struct __adjacent_difference_selector : public __generic_for_each_selector<_It>
{ {
template<typename Op> template<typename _Op>
bool bool
operator()(Op& o, It i) operator()(_Op& __o, _It __i)
{ {
typename It::first_type go_back_one = i.first; typename _It::first_type __go_back_one = __i.first;
--go_back_one; --__go_back_one;
*i.second = o(*i.first, *go_back_one); *__i.__second = __o(*__i.__first, *__go_back_one);
return true; return true;
} }
}; };
...@@ -283,77 +283,77 @@ namespace __gnu_parallel ...@@ -283,77 +283,77 @@ namespace __gnu_parallel
// XXX move into type_traits? // XXX move into type_traits?
/** @brief Functor doing nothing /** @brief Functor doing nothing
* *
* For some reduction tasks (this is not a function object, but is * For some __reduction tasks (this is not a function object, but is
* passed as selector dummy parameter. * passed as __selector __dummy parameter.
*/ */
struct nothing struct _Nothing
{ {
/** @brief Functor execution. /** @brief Functor execution.
* @param i Iterator referencing object. */ * @param __i iterator referencing object. */
template<typename It> template<typename _It>
void void
operator()(It i) { } operator()(_It __i) { }
}; };
/** @brief Reduction function doing nothing. */ /** @brief Reduction function doing nothing. */
struct dummy_reduct struct _DummyReduct
{ {
bool bool
operator()(bool /*x*/, bool /*y*/) const operator()(bool /*__x*/, bool /*__y*/) const
{ return true; } { return true; }
}; };
/** @brief Reduction for finding the maximum element, using a comparator. */ /** @brief Reduction for finding the maximum element, using a comparator. */
template<typename Comp, typename It> template<typename _Compare, typename _It>
struct min_element_reduct struct __min_element_reduct
{ {
Comp& comp; _Compare& __comp;
explicit explicit
min_element_reduct(Comp &c) : comp(c) { } __min_element_reduct(_Compare &__c) : __comp(__c) { }
It _It
operator()(It x, It y) operator()(_It __x, _It __y)
{ {
if (comp(*x, *y)) if (__comp(*__x, *__y))
return x; return __x;
else else
return y; return __y;
} }
}; };
/** @brief Reduction for finding the maximum element, using a comparator. */ /** @brief Reduction for finding the maximum element, using a comparator. */
template<typename Comp, typename It> template<typename _Compare, typename _It>
struct max_element_reduct struct __max_element_reduct
{ {
Comp& comp; _Compare& __comp;
explicit explicit
max_element_reduct(Comp& c) : comp(c) { } __max_element_reduct(_Compare& __c) : __comp(__c) { }
It _It
operator()(It x, It y) operator()(_It __x, _It __y)
{ {
if (comp(*x, *y)) if (__comp(*__x, *__y))
return y; return __y;
else else
return x; return __x;
} }
}; };
/** @brief General reduction, using a binary operator. */ /** @brief General reduction, using a binary operator. */
template<typename BinOp> template<typename _BinOp>
struct accumulate_binop_reduct struct __accumulate_binop_reduct
{ {
BinOp& binop; _BinOp& __binop;
explicit explicit
accumulate_binop_reduct(BinOp& b) : binop(b) { } __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
template<typename Result, typename Addend> template<typename _Result, typename _Addend>
Result _Result
operator()(const Result& x, const Addend& y) operator()(const _Result& __x, const _Addend& __y)
{ return binop(x, y); } { return __binop(__x, __y); }
}; };
} }
......
...@@ -40,160 +40,160 @@ namespace __gnu_parallel ...@@ -40,160 +40,160 @@ namespace __gnu_parallel
/** @brief A pair of iterators. The usual iterator operations are /** @brief A pair of iterators. The usual iterator operations are
* applied to both child iterators. * applied to both child iterators.
*/ */
template<typename Iterator1, typename Iterator2, typename IteratorCategory> template<typename _Iterator1, typename _Iterator2, typename _IteratorCategory>
class iterator_pair : public std::pair<Iterator1, Iterator2> class _IteratorPair : public std::pair<_Iterator1, _Iterator2>
{ {
private: private:
typedef iterator_pair<Iterator1, Iterator2, IteratorCategory> type; typedef _IteratorPair<_Iterator1, _Iterator2, _IteratorCategory> _Self;
typedef std::pair<Iterator1, Iterator2> base_type; typedef std::pair<_Iterator1, _Iterator2> _Base;
public: public:
typedef IteratorCategory iterator_category; typedef _IteratorCategory iterator_category;
typedef void value_type; typedef void value_type;
typedef std::iterator_traits<Iterator1> traits_type; typedef std::iterator_traits<_Iterator1> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type difference_type;
typedef type* pointer; typedef _Self* pointer;
typedef type& reference; typedef _Self& reference;
iterator_pair() { } _IteratorPair() { }
iterator_pair(const Iterator1& first, const Iterator2& second) _IteratorPair(const _Iterator1& __first, const _Iterator2& __second)
: base_type(first, second) { } : _Base(__first, __second) { }
// Pre-increment operator. // Pre-increment operator.
type& _Self&
operator++() operator++()
{ {
++base_type::first; ++_Base::first;
++base_type::second; ++_Base::second;
return *this; return *this;
} }
// Post-increment operator. // Post-increment operator.
const type const _Self
operator++(int) operator++(int)
{ return type(base_type::first++, base_type::second++); } { return _Self(_Base::first++, _Base::second++); }
// Pre-decrement operator. // Pre-decrement operator.
type& _Self&
operator--() operator--()
{ {
--base_type::first; --_Base::first;
--base_type::second; --_Base::second;
return *this; return *this;
} }
// Post-decrement operator. // Post-decrement operator.
const type const _Self
operator--(int) operator--(int)
{ return type(base_type::first--, base_type::second--); } { return _Self(_Base::first--, _Base::second--); }
// Type conversion. // Type conversion.
operator Iterator2() const operator _Iterator2() const
{ return base_type::second; } { return _Base::second; }
type& _Self&
operator=(const type& other) operator=(const _Self& __other)
{ {
base_type::first = other.first; _Base::first = __other.first;
base_type::second = other.second; _Base::second = __other.second;
return *this; return *this;
} }
type _Self
operator+(difference_type delta) const operator+(difference_type __delta) const
{ return type(base_type::first + delta, base_type::second + delta); } { return _Self(_Base::first + __delta, _Base::second + __delta); }
difference_type difference_type
operator-(const type& other) const operator-(const _Self& __other) const
{ return base_type::first - other.first; } { return _Base::first - __other.first; }
}; };
/** @brief A triple of iterators. The usual iterator operations are /** @brief A triple of iterators. The usual iterator operations are
applied to all three child iterators. applied to all three child iterators.
*/ */
template<typename Iterator1, typename Iterator2, typename Iterator3, template<typename _Iterator1, typename _Iterator2, typename _Iterator3,
typename IteratorCategory> typename _IteratorCategory>
class iterator_triple class _IteratorTriple
{ {
private: private:
typedef iterator_triple<Iterator1, Iterator2, Iterator3, typedef _IteratorTriple<_Iterator1, _Iterator2, _Iterator3,
IteratorCategory> type; _IteratorCategory> _Self;
public: public:
typedef IteratorCategory iterator_category; typedef _IteratorCategory iterator_category;
typedef void value_type; typedef void value_type;
typedef typename std::iterator_traits<Iterator1>::difference_type typedef typename std::iterator_traits<_Iterator1>::difference_type
difference_type; difference_type;
typedef type* pointer; typedef _Self* pointer;
typedef type& reference; typedef _Self& reference;
Iterator1 first; _Iterator1 __first;
Iterator2 second; _Iterator2 __second;
Iterator3 third; _Iterator3 __third;
iterator_triple() { } _IteratorTriple() { }
iterator_triple(const Iterator1& _first, const Iterator2& _second, _IteratorTriple(const _Iterator1& _first, const _Iterator2& _second,
const Iterator3& _third) const _Iterator3& _third)
{ {
first = _first; __first = _first;
second = _second; __second = _second;
third = _third; __third = _third;
} }
// Pre-increment operator. // Pre-increment operator.
type& _Self&
operator++() operator++()
{ {
++first; ++__first;
++second; ++__second;
++third; ++__third;
return *this; return *this;
} }
// Post-increment operator. // Post-increment operator.
const type const _Self
operator++(int) operator++(int)
{ return type(first++, second++, third++); } { return _Self(__first++, __second++, __third++); }
// Pre-decrement operator. // Pre-decrement operator.
type& _Self&
operator--() operator--()
{ {
--first; --__first;
--second; --__second;
--third; --__third;
return *this; return *this;
} }
// Post-decrement operator. // Post-decrement operator.
const type const _Self
operator--(int) operator--(int)
{ return type(first--, second--, third--); } { return _Self(__first--, __second--, __third--); }
// Type conversion. // Type conversion.
operator Iterator3() const operator _Iterator3() const
{ return third; } { return __third; }
type& _Self&
operator=(const type& other) operator=(const _Self& __other)
{ {
first = other.first; __first = __other.__first;
second = other.second; __second = __other.__second;
third = other.third; __third = __other.__third;
return *this; return *this;
} }
type _Self
operator+(difference_type delta) const operator+(difference_type __delta) const
{ return type(first + delta, second + delta, third + delta); } { return _Self(__first + __delta, __second + __delta, __third + __delta); }
difference_type difference_type
operator-(const type& other) const operator-(const _Self& __other) const
{ return first - other.first; } { return __first - __other.__first; }
}; };
} }
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms // software; you can redistribute __it and/or modify __it under the terms
// of the GNU General Public License as published by the Free Software // of the GNU General Public License as published by the Free Software
// Foundation; either version 3, or (at your option) any later // Foundation; either version 3, or (at your option) any later
// version. // version.
// This library is distributed in the hope that it will be useful, but // This library is distributed in the hope that __it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details. // General Public License for more details.
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/list_partition.h /** @file parallel/list_partition.h
* @brief Functionality to split sequence referenced by only input * @brief _Functionality to split __sequence referenced by only input
* iterators. * iterators.
* This file is a GNU parallel extension to the Standard C++ Library. * This file is a GNU parallel extension to the Standard C++ Library.
*/ */
...@@ -39,137 +39,137 @@ ...@@ -39,137 +39,137 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Shrinks and doubles the ranges. /** @brief Shrinks and doubles the ranges.
* @param os_starts Start positions worked on (oversampled). * @param __os_starts Start positions worked on (oversampled).
* @param count_to_two Counts up to 2. * @param __count_to_two Counts up to 2.
* @param range_length Current length of a chunk. * @param __range_length Current length of a chunk.
* @param make_twice Whether the @c os_starts is allowed to be * @param __make_twice Whether the @__c __os_starts is allowed to be
* grown or not * grown or not
*/ */
template<typename InputIterator> template<typename _IIter>
void void
shrink_and_double(std::vector<InputIterator>& os_starts, __shrink_and_double(std::vector<_IIter>& __os_starts,
size_t& count_to_two, size_t& range_length, size_t& __count_to_two, size_t& __range_length,
const bool make_twice) const bool __make_twice)
{ {
++count_to_two; ++__count_to_two;
if (not make_twice or count_to_two < 2) if (not __make_twice or __count_to_two < 2)
shrink(os_starts, count_to_two, range_length); __shrink(__os_starts, __count_to_two, __range_length);
else else
{ {
os_starts.resize((os_starts.size() - 1) * 2 + 1); __os_starts.resize((__os_starts.size() - 1) * 2 + 1);
count_to_two = 0; __count_to_two = 0;
} }
} }
/** @brief Combines two ranges into one and thus halves the number of ranges. /** @brief Combines two ranges into one and thus halves the number of ranges.
* @param os_starts Start positions worked on (oversampled). * @param __os_starts Start positions worked on (oversampled).
* @param count_to_two Counts up to 2. * @param __count_to_two Counts up to 2.
* @param range_length Current length of a chunk. */ * @param __range_length Current length of a chunk. */
template<typename InputIterator> template<typename _IIter>
void void
shrink(std::vector<InputIterator>& os_starts, size_t& count_to_two, __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two,
size_t& range_length) size_t& __range_length)
{ {
for (typename std::vector<InputIterator>::size_type i = 0; for (typename std::vector<_IIter>::size_type __i = 0;
i <= (os_starts.size() / 2); ++i) __i <= (__os_starts.size() / 2); ++__i)
os_starts[i] = os_starts[i * 2]; __os_starts[__i] = __os_starts[__i * 2];
range_length *= 2; __range_length *= 2;
} }
/** @brief Splits a sequence given by input iterators into parts of /** @brief Splits a sequence given by input iterators into parts of
* almost equal size * almost equal size
* *
* The function needs only one pass over the sequence. * The function needs only one pass over the sequence.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param starts Start iterators for the resulting parts, dimension * @param __starts Start iterators for the resulting parts, dimension
* @c num_parts+1. For convenience, @c starts @c [num_parts] * @__c __num_parts+1. For convenience, @__c __starts @__c [__num_parts]
* contains the end iterator of the sequence. * contains the end iterator of the sequence.
* @param lengths Length of the resulting parts. * @param __lengths Length of the resulting parts.
* @param num_parts Number of parts to split the sequence into. * @param __num_parts Number of parts to split the sequence into.
* @param f Functor to be applied to each element by traversing it * @param __f Functor to be applied to each element by traversing __it
* @param oversampling Oversampling factor. If 0, then the * @param __oversampling Oversampling factor. If 0, then the
* partitions will differ in at most @f$ \sqrt{\mathrm{end} - * partitions will differ in at most @__f$ \sqrt{\mathrm{__end} -
* \mathrm{begin}} @f$ elements. Otherwise, the ratio between the * \mathrm{__begin}} @__f$ __elements. Otherwise, the ratio between the
* longest and the shortest part is bounded by @f$ * longest and the shortest part is bounded by @__f$
* 1/(\mathrm{oversampling} \cdot \mathrm{num\_parts}) @f$. * 1/(\mathrm{__oversampling} \cdot \mathrm{num\_parts}) @__f$.
* @return Length of the whole sequence. * @return Length of the whole sequence.
*/ */
template<typename InputIterator, typename FunctorType> template<typename _IIter, typename _FunctorType>
size_t size_t
list_partition(const InputIterator begin, const InputIterator end, list_partition(const _IIter __begin, const _IIter __end,
InputIterator* starts, size_t* lengths, const int num_parts, _IIter* __starts, size_t* __lengths, const int __num_parts,
FunctorType& f, int oversampling = 0) _FunctorType& __f, int __oversampling = 0)
{ {
bool make_twice = false; bool __make_twice = false;
// The resizing algorithm is chosen according to the oversampling factor. // The resizing algorithm is chosen according to the oversampling factor.
if (oversampling == 0) if (__oversampling == 0)
{ {
make_twice = true; __make_twice = true;
oversampling = 1; __oversampling = 1;
} }
std::vector<InputIterator> os_starts(2 * oversampling * num_parts + 1); std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1);
os_starts[0]= begin; __os_starts[0]= __begin;
InputIterator prev = begin, it = begin; _IIter __prev = __begin, __it = __begin;
size_t dist_limit = 0, dist = 0; size_t __dist_limit = 0, __dist = 0;
size_t cur = 1, next = 1; size_t __cur = 1, __next = 1;
size_t range_length = 1; size_t __range_length = 1;
size_t count_to_two = 0; size_t __count_to_two = 0;
while (it != end) while (__it != __end)
{ {
cur = next; __cur = __next;
for (; cur < os_starts.size() and it != end; ++cur) for (; __cur < __os_starts.size() and __it != __end; ++__cur)
{ {
for (dist_limit += range_length; for (__dist_limit += __range_length;
dist < dist_limit and it != end; ++dist) __dist < __dist_limit and __it != __end; ++__dist)
{ {
f(it); __f(__it);
++it; ++__it;
} }
os_starts[cur] = it; __os_starts[__cur] = __it;
} }
// Must compare for end and not cur < os_starts.size() , because // Must compare for end and not __cur < __os_starts.size() , because
// cur could be == os_starts.size() as well // __cur could be == __os_starts.size() as well
if (it == end) if (__it == __end)
break; break;
shrink_and_double(os_starts, count_to_two, range_length, make_twice); __shrink_and_double(__os_starts, __count_to_two, __range_length, __make_twice);
next = os_starts.size() / 2 + 1; __next = __os_starts.size() / 2 + 1;
} }
// Calculation of the parts (one must be extracted from current // Calculation of the parts (one must be extracted from __current
// because the partition beginning at end, consists only of // because the partition beginning at __end, consists only of
// itself). // itself).
size_t size_part = (cur - 1) / num_parts; size_t __size_part = (__cur - 1) / __num_parts;
int size_greater = static_cast<int>((cur - 1) % num_parts); int __size_greater = static_cast<int>((__cur - 1) % __num_parts);
starts[0] = os_starts[0]; __starts[0] = __os_starts[0];
size_t index = 0; size_t __index = 0;
// Smallest partitions. // Smallest partitions.
for (int i = 1; i < (num_parts + 1 - size_greater); ++i) for (int __i = 1; __i < (__num_parts + 1 - __size_greater); ++__i)
{ {
lengths[i - 1] = size_part * range_length; __lengths[__i - 1] = __size_part * __range_length;
index += size_part; __index += __size_part;
starts[i] = os_starts[index]; __starts[__i] = __os_starts[__index];
} }
// Biggest partitions. // Biggest partitions.
for (int i = num_parts + 1 - size_greater; i <= num_parts; ++i) for (int __i = __num_parts + 1 - __size_greater; __i <= __num_parts; ++__i)
{ {
lengths[i - 1] = (size_part+1) * range_length; __lengths[__i - 1] = (__size_part+1) * __range_length;
index += (size_part+1); __index += (__size_part+1);
starts[i] = os_starts[index]; __starts[__i] = __os_starts[__index];
} }
// Correction of the end size (the end iteration has not finished). // Correction of the end size (the end iteration has not finished).
lengths[num_parts - 1] -= (dist_limit - dist); __lengths[__num_parts - 1] -= (__dist_limit - __dist);
return dist; return __dist;
} }
} }
......
...@@ -46,45 +46,45 @@ namespace __gnu_parallel ...@@ -46,45 +46,45 @@ namespace __gnu_parallel
* *
* The smallest element is at the top. * The smallest element is at the top.
* *
* Guarding is done explicitly through one flag sup per element, * Guarding is done explicitly through one flag _M_sup per element,
* inf is not needed due to a better initialization routine. This * inf is not needed due to a better initialization routine. This
* is a well-performing variant. * is a well-performing variant.
* *
* @param T the element type * @param _Tp the element _Self
* @param Comparator the comparator to use, defaults to std::less<T> * @param _Compare the comparator to use, defaults to std::less<_Tp>
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreeBase class LoserTreeBase
{ {
protected: protected:
/** @brief Internal representation of a LoserTree element. */ /** @brief Internal representation of a LoserTree element. */
struct Loser struct _Loser
{ {
/** @brief flag, true iff this is a "maximum" sentinel. */ /** @brief flag, true iff this is a "maximum" __sentinel. */
bool sup; bool _M_sup;
/** @brief index of the source sequence. */ /** @brief __index of the _M_source __sequence. */
int source; int _M_source;
/** @brief key of the element in the LoserTree. */ /** @brief _M_key of the element in the LoserTree. */
T key; _Tp _M_key;
}; };
unsigned int ik, k, offset; unsigned int __ik, __k, __offset;
/** log_2{k} */ /** log_2{__k} */
unsigned int _M_log_k; unsigned int _M_log_k;
/** @brief LoserTree elements. */ /** @brief LoserTree __elements. */
Loser* losers; _Loser* __losers;
/** @brief Comparator to use. */ /** @brief _Compare to use. */
Comparator comp; _Compare __comp;
/** /**
* @brief State flag that determines whether the LoserTree is empty. * @brief State flag that determines whether the LoserTree is empty.
* *
* Only used for building the LoserTree. * Only used for building the LoserTree.
*/ */
bool first_insert; bool __first_insert;
public: public:
/** /**
...@@ -93,117 +93,117 @@ public: ...@@ -93,117 +93,117 @@ public:
* @param _k The number of sequences to merge. * @param _k The number of sequences to merge.
* @param _comp The comparator to use. * @param _comp The comparator to use.
*/ */
LoserTreeBase(unsigned int _k, Comparator _comp) LoserTreeBase(unsigned int _k, _Compare _comp)
: comp(_comp) : __comp(_comp)
{ {
ik = _k; __ik = _k;
// Compute log_2{k} for the Loser Tree // Compute log_2{__k} for the _Loser Tree
_M_log_k = __log2(ik - 1) + 1; _M_log_k = __log2(__ik - 1) + 1;
// Next greater power of 2. // Next greater power of 2.
k = 1 << _M_log_k; __k = 1 << _M_log_k;
offset = k; __offset = __k;
// Avoid default-constructing losers[].key // Avoid default-constructing __losers[]._M_key
losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser))); __losers = static_cast<_Loser*>(::operator new(2 * __k * sizeof(_Loser)));
for (unsigned int i = ik - 1; i < k; ++i) for (unsigned int __i = __ik - 1; __i < __k; ++__i)
losers[i + k].sup = true; __losers[__i + __k]._M_sup = true;
first_insert = true; __first_insert = true;
} }
/** /**
* @brief The destructor. * @brief The destructor.
*/ */
~LoserTreeBase() ~LoserTreeBase()
{ ::operator delete(losers); } { ::operator delete(__losers); }
/** /**
* @brief Initializes the sequence "source" with the element "key". * @brief Initializes the sequence "_M_source" with the element "_M_key".
* *
* @param key the element to insert * @param _M_key the element to insert
* @param source index of the source sequence * @param _M_source __index of the _M_source __sequence
* @param sup flag that determines whether the value to insert is an * @param _M_sup flag that determines whether the value to insert is an
* explicit supremum. * explicit __supremum.
*/ */
inline void inline void
insert_start(const T& key, int source, bool sup) __insert_start(const _Tp& _M_key, int _M_source, bool _M_sup)
{ {
unsigned int pos = k + source; unsigned int __pos = __k + _M_source;
if(first_insert) if(__first_insert)
{ {
// Construct all keys, so we can easily deconstruct them. // Construct all keys, so we can easily deconstruct them.
for (unsigned int i = 0; i < (2 * k); ++i) for (unsigned int __i = 0; __i < (2 * __k); ++__i)
new(&(losers[i].key)) T(key); new(&(__losers[__i]._M_key)) _Tp(_M_key);
first_insert = false; __first_insert = false;
} }
else else
new(&(losers[pos].key)) T(key); new(&(__losers[__pos]._M_key)) _Tp(_M_key);
losers[pos].sup = sup; __losers[__pos]._M_sup = _M_sup;
losers[pos].source = source; __losers[__pos]._M_source = _M_source;
} }
/** /**
* @return the index of the sequence with the smallest element. * @return the index of the sequence with the smallest element.
*/ */
int get_min_source() int __get_min_source()
{ return losers[0].source; } { return __losers[0]._M_source; }
}; };
/** /**
* @brief Stable LoserTree variant. * @brief Stable LoserTree variant.
* *
* Provides the stable implementations of insert_start, init_winner, * Provides the stable implementations of insert_start, __init_winner,
* init and delete_min_insert. * __init and __delete_min_insert.
* *
* Unstable variant is done using partial specialisation below. * Unstable variant is done using partial specialisation below.
*/ */
template<bool stable/* default == true */, typename T, typename Comparator> template<bool __stable/* default == true */, typename _Tp, typename _Compare>
class LoserTree : public LoserTreeBase<T, Comparator> class LoserTree : public LoserTreeBase<_Tp, _Compare>
{ {
typedef LoserTreeBase<T, Comparator> Base; typedef LoserTreeBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
using Base::first_insert; using Base::__first_insert;
public: public:
LoserTree(unsigned int _k, Comparator _comp) LoserTree(unsigned int _k, _Compare _comp)
: Base::LoserTreeBase(_k, _comp) : Base::LoserTreeBase(_k, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (losers[right].sup if (__losers[__right]._M_sup
|| (!losers[left].sup || (!__losers[__left]._M_sup
&& !comp(losers[right].key, losers[left].key))) && !__comp(__losers[__right]._M_key, __losers[__left]._M_key)))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
void init() void __init()
{ losers[0] = losers[init_winner(1)]; } { __losers[0] = __losers[__init_winner(1)]; }
/** /**
* @brief Delete the smallest element and insert a new element from * @brief Delete the smallest element and insert a new element from
...@@ -211,34 +211,34 @@ public: ...@@ -211,34 +211,34 @@ public:
* *
* This implementation is stable. * This implementation is stable.
*/ */
// Do not pass a const reference since key will be used as local variable. // Do not pass a const reference since _M_key will be used as local variable.
void delete_min_insert(T key, bool sup) void __delete_min_insert(_Tp _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted, ties are broken by source. // The smaller one gets promoted, ties are broken by _M_source.
if ((sup && (!losers[pos].sup || losers[pos].source < source)) if ((_M_sup && (!__losers[__pos]._M_sup || __losers[__pos]._M_source < _M_source))
|| (!sup && !losers[pos].sup || (!_M_sup && !__losers[__pos]._M_sup
&& ((comp(losers[pos].key, key)) && ((__comp(__losers[__pos]._M_key, _M_key))
|| (!comp(key, losers[pos].key) || (!__comp(_M_key, __losers[__pos]._M_key)
&& losers[pos].source < source)))) && __losers[__pos]._M_source < _M_source))))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].sup, sup); std::swap(__losers[__pos]._M_sup, _M_sup);
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].key, key); std::swap(__losers[__pos]._M_key, _M_key);
} }
} }
losers[0].sup = sup; __losers[0]._M_sup = _M_sup;
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].key = key; __losers[0]._M_key = _M_key;
} }
}; };
...@@ -247,141 +247,141 @@ public: ...@@ -247,141 +247,141 @@ public:
* *
* Stability (non-stable here) is selected with partial specialization. * Stability (non-stable here) is selected with partial specialization.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTree</* stable == */false, T, Comparator> : class LoserTree</* __stable == */false, _Tp, _Compare> :
public LoserTreeBase<T, Comparator> public LoserTreeBase<_Tp, _Compare>
{ {
typedef LoserTreeBase<T, Comparator> Base; typedef LoserTreeBase<_Tp, _Compare> Base;
using Base::_M_log_k; using Base::_M_log_k;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
using Base::first_insert; using Base::__first_insert;
public: public:
LoserTree(unsigned int _k, Comparator _comp) LoserTree(unsigned int _k, _Compare _comp)
: Base::LoserTreeBase(_k, _comp) : Base::LoserTreeBase(_k, _comp)
{} {}
/** /**
* Computes the winner of the competition at position "root". * Computes the winner of the competition at __position "__root".
* *
* Called recursively (starting at 0) to build the initial tree. * Called recursively (starting at 0) to build the initial tree.
* *
* @param root index of the "game" to start. * @param __root __index of the "game" to start.
*/ */
unsigned int unsigned int
init_winner (unsigned int root) __init_winner (unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (losers[right].sup || if (__losers[__right]._M_sup ||
(!losers[left].sup (!__losers[__left]._M_sup
&& !comp(losers[right].key, losers[left].key))) && !__comp(__losers[__right]._M_key, __losers[__left]._M_key)))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
inline void inline void
init() __init()
{ losers[0] = losers[init_winner(1)]; } { __losers[0] = __losers[__init_winner(1)]; }
/** /**
* Delete the key smallest element and insert the element key instead. * Delete the _M_key smallest element and insert the element _M_key instead.
* *
* @param key the key to insert * @param _M_key the _M_key to insert
* @param sup true iff key is an explicitly marked supremum * @param _M_sup true iff _M_key is an explicitly marked supremum
*/ */
// Do not pass a const reference since key will be used as local variable. // Do not pass a const reference since _M_key will be used as local variable.
inline void inline void
delete_min_insert(T key, bool sup) __delete_min_insert(_Tp _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted. // The smaller one gets promoted.
if (sup || (!losers[pos].sup && comp(losers[pos].key, key))) if (_M_sup || (!__losers[__pos]._M_sup && __comp(__losers[__pos]._M_key, _M_key)))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].sup, sup); std::swap(__losers[__pos]._M_sup, _M_sup);
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].key, key); std::swap(__losers[__pos]._M_key, _M_key);
} }
} }
losers[0].sup = sup; __losers[0]._M_sup = _M_sup;
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].key = key; __losers[0]._M_key = _M_key;
} }
}; };
/** /**
* @brief Base class of Loser Tree implementation using pointers. * @brief Base class of _Loser Tree implementation using pointers.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreePointerBase class _LoserTreePointerBase
{ {
protected: protected:
/** @brief Internal representation of LoserTree elements. */ /** @brief Internal representation of LoserTree __elements. */
struct Loser struct _Loser
{ {
bool sup; bool _M_sup;
int source; int _M_source;
const T* keyp; const _Tp* _M_keyp;
}; };
unsigned int ik, k, offset; unsigned int __ik, __k, __offset;
Loser* losers; _Loser* __losers;
Comparator comp; _Compare __comp;
public: public:
LoserTreePointerBase(unsigned int _k, Comparator _comp = std::less<T>()) _LoserTreePointerBase(unsigned int _k, _Compare _comp = std::less<_Tp>())
: comp(_comp) : __comp(_comp)
{ {
ik = _k; __ik = _k;
// Next greater power of 2. // Next greater power of 2.
k = 1 << (__log2(ik - 1) + 1); __k = 1 << (__log2(__ik - 1) + 1);
offset = k; __offset = __k;
losers = new Loser[k * 2]; __losers = new _Loser[__k * 2];
for (unsigned int i = ik - 1; i < k; i++) for (unsigned int __i = __ik - 1; __i < __k; __i++)
losers[i + k].sup = true; __losers[__i + __k]._M_sup = true;
} }
~LoserTreePointerBase() ~_LoserTreePointerBase()
{ ::operator delete[](losers); } { ::operator delete[](__losers); }
int get_min_source() int __get_min_source()
{ return losers[0].source; } { return __losers[0]._M_source; }
void insert_start(const T& key, int source, bool sup) void __insert_start(const _Tp& _M_key, int _M_source, bool _M_sup)
{ {
unsigned int pos = k + source; unsigned int __pos = __k + _M_source;
losers[pos].sup = sup; __losers[__pos]._M_sup = _M_sup;
losers[pos].source = source; __losers[__pos]._M_source = _M_source;
losers[pos].keyp = &key; __losers[__pos]._M_keyp = &_M_key;
} }
}; };
...@@ -390,77 +390,77 @@ public: ...@@ -390,77 +390,77 @@ public:
* *
* The unstable variant is implemented using partial instantiation below. * The unstable variant is implemented using partial instantiation below.
*/ */
template<bool stable/* default == true */, typename T, typename Comparator> template<bool __stable/* default == true */, typename _Tp, typename _Compare>
class LoserTreePointer : public LoserTreePointerBase<T, Comparator> class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare>
{ {
typedef LoserTreePointerBase<T, Comparator> Base; typedef _LoserTreePointerBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>()) _LoserTreePointer(unsigned int _k, _Compare _comp = std::less<_Tp>())
: Base::LoserTreePointerBase(_k, _comp) : Base::_LoserTreePointerBase(_k, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (losers[right].sup if (__losers[__right]._M_sup
|| (!losers[left].sup && !comp(*losers[right].keyp, || (!__losers[__left]._M_sup && !__comp(*__losers[__right]._M_keyp,
*losers[left].keyp))) *__losers[__left]._M_keyp)))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
void init() void __init()
{ losers[0] = losers[init_winner(1)]; } { __losers[0] = __losers[__init_winner(1)]; }
void delete_min_insert(const T& key, bool sup) void __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
const T* keyp = &key; const _Tp* _M_keyp = &_M_key;
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted, ties are broken by source. // The smaller one gets promoted, ties are broken by _M_source.
if ((sup && (!losers[pos].sup || losers[pos].source < source)) || if ((_M_sup && (!__losers[__pos]._M_sup || __losers[__pos]._M_source < _M_source)) ||
(!sup && !losers[pos].sup && (!_M_sup && !__losers[__pos]._M_sup &&
((comp(*losers[pos].keyp, *keyp)) || ((__comp(*__losers[__pos]._M_keyp, *_M_keyp)) ||
(!comp(*keyp, *losers[pos].keyp) (!__comp(*_M_keyp, *__losers[__pos]._M_keyp)
&& losers[pos].source < source)))) && __losers[__pos]._M_source < _M_source))))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].sup, sup); std::swap(__losers[__pos]._M_sup, _M_sup);
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].keyp, keyp); std::swap(__losers[__pos]._M_keyp, _M_keyp);
} }
} }
losers[0].sup = sup; __losers[0]._M_sup = _M_sup;
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].keyp = keyp; __losers[0]._M_keyp = _M_keyp;
} }
}; };
...@@ -469,74 +469,74 @@ public: ...@@ -469,74 +469,74 @@ public:
* *
* The stable variant is above. * The stable variant is above.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreePointer</* stable == */false, T, Comparator> : class _LoserTreePointer</* __stable == */false, _Tp, _Compare> :
public LoserTreePointerBase<T, Comparator> public _LoserTreePointerBase<_Tp, _Compare>
{ {
typedef LoserTreePointerBase<T, Comparator> Base; typedef _LoserTreePointerBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>()) _LoserTreePointer(unsigned int _k, _Compare _comp = std::less<_Tp>())
: Base::LoserTreePointerBase(_k, _comp) : Base::_LoserTreePointerBase(_k, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (losers[right].sup if (__losers[__right]._M_sup
|| (!losers[left].sup || (!__losers[__left]._M_sup
&& !comp(*losers[right].keyp, *losers[left].keyp))) && !__comp(*__losers[__right]._M_keyp, *__losers[__left]._M_keyp)))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
void init() void __init()
{ losers[0] = losers[init_winner(1)]; } { __losers[0] = __losers[__init_winner(1)]; }
void delete_min_insert(const T& key, bool sup) void __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
const T* keyp = &key; const _Tp* _M_keyp = &_M_key;
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted. // The smaller one gets promoted.
if (sup || (!losers[pos].sup && comp(*losers[pos].keyp, *keyp))) if (_M_sup || (!__losers[__pos]._M_sup && __comp(*__losers[__pos]._M_keyp, *_M_keyp)))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].sup, sup); std::swap(__losers[__pos]._M_sup, _M_sup);
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].keyp, keyp); std::swap(__losers[__pos]._M_keyp, _M_keyp);
} }
} }
losers[0].sup = sup; __losers[0]._M_sup = _M_sup;
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].keyp = keyp; __losers[0]._M_keyp = _M_keyp;
} }
}; };
...@@ -545,66 +545,66 @@ public: ...@@ -545,66 +545,66 @@ public:
* The whole element is copied into the tree structure. * The whole element is copied into the tree structure.
* *
* No guarding is done, therefore not a single input sequence must * No guarding is done, therefore not a single input sequence must
* run empty. Unused sequence heads are marked with a sentinel which * run empty. Unused __sequence heads are marked with a sentinel which
* is &gt; all elements that are to be merged. * is &gt; all elements that are to be merged.
* *
* This is a very fast variant. * This is a very fast variant.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreeUnguardedBase class _LoserTreeUnguardedBase
{ {
protected: protected:
struct Loser struct _Loser
{ {
int source; int _M_source;
T key; _Tp _M_key;
}; };
unsigned int ik, k, offset; unsigned int __ik, __k, __offset;
Loser* losers; _Loser* __losers;
Comparator comp; _Compare __comp;
public: public:
inline inline
LoserTreeUnguardedBase(unsigned int _k, const T _sentinel, _LoserTreeUnguardedBase(unsigned int _k, const _Tp _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: comp(_comp) : __comp(_comp)
{ {
ik = _k; __ik = _k;
// Next greater power of 2. // Next greater power of 2.
k = 1 << (__log2(ik - 1) + 1); __k = 1 << (__log2(__ik - 1) + 1);
offset = k; __offset = __k;
// Avoid default-constructing losers[].key // Avoid default-constructing __losers[]._M_key
losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser))); __losers = static_cast<_Loser*>(::operator new(2 * __k * sizeof(_Loser)));
for (unsigned int i = k + ik - 1; i < (2 * k); ++i) for (unsigned int __i = __k + __ik - 1; __i < (2 * __k); ++__i)
{ {
losers[i].key = _sentinel; __losers[__i]._M_key = _sentinel;
losers[i].source = -1; __losers[__i]._M_source = -1;
} }
} }
inline ~LoserTreeUnguardedBase() inline ~_LoserTreeUnguardedBase()
{ ::operator delete(losers); } { ::operator delete(__losers); }
inline int inline int
get_min_source() __get_min_source()
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
return losers[0].source; return __losers[0]._M_source;
} }
inline void inline void
insert_start(const T& key, int source, bool) __insert_start(const _Tp& _M_key, int _M_source, bool)
{ {
unsigned int pos = k + source; unsigned int __pos = __k + _M_source;
new(&(losers[pos].key)) T(key); new(&(__losers[__pos]._M_key)) _Tp(_M_key);
losers[pos].source = source; __losers[__pos]._M_source = _M_source;
} }
}; };
...@@ -613,80 +613,80 @@ public: ...@@ -613,80 +613,80 @@ public:
* *
* Unstable variant is selected below with partial specialization. * Unstable variant is selected below with partial specialization.
*/ */
template<bool stable/* default == true */, typename T, typename Comparator> template<bool __stable/* default == true */, typename _Tp, typename _Compare>
class LoserTreeUnguarded : public LoserTreeUnguardedBase<T, Comparator> class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare>
{ {
typedef LoserTreeUnguardedBase<T, Comparator> Base; typedef _LoserTreeUnguardedBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreeUnguarded(unsigned int _k, const T _sentinel, _LoserTreeUnguarded(unsigned int _k, const _Tp _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: Base::LoserTreeUnguardedBase(_k, _sentinel, _comp) : Base::_LoserTreeUnguardedBase(_k, _sentinel, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (!comp(losers[right].key, losers[left].key)) if (!__comp(__losers[__right]._M_key, __losers[__left]._M_key))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
inline void inline void
init() __init()
{ {
losers[0] = losers[init_winner(1)]; __losers[0] = __losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!) // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
} }
// Do not pass a const reference since key will be used as local variable. // Do not pass a const reference since _M_key will be used as local variable.
inline void inline void
delete_min_insert(T key, bool) __delete_min_insert(_Tp _M_key, bool)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted, ties are broken by source. // The smaller one gets promoted, ties are broken by _M_source.
if (comp(losers[pos].key, key) if (__comp(__losers[__pos]._M_key, _M_key)
|| (!comp(key, losers[pos].key) && losers[pos].source < source)) || (!__comp(_M_key, __losers[__pos]._M_key) && __losers[__pos]._M_source < _M_source))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].key, key); std::swap(__losers[__pos]._M_key, _M_key);
} }
} }
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].key = key; __losers[0]._M_key = _M_key;
} }
}; };
...@@ -695,152 +695,152 @@ public: ...@@ -695,152 +695,152 @@ public:
* *
* Stable implementation is above. * Stable implementation is above.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreeUnguarded</* stable == */false, T, Comparator> : class _LoserTreeUnguarded</* __stable == */false, _Tp, _Compare> :
public LoserTreeUnguardedBase<T, Comparator> public _LoserTreeUnguardedBase<_Tp, _Compare>
{ {
typedef LoserTreeUnguardedBase<T, Comparator> Base; typedef _LoserTreeUnguardedBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreeUnguarded(unsigned int _k, const T _sentinel, _LoserTreeUnguarded(unsigned int _k, const _Tp _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: Base::LoserTreeUnguardedBase(_k, _sentinel, _comp) : Base::_LoserTreeUnguardedBase(_k, _sentinel, _comp)
{} {}
unsigned int unsigned int
init_winner (unsigned int root) __init_winner (unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// If left one is sentinel then right one must be, too. // If __left one is sentinel then __right one must be, too.
if (losers[left].source == -1) if (__losers[__left]._M_source == -1)
_GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1); _GLIBCXX_PARALLEL_ASSERT(__losers[__right]._M_source == -1);
#endif #endif
if (!comp(losers[right].key, losers[left].key)) if (!__comp(__losers[__right]._M_key, __losers[__left]._M_key))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
inline void inline void
init() __init()
{ {
losers[0] = losers[init_winner(1)]; __losers[0] = __losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!) // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
} }
// Do not pass a const reference since key will be used as local variable. // Do not pass a const reference since _M_key will be used as local variable.
inline void inline void
delete_min_insert(T key, bool) __delete_min_insert(_Tp _M_key, bool)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted. // The smaller one gets promoted.
if (comp(losers[pos].key, key)) if (__comp(__losers[__pos]._M_key, _M_key))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].key, key); std::swap(__losers[__pos]._M_key, _M_key);
} }
} }
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].key = key; __losers[0]._M_key = _M_key;
} }
}; };
/** @brief Unguarded loser tree, keeping only pointers to the /** @brief Unguarded loser tree, keeping only pointers to the
* elements in the tree structure. * __elements in the tree structure.
* *
* No guarding is done, therefore not a single input sequence must * No guarding is done, therefore not a single input sequence must
* run empty. This is a very fast variant. * run empty. This is a very fast variant.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreePointerUnguardedBase class LoserTreePointerUnguardedBase
{ {
protected: protected:
struct Loser struct _Loser
{ {
int source; int _M_source;
const T* keyp; const _Tp* _M_keyp;
}; };
unsigned int ik, k, offset; unsigned int __ik, __k, __offset;
Loser* losers; _Loser* __losers;
Comparator comp; _Compare __comp;
public: public:
inline inline
LoserTreePointerUnguardedBase(unsigned int _k, const T& _sentinel, LoserTreePointerUnguardedBase(unsigned int _k, const _Tp& _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: comp(_comp) : __comp(_comp)
{ {
ik = _k; __ik = _k;
// Next greater power of 2. // Next greater power of 2.
k = 1 << (__log2(ik - 1) + 1); __k = 1 << (__log2(__ik - 1) + 1);
offset = k; __offset = __k;
// Avoid default-constructing losers[].key // Avoid default-constructing __losers[]._M_key
losers = new Loser[2 * k]; __losers = new _Loser[2 * __k];
for (unsigned int i = k + ik - 1; i < (2 * k); ++i) for (unsigned int __i = __k + __ik - 1; __i < (2 * __k); ++__i)
{ {
losers[i].keyp = &_sentinel; __losers[__i]._M_keyp = &_sentinel;
losers[i].source = -1; __losers[__i]._M_source = -1;
} }
} }
inline ~LoserTreePointerUnguardedBase() inline ~LoserTreePointerUnguardedBase()
{ delete[] losers; } { delete[] __losers; }
inline int inline int
get_min_source() __get_min_source()
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
return losers[0].source; return __losers[0]._M_source;
} }
inline void inline void
insert_start(const T& key, int source, bool) __insert_start(const _Tp& _M_key, int _M_source, bool)
{ {
unsigned int pos = k + source; unsigned int __pos = __k + _M_source;
losers[pos].keyp = &key; __losers[__pos]._M_keyp = &_M_key;
losers[pos].source = source; __losers[__pos]._M_source = _M_source;
} }
}; };
...@@ -849,81 +849,81 @@ public: ...@@ -849,81 +849,81 @@ public:
* *
* Unstable variant is implemented below using partial specialization. * Unstable variant is implemented below using partial specialization.
*/ */
template<bool stable/* default == true */, typename T, typename Comparator> template<bool __stable/* default == true */, typename _Tp, typename _Compare>
class LoserTreePointerUnguarded : class LoserTreePointerUnguarded :
public LoserTreePointerUnguardedBase<T, Comparator> public LoserTreePointerUnguardedBase<_Tp, _Compare>
{ {
typedef LoserTreePointerUnguardedBase<T, Comparator> Base; typedef LoserTreePointerUnguardedBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel, LoserTreePointerUnguarded(unsigned int _k, const _Tp& _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp) : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
if (!comp(*losers[right].keyp, *losers[left].keyp)) if (!__comp(*__losers[__right]._M_keyp, *__losers[__left]._M_keyp))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
inline void inline void
init() __init()
{ {
losers[0] = losers[init_winner(1)]; __losers[0] = __losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!) // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
} }
inline void inline void
delete_min_insert(const T& key, bool sup) __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
const T* keyp = &key; const _Tp* _M_keyp = &_M_key;
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted, ties are broken by source. // The smaller one gets promoted, ties are broken by _M_source.
if (comp(*losers[pos].keyp, *keyp) if (__comp(*__losers[__pos]._M_keyp, *_M_keyp)
|| (!comp(*keyp, *losers[pos].keyp) && losers[pos].source < source)) || (!__comp(*_M_keyp, *__losers[__pos]._M_keyp) && __losers[__pos]._M_source < _M_source))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].keyp, keyp); std::swap(__losers[__pos]._M_keyp, _M_keyp);
} }
} }
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].keyp = keyp; __losers[0]._M_keyp = _M_keyp;
} }
}; };
...@@ -932,87 +932,87 @@ public: ...@@ -932,87 +932,87 @@ public:
* *
* Stable variant is above. * Stable variant is above.
*/ */
template<typename T, typename Comparator> template<typename _Tp, typename _Compare>
class LoserTreePointerUnguarded</* stable == */false, T, Comparator> : class LoserTreePointerUnguarded</* __stable == */false, _Tp, _Compare> :
public LoserTreePointerUnguardedBase<T, Comparator> public LoserTreePointerUnguardedBase<_Tp, _Compare>
{ {
typedef LoserTreePointerUnguardedBase<T, Comparator> Base; typedef LoserTreePointerUnguardedBase<_Tp, _Compare> Base;
using Base::k; using Base::__k;
using Base::losers; using Base::__losers;
public: public:
LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel, LoserTreePointerUnguarded(unsigned int _k, const _Tp& _sentinel,
Comparator _comp = std::less<T>()) _Compare _comp = std::less<_Tp>())
: Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp) : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
{} {}
unsigned int unsigned int
init_winner(unsigned int root) __init_winner(unsigned int __root)
{ {
if (root >= k) if (__root >= __k)
{ {
return root; return __root;
} }
else else
{ {
unsigned int left = init_winner (2 * root); unsigned int __left = __init_winner (2 * __root);
unsigned int right = init_winner (2 * root + 1); unsigned int __right = __init_winner (2 * __root + 1);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// If left one is sentinel then right one must be, too. // If __left one is sentinel then __right one must be, too.
if (losers[left].source == -1) if (__losers[__left]._M_source == -1)
_GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1); _GLIBCXX_PARALLEL_ASSERT(__losers[__right]._M_source == -1);
#endif #endif
if (!comp(*losers[right].keyp, *losers[left].keyp)) if (!__comp(*__losers[__right]._M_keyp, *__losers[__left]._M_keyp))
{ {
// Left one is less or equal. // Left one is less or equal.
losers[root] = losers[right]; __losers[__root] = __losers[__right];
return left; return __left;
} }
else else
{ {
// Right one is less. // Right one is less.
losers[root] = losers[left]; __losers[__root] = __losers[__left];
return right; return __right;
} }
} }
} }
inline void inline void
init() __init()
{ {
losers[0] = losers[init_winner(1)]; __losers[0] = __losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!) // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
} }
inline void inline void
delete_min_insert(const T& key, bool sup) __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top! // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1); _GLIBCXX_PARALLEL_ASSERT(__losers[0]._M_source != -1);
#endif #endif
const T* keyp = &key; const _Tp* _M_keyp = &_M_key;
int source = losers[0].source; int _M_source = __losers[0]._M_source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) for (unsigned int __pos = (__k + _M_source) / 2; __pos > 0; __pos /= 2)
{ {
// The smaller one gets promoted. // The smaller one gets promoted.
if (comp(*(losers[pos].keyp), *keyp)) if (__comp(*(__losers[__pos]._M_keyp), *_M_keyp))
{ {
// The other one is smaller. // The other one is smaller.
std::swap(losers[pos].source, source); std::swap(__losers[__pos]._M_source, _M_source);
std::swap(losers[pos].keyp, keyp); std::swap(__losers[__pos]._M_keyp, _M_keyp);
} }
} }
losers[0].source = source; __losers[0]._M_source = _M_source;
losers[0].keyp = keyp; __losers[0]._M_keyp = _M_keyp;
} }
}; };
......
...@@ -37,224 +37,224 @@ ...@@ -37,224 +37,224 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Merge routine being able to merge only the @c max_length /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements. * smallest elements.
* *
* The @c begin iterators are advanced accordingly, they might not * The @__c __begin iterators are advanced accordingly, they might not
* reach @c end, in contrast to the usual variant. * reach @__c __end, in contrast to the usual variant.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param target Target begin iterator. * @param __target Target begin iterator.
* @param max_length Maximum number of elements to merge. * @param __max_length Maximum number of elements to merge.
* @param comp Comparator. * @param __comp Comparator.
* @return Output end iterator. */ * @return Output end iterator. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename OutputIterator, typename _DifferenceTp, typename _OutputIterator, typename _DifferenceTp,
typename Comparator> typename _Compare>
OutputIterator _OutputIterator
merge_advance_usual(RandomAccessIterator1& begin1, __merge_advance_usual(_RAIter1& __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2& begin2, _RAIter2& __begin2,
RandomAccessIterator2 end2, OutputIterator target, _RAIter2 __end2, _OutputIterator __target,
_DifferenceTp max_length, Comparator comp) _DifferenceTp __max_length, _Compare __comp)
{ {
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
while (begin1 != end1 && begin2 != end2 && max_length > 0) while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0)
{ {
// array1[i1] < array0[i0] // array1[__i1] < array0[i0]
if (comp(*begin2, *begin1)) if (__comp(*__begin2, *__begin1))
*target++ = *begin2++; *__target++ = *__begin2++;
else else
*target++ = *begin1++; *__target++ = *__begin1++;
--max_length; --__max_length;
} }
if (begin1 != end1) if (__begin1 != __end1)
{ {
target = std::copy(begin1, begin1 + max_length, target); __target = std::copy(__begin1, __begin1 + __max_length, __target);
begin1 += max_length; __begin1 += __max_length;
} }
else else
{ {
target = std::copy(begin2, begin2 + max_length, target); __target = std::copy(__begin2, __begin2 + __max_length, __target);
begin2 += max_length; __begin2 += __max_length;
} }
return target; return __target;
} }
/** @brief Merge routine being able to merge only the @c max_length /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements. * smallest elements.
* *
* The @c begin iterators are advanced accordingly, they might not * The @__c __begin iterators are advanced accordingly, they might not
* reach @c end, in contrast to the usual variant. * reach @__c __end, in contrast to the usual variant.
* Specially designed code should allow the compiler to generate * Specially designed code should allow the compiler to generate
* conditional moves instead of branches. * conditional moves instead of branches.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param target Target begin iterator. * @param __target Target begin iterator.
* @param max_length Maximum number of elements to merge. * @param __max_length Maximum number of elements to merge.
* @param comp Comparator. * @param __comp Comparator.
* @return Output end iterator. */ * @return Output end iterator. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename OutputIterator, typename _DifferenceTp, typename _OutputIterator, typename _DifferenceTp,
typename Comparator> typename _Compare>
OutputIterator _OutputIterator
merge_advance_movc(RandomAccessIterator1& begin1, __merge_advance_movc(_RAIter1& __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2& begin2, _RAIter2& __begin2,
RandomAccessIterator2 end2, _RAIter2 __end2,
OutputIterator target, _OutputIterator __target,
_DifferenceTp max_length, Comparator comp) _DifferenceTp __max_length, _Compare __comp)
{ {
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
typedef typename std::iterator_traits<RandomAccessIterator1>::value_type typedef typename std::iterator_traits<_RAIter1>::value_type
value_type1; value_type1;
typedef typename std::iterator_traits<RandomAccessIterator2>::value_type typedef typename std::iterator_traits<_RAIter2>::value_type
value_type2; value_type2;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(max_length >= 0); _GLIBCXX_PARALLEL_ASSERT(__max_length >= 0);
#endif #endif
while (begin1 != end1 && begin2 != end2 && max_length > 0) while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0)
{ {
RandomAccessIterator1 next1 = begin1 + 1; _RAIter1 __next1 = __begin1 + 1;
RandomAccessIterator2 next2 = begin2 + 1; _RAIter2 __next2 = __begin2 + 1;
value_type1 element1 = *begin1; value_type1 __element1 = *__begin1;
value_type2 element2 = *begin2; value_type2 __element2 = *__begin2;
if (comp(element2, element1)) if (__comp(__element2, __element1))
{ {
element1 = element2; __element1 = __element2;
begin2 = next2; __begin2 = __next2;
} }
else else
begin1 = next1; __begin1 = __next1;
*target = element1; *__target = __element1;
++target; ++__target;
--max_length; --__max_length;
} }
if (begin1 != end1) if (__begin1 != __end1)
{ {
target = std::copy(begin1, begin1 + max_length, target); __target = std::copy(__begin1, __begin1 + __max_length, __target);
begin1 += max_length; __begin1 += __max_length;
} }
else else
{ {
target = std::copy(begin2, begin2 + max_length, target); __target = std::copy(__begin2, __begin2 + __max_length, __target);
begin2 += max_length; __begin2 += __max_length;
} }
return target; return __target;
} }
/** @brief Merge routine being able to merge only the @c max_length /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements. * smallest elements.
* *
* The @c begin iterators are advanced accordingly, they might not * The @__c __begin iterators are advanced accordingly, they might not
* reach @c end, in contrast to the usual variant. * reach @__c __end, in contrast to the usual variant.
* Static switch on whether to use the conditional-move variant. * Static switch on whether to use the conditional-move variant.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param target Target begin iterator. * @param __target Target begin iterator.
* @param max_length Maximum number of elements to merge. * @param __max_length Maximum number of elements to merge.
* @param comp Comparator. * @param __comp Comparator.
* @return Output end iterator. */ * @return Output end iterator. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename OutputIterator, typename _DifferenceTp, typename _OutputIterator, typename _DifferenceTp,
typename Comparator> typename _Compare>
inline OutputIterator inline _OutputIterator
merge_advance(RandomAccessIterator1& begin1, RandomAccessIterator1 end1, __merge_advance(_RAIter1& __begin1, _RAIter1 __end1,
RandomAccessIterator2& begin2, RandomAccessIterator2 end2, _RAIter2& __begin2, _RAIter2 __end2,
OutputIterator target, _DifferenceTp max_length, _OutputIterator __target, _DifferenceTp __max_length,
Comparator comp) _Compare __comp)
{ {
_GLIBCXX_CALL(max_length) _GLIBCXX_CALL(__max_length)
return merge_advance_movc(begin1, end1, begin2, end2, target, return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target,
max_length, comp); __max_length, __comp);
} }
/** @brief Merge routine fallback to sequential in case the /** @brief Merge routine fallback to sequential in case the
iterators of the two input sequences are of different type. iterators of the two input sequences are of different type.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param target Target begin iterator. * @param __target Target begin iterator.
* @param max_length Maximum number of elements to merge. * @param __max_length Maximum number of elements to merge.
* @param comp Comparator. * @param __comp Comparator.
* @return Output end iterator. */ * @return Output end iterator. */
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename RandomAccessIterator3, typename Comparator> typename _RAIter3, typename _Compare>
inline RandomAccessIterator3 inline _RAIter3
parallel_merge_advance(RandomAccessIterator1& begin1, __parallel_merge_advance(_RAIter1& __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator2& begin2, _RAIter2& __begin2,
// different iterators, parallel implementation // different iterators, parallel implementation
// not available // not available
RandomAccessIterator2 end2, _RAIter2 __end2,
RandomAccessIterator3 target, typename _RAIter3 __target, typename
std::iterator_traits<RandomAccessIterator1>:: std::iterator_traits<_RAIter1>::
difference_type max_length, Comparator comp) difference_type __max_length, _Compare __comp)
{ return merge_advance(begin1, end1, begin2, end2, target, { return __merge_advance(__begin1, __end1, __begin2, __end2, __target,
max_length, comp); } __max_length, __comp); }
/** @brief Parallel merge routine being able to merge only the @c /** @brief Parallel merge routine being able to merge only the @__c
* max_length smallest elements. * __max_length smallest elements.
* *
* The @c begin iterators are advanced accordingly, they might not * The @__c __begin iterators are advanced accordingly, they might not
* reach @c end, in contrast to the usual variant. * reach @__c __end, in contrast to the usual variant.
* The functionality is projected onto parallel_multiway_merge. * The functionality is projected onto parallel_multiway_merge.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param target Target begin iterator. * @param __target Target begin iterator.
* @param max_length Maximum number of elements to merge. * @param __max_length Maximum number of elements to merge.
* @param comp Comparator. * @param __comp Comparator.
* @return Output end iterator. * @return Output end iterator.
*/ */
template<typename RandomAccessIterator1, typename RandomAccessIterator3, template<typename _RAIter1, typename _RAIter3,
typename Comparator> typename _Compare>
inline RandomAccessIterator3 inline _RAIter3
parallel_merge_advance(RandomAccessIterator1& begin1, __parallel_merge_advance(_RAIter1& __begin1,
RandomAccessIterator1 end1, _RAIter1 __end1,
RandomAccessIterator1& begin2, _RAIter1& __begin2,
RandomAccessIterator1 end2, _RAIter1 __end2,
RandomAccessIterator3 target, typename _RAIter3 __target, typename
std::iterator_traits<RandomAccessIterator1>:: std::iterator_traits<_RAIter1>::
difference_type max_length, Comparator comp) difference_type __max_length, _Compare __comp)
{ {
typedef typename typedef typename
std::iterator_traits<RandomAccessIterator1>::value_type value_type; std::iterator_traits<_RAIter1>::value_type _ValueType;
typedef typename std::iterator_traits<RandomAccessIterator1>:: typedef typename std::iterator_traits<_RAIter1>::
difference_type difference_type1 /* == difference_type2 */; difference_type _DifferenceType1 /* == difference_type2 */;
typedef typename std::iterator_traits<RandomAccessIterator3>:: typedef typename std::iterator_traits<_RAIter3>::
difference_type difference_type3; difference_type _DifferenceType3;
typedef typename std::pair<RandomAccessIterator1, RandomAccessIterator1> typedef typename std::pair<_RAIter1, _RAIter1>
iterator_pair; _IteratorPair;
iterator_pair _IteratorPair
seqs[2] = { std::make_pair(begin1, end1), seqs[2] = { std::make_pair(__begin1, __end1),
std::make_pair(begin2, end2) }; std::make_pair(__begin2, __end2) };
RandomAccessIterator3 _RAIter3
target_end = parallel_multiway_merge __target_end = parallel_multiway_merge
< /* stable = */ true, /* sentinels = */ false>( < /* __stable = */ true, /* __sentinels = */ false>(
seqs, seqs + 2, target, seqs, seqs + 2, __target,
multiway_merge_exact_splitting multiway_merge_exact_splitting
< /* stable = */ true, iterator_pair*, < /* __stable = */ true, _IteratorPair*,
Comparator, difference_type1>, _Compare, _DifferenceType1>,
max_length, comp, omp_get_max_threads()); __max_length, __comp, omp_get_max_threads());
return target_end; return __target_end;
} }
} //namespace __gnu_parallel } //namespace __gnu_parallel
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/multiseq_selection.h /** @file parallel/multiseq_selection.h
* @brief Functions to find elements of a certain global rank in * @brief Functions to find elements of a certain global __rank in
* multiple sorted sequences. Also serves for splitting such * multiple sorted sequences. Also serves for splitting such
* sequence sets. * sequence sets.
* *
...@@ -50,275 +50,275 @@ ...@@ -50,275 +50,275 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Compare a pair of types lexicographically, ascending. */ /** @brief Compare __a pair of types lexicographically, ascending. */
template<typename T1, typename T2, typename Comparator> template<typename _T1, typename _T2, typename _Compare>
class lexicographic class _Lexicographic
: public std::binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool> : public std::binary_function<std::pair<_T1, _T2>, std::pair<_T1, _T2>, bool>
{ {
private: private:
Comparator& comp; _Compare& __comp;
public: public:
lexicographic(Comparator& _comp) : comp(_comp) { } _Lexicographic(_Compare& _comp) : __comp(_comp) { }
bool bool
operator()(const std::pair<T1, T2>& p1, operator()(const std::pair<_T1, _T2>& __p1,
const std::pair<T1, T2>& p2) const const std::pair<_T1, _T2>& __p2) const
{ {
if (comp(p1.first, p2.first)) if (__comp(__p1.first, __p2.first))
return true; return true;
if (comp(p2.first, p1.first)) if (__comp(__p2.first, __p1.first))
return false; return false;
// Firsts are equal. // Firsts are equal.
return p1.second < p2.second; return __p1.second < __p2.second;
} }
}; };
/** @brief Compare a pair of types lexicographically, descending. */ /** @brief Compare __a pair of types lexicographically, descending. */
template<typename T1, typename T2, typename Comparator> template<typename _T1, typename _T2, typename _Compare>
class lexicographic_reverse : public std::binary_function<T1, T2, bool> class _LexicographicReverse : public std::binary_function<_T1, _T2, bool>
{ {
private: private:
Comparator& comp; _Compare& __comp;
public: public:
lexicographic_reverse(Comparator& _comp) : comp(_comp) { } _LexicographicReverse(_Compare& _comp) : __comp(_comp) { }
bool bool
operator()(const std::pair<T1, T2>& p1, operator()(const std::pair<_T1, _T2>& __p1,
const std::pair<T1, T2>& p2) const const std::pair<_T1, _T2>& __p2) const
{ {
if (comp(p2.first, p1.first)) if (__comp(__p2.first, __p1.first))
return true; return true;
if (comp(p1.first, p2.first)) if (__comp(__p1.first, __p2.first))
return false; return false;
// Firsts are equal. // Firsts are equal.
return p2.second < p1.second; return __p2.second < __p1.second;
} }
}; };
/** /**
* @brief Splits several sorted sequences at a certain global rank, * @brief Splits several sorted sequences at __a certain global __rank,
* resulting in a splitting point for each sequence. * resulting in a splitting point for each sequence.
* The sequences are passed via a sequence of random-access * The sequences are passed via __a __sequence of random-access
* iterator pairs, none of the sequences may be empty. If there * iterator pairs, none of the sequences may be empty. If there
* are several equal elements across the split, the ones on the * are several equal elements across the split, the ones on the
* left side will be chosen from sequences with smaller number. * __left side will be chosen from sequences with smaller number.
* @param begin_seqs Begin of the sequence of iterator pairs. * @param __begin_seqs Begin of the sequence of iterator pairs.
* @param end_seqs End of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs.
* @param rank The global rank to partition at. * @param __rank The global __rank to partition at.
* @param begin_offsets A random-access sequence begin where the * @param __begin_offsets A random-access __sequence __begin where the
* result will be stored in. Each element of the sequence is an * __result will be stored in. Each element of the sequence is an
* iterator that points to the first element on the greater part of * iterator that points to the first element on the greater part of
* the respective sequence. * the respective __sequence.
* @param comp The ordering functor, defaults to std::less<T>. * @param __comp The ordering functor, defaults to std::less<_Tp>.
*/ */
template<typename RanSeqs, typename RankType, typename RankIterator, template<typename _RanSeqs, typename _RankType, typename _RankIterator,
typename Comparator> typename _Compare>
void void
multiseq_partition(RanSeqs begin_seqs, RanSeqs end_seqs, multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs,
RankType rank, _RankType __rank,
RankIterator begin_offsets, _RankIterator __begin_offsets,
Comparator comp = std::less< _Compare __comp = std::less<
typename std::iterator_traits<typename typename std::iterator_traits<typename
std::iterator_traits<RanSeqs>::value_type:: std::iterator_traits<_RanSeqs>::value_type::
first_type>::value_type>()) // std::less<T> first_type>::value_type>()) // std::less<_Tp>
{ {
_GLIBCXX_CALL(end_seqs - begin_seqs) _GLIBCXX_CALL(__end_seqs - __begin_seqs)
typedef typename std::iterator_traits<RanSeqs>::value_type::first_type typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
It; _It;
typedef typename std::iterator_traits<It>::difference_type typedef typename std::iterator_traits<_It>::difference_type
difference_type; _DifferenceType;
typedef typename std::iterator_traits<It>::value_type value_type; typedef typename std::iterator_traits<_It>::value_type _ValueType;
lexicographic<value_type, int, Comparator> lcomp(comp); _Lexicographic<_ValueType, int, _Compare> __lcomp(__comp);
lexicographic_reverse<value_type, int, Comparator> lrcomp(comp); _LexicographicReverse<_ValueType, int, _Compare> __lrcomp(__comp);
// Number of sequences, number of elements in total (possibly // Number of sequences, number of elements in total (possibly
// including padding). // including padding).
difference_type m = std::distance(begin_seqs, end_seqs), N = 0, _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __N = 0,
nmax, n, r; __nmax, __n, __r;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
N += std::distance(begin_seqs[i].first, begin_seqs[i].second); __N += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second);
_GLIBCXX_PARALLEL_ASSERT( _GLIBCXX_PARALLEL_ASSERT(
std::distance(begin_seqs[i].first, begin_seqs[i].second) > 0); std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second) > 0);
} }
if (rank == N) if (__rank == __N)
{ {
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
begin_offsets[i] = begin_seqs[i].second; // Very end. __begin_offsets[__i] = __begin_seqs[__i].second; // Very end.
// Return m - 1; // Return __m - 1;
return; return;
} }
_GLIBCXX_PARALLEL_ASSERT(m != 0); _GLIBCXX_PARALLEL_ASSERT(__m != 0);
_GLIBCXX_PARALLEL_ASSERT(N != 0); _GLIBCXX_PARALLEL_ASSERT(__N != 0);
_GLIBCXX_PARALLEL_ASSERT(rank >= 0); _GLIBCXX_PARALLEL_ASSERT(__rank >= 0);
_GLIBCXX_PARALLEL_ASSERT(rank < N); _GLIBCXX_PARALLEL_ASSERT(__rank < __N);
difference_type* ns = new difference_type[m]; _DifferenceType* __ns = new _DifferenceType[__m];
difference_type* a = new difference_type[m]; _DifferenceType* __a = new _DifferenceType[__m];
difference_type* b = new difference_type[m]; _DifferenceType* __b = new _DifferenceType[__m];
difference_type l; _DifferenceType __l;
ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second); __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
nmax = ns[0]; __nmax = __ns[0];
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second); __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second);
nmax = std::max(nmax, ns[i]); __nmax = std::max(__nmax, __ns[__i]);
} }
r = __log2(nmax) + 1; __r = __log2(__nmax) + 1;
// Pad all lists to this length, at least as long as any ns[i], // Pad all lists to this length, at least as long as any ns[__i],
// equality iff nmax = 2^k - 1. // equality iff __nmax = 2^__k - 1.
l = (1ULL << r) - 1; __l = (1ULL << __r) - 1;
// From now on, including padding. // From now on, including padding.
N = l * m; __N = __l * __m;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
a[i] = 0; __a[__i] = 0;
b[i] = l; __b[__i] = __l;
} }
n = l / 2; __n = __l / 2;
// Invariants: // Invariants:
// 0 <= a[i] <= ns[i], 0 <= b[i] <= l // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l
#define S(i) (begin_seqs[i].first) #define __S(__i) (__begin_seqs[__i].first)
// Initial partition. // Initial partition.
std::vector<std::pair<value_type, int> > sample; std::vector<std::pair<_ValueType, int> > __sample;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
if (n < ns[i]) //sequence long enough if (__n < __ns[__i]) //__sequence long enough
sample.push_back(std::make_pair(S(i)[n], i)); __sample.push_back(std::make_pair(__S(__i)[__n], __i));
__gnu_sequential::sort(sample.begin(), sample.end(), lcomp); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp);
for (int i = 0; i < m; i++) //conceptual infinity for (int __i = 0; __i < __m; __i++) //conceptual infinity
if (n >= ns[i]) //sequence too short, conceptual infinity if (__n >= __ns[__i]) //__sequence too short, conceptual infinity
sample.push_back(std::make_pair(S(i)[0] /*dummy element*/, i)); __sample.push_back(std::make_pair(__S(__i)[0] /*__dummy element*/, __i));
difference_type localrank = rank * m / N ; _DifferenceType localrank = __rank * __m / __N ;
int j; int __j;
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j) for (__j = 0; __j < localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j)
a[sample[j].second] += n + 1; __a[__sample[__j].second] += __n + 1;
for (; j < m; j++) for (; __j < __m; __j++)
b[sample[j].second] -= n + 1; __b[__sample[__j].second] -= __n + 1;
// Further refinement. // Further refinement.
while (n > 0) while (__n > 0)
{ {
n /= 2; __n /= 2;
int lmax_seq = -1; // to avoid warning int __lmax_seq = -1; // to avoid warning
const value_type* lmax = NULL; // impossible to avoid the warning? const _ValueType* __lmax = NULL; // impossible to avoid the warning?
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
if (a[i] > 0) if (__a[__i] > 0)
{ {
if (!lmax) if (!__lmax)
{ {
lmax = &(S(i)[a[i] - 1]); __lmax = &(__S(__i)[__a[__i] - 1]);
lmax_seq = i; __lmax_seq = __i;
} }
else else
{ {
// Max, favor rear sequences. // Max, favor rear sequences.
if (!comp(S(i)[a[i] - 1], *lmax)) if (!__comp(__S(__i)[__a[__i] - 1], *__lmax))
{ {
lmax = &(S(i)[a[i] - 1]); __lmax = &(__S(__i)[__a[__i] - 1]);
lmax_seq = i; __lmax_seq = __i;
} }
} }
} }
} }
int i; int __i;
for (i = 0; i < m; i++) for (__i = 0; __i < __m; __i++)
{ {
difference_type middle = (b[i] + a[i]) / 2; _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
if (lmax && middle < ns[i] && if (__lmax && __middle < __ns[__i] &&
lcomp(std::make_pair(S(i)[middle], i), __lcomp(std::make_pair(__S(__i)[__middle], __i),
std::make_pair(*lmax, lmax_seq))) std::make_pair(*__lmax, __lmax_seq)))
a[i] = std::min(a[i] + n + 1, ns[i]); __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]);
else else
b[i] -= n + 1; __b[__i] -= __n + 1;
} }
difference_type leftsize = 0, total = 0; _DifferenceType __leftsize = 0, __total = 0;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
leftsize += a[i] / (n + 1); __leftsize += __a[__i] / (__n + 1);
total += l / (n + 1); __total += __l / (__n + 1);
} }
difference_type skew = static_cast<difference_type> _DifferenceType __skew = static_cast<_DifferenceType>
(static_cast<uint64>(total) * rank / N - leftsize); (static_cast<uint64>(__total) * __rank / __N - __leftsize);
if (skew > 0) if (__skew > 0)
{ {
// Move to the left, find smallest. // Move to the left, find smallest.
std::priority_queue<std::pair<value_type, int>, std::priority_queue<std::pair<_ValueType, int>,
std::vector<std::pair<value_type, int> >, std::vector<std::pair<_ValueType, int> >,
lexicographic_reverse<value_type, int, Comparator> > _LexicographicReverse<_ValueType, int, _Compare> >
pq(lrcomp); __pq(__lrcomp);
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
if (b[i] < ns[i]) if (__b[__i] < __ns[__i])
pq.push(std::make_pair(S(i)[b[i]], i)); __pq.push(std::make_pair(__S(__i)[__b[__i]], __i));
for (; skew != 0 && !pq.empty(); --skew) for (; __skew != 0 && !__pq.empty(); --__skew)
{ {
int source = pq.top().second; int source = __pq.top().second;
pq.pop(); __pq.pop();
a[source] = std::min(a[source] + n + 1, ns[source]); __a[source] = std::min(__a[source] + __n + 1, __ns[source]);
b[source] += n + 1; __b[source] += __n + 1;
if (b[source] < ns[source]) if (__b[source] < __ns[source])
pq.push(std::make_pair(S(source)[b[source]], source)); __pq.push(std::make_pair(__S(source)[__b[source]], source));
} }
} }
else if (skew < 0) else if (__skew < 0)
{ {
// Move to the right, find greatest. // Move to the right, find greatest.
std::priority_queue<std::pair<value_type, int>, std::priority_queue<std::pair<_ValueType, int>,
std::vector<std::pair<value_type, int> >, std::vector<std::pair<_ValueType, int> >,
lexicographic<value_type, int, Comparator> > pq(lcomp); _Lexicographic<_ValueType, int, _Compare> > __pq(__lcomp);
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
if (a[i] > 0) if (__a[__i] > 0)
pq.push(std::make_pair(S(i)[a[i] - 1], i)); __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i));
for (; skew != 0; ++skew) for (; __skew != 0; ++__skew)
{ {
int source = pq.top().second; int source = __pq.top().second;
pq.pop(); __pq.pop();
a[source] -= n + 1; __a[source] -= __n + 1;
b[source] -= n + 1; __b[source] -= __n + 1;
if (a[source] > 0) if (__a[source] > 0)
pq.push(std::make_pair(S(source)[a[source] - 1], source)); __pq.push(std::make_pair(__S(source)[__a[source] - 1], source));
} }
} }
} }
// Postconditions: // Postconditions:
// a[i] == b[i] in most cases, except when a[i] has been clamped // __a[__i] == __b[__i] in most cases, except when __a[__i] has been clamped
// because of having reached the boundary // because of having reached the boundary
// Now return the result, calculate the offset. // Now return the result, calculate the offset.
...@@ -326,236 +326,236 @@ namespace __gnu_parallel ...@@ -326,236 +326,236 @@ namespace __gnu_parallel
// Compare the keys on both edges of the border. // Compare the keys on both edges of the border.
// Maximum of left edge, minimum of right edge. // Maximum of left edge, minimum of right edge.
value_type* maxleft = NULL; _ValueType* __maxleft = NULL;
value_type* minright = NULL; _ValueType* __minright = NULL;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
{ {
if (a[i] > 0) if (__a[__i] > 0)
{ {
if (!maxleft) if (!__maxleft)
maxleft = &(S(i)[a[i] - 1]); __maxleft = &(__S(__i)[__a[__i] - 1]);
else else
{ {
// Max, favor rear sequences. // Max, favor rear sequences.
if (!comp(S(i)[a[i] - 1], *maxleft)) if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft))
maxleft = &(S(i)[a[i] - 1]); __maxleft = &(__S(__i)[__a[__i] - 1]);
} }
} }
if (b[i] < ns[i]) if (__b[__i] < __ns[__i])
{ {
if (!minright) if (!__minright)
minright = &(S(i)[b[i]]); __minright = &(__S(__i)[__b[__i]]);
else else
{ {
// Min, favor fore sequences. // Min, favor fore sequences.
if (comp(S(i)[b[i]], *minright)) if (__comp(__S(__i)[__b[__i]], *__minright))
minright = &(S(i)[b[i]]); __minright = &(__S(__i)[__b[__i]]);
} }
} }
} }
int seq = 0; int __seq = 0;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
begin_offsets[i] = S(i) + a[i]; __begin_offsets[__i] = __S(__i) + __a[__i];
delete[] ns; delete[] __ns;
delete[] a; delete[] __a;
delete[] b; delete[] __b;
} }
/** /**
* @brief Selects the element at a certain global rank from several * @brief Selects the element at __a certain global __rank from several
* sorted sequences. * sorted sequences.
* *
* The sequences are passed via a sequence of random-access * The sequences are passed via __a __sequence of random-access
* iterator pairs, none of the sequences may be empty. * iterator pairs, none of the sequences may be empty.
* @param begin_seqs Begin of the sequence of iterator pairs. * @param __begin_seqs Begin of the sequence of iterator pairs.
* @param end_seqs End of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs.
* @param rank The global rank to partition at. * @param __rank The global __rank to partition at.
* @param offset The rank of the selected element in the global * @param __offset The rank of the selected element in the global
* subsequence of elements equal to the selected element. If the * subsequence of elements equal to the selected element. If the
* selected element is unique, this number is 0. * selected element is unique, this number is 0.
* @param comp The ordering functor, defaults to std::less. * @param __comp The ordering functor, defaults to std::less.
*/ */
template<typename T, typename RanSeqs, typename RankType, template<typename _Tp, typename _RanSeqs, typename _RankType,
typename Comparator> typename _Compare>
T _Tp
multiseq_selection(RanSeqs begin_seqs, RanSeqs end_seqs, RankType rank, multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank,
RankType& offset, Comparator comp = std::less<T>()) _RankType& __offset, _Compare __comp = std::less<_Tp>())
{ {
_GLIBCXX_CALL(end_seqs - begin_seqs) _GLIBCXX_CALL(__end_seqs - __begin_seqs)
typedef typename std::iterator_traits<RanSeqs>::value_type::first_type typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
It; _It;
typedef typename std::iterator_traits<It>::difference_type typedef typename std::iterator_traits<_It>::difference_type
difference_type; _DifferenceType;
lexicographic<T, int, Comparator> lcomp(comp); _Lexicographic<_Tp, int, _Compare> __lcomp(__comp);
lexicographic_reverse<T, int, Comparator> lrcomp(comp); _LexicographicReverse<_Tp, int, _Compare> __lrcomp(__comp);
// Number of sequences, number of elements in total (possibly // Number of sequences, number of elements in total (possibly
// including padding). // including padding).
difference_type m = std::distance(begin_seqs, end_seqs); _DifferenceType __m = std::distance(__begin_seqs, __end_seqs);
difference_type N = 0; _DifferenceType __N = 0;
difference_type nmax, n, r; _DifferenceType __nmax, __n, __r;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
N += std::distance(begin_seqs[i].first, begin_seqs[i].second); __N += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second);
if (m == 0 || N == 0 || rank < 0 || rank >= N) if (__m == 0 || __N == 0 || __rank < 0 || __rank >= __N)
{ {
// Result undefined when there is no data or rank is outside bounds. // _Result undefined when there is no data or __rank is outside bounds.
throw std::exception(); throw std::exception();
} }
difference_type* ns = new difference_type[m]; _DifferenceType* __ns = new _DifferenceType[__m];
difference_type* a = new difference_type[m]; _DifferenceType* __a = new _DifferenceType[__m];
difference_type* b = new difference_type[m]; _DifferenceType* __b = new _DifferenceType[__m];
difference_type l; _DifferenceType __l;
ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second); __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
nmax = ns[0]; __nmax = __ns[0];
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second); __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second);
nmax = std::max(nmax, ns[i]); __nmax = std::max(__nmax, __ns[__i]);
} }
r = __log2(nmax) + 1; __r = __log2(__nmax) + 1;
// Pad all lists to this length, at least as long as any ns[i], // Pad all lists to this length, at least as long as any ns[__i],
// equality iff nmax = 2^k - 1 // equality iff __nmax = 2^__k - 1
l = pow2(r) - 1; __l = pow2(__r) - 1;
// From now on, including padding. // From now on, including padding.
N = l * m; __N = __l * __m;
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
a[i] = 0; __a[__i] = 0;
b[i] = l; __b[__i] = __l;
} }
n = l / 2; __n = __l / 2;
// Invariants: // Invariants:
// 0 <= a[i] <= ns[i], 0 <= b[i] <= l // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l
#define S(i) (begin_seqs[i].first) #define __S(__i) (__begin_seqs[__i].first)
// Initial partition. // Initial partition.
std::vector<std::pair<T, int> > sample; std::vector<std::pair<_Tp, int> > __sample;
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
if (n < ns[i]) if (__n < __ns[__i])
sample.push_back(std::make_pair(S(i)[n], i)); __sample.push_back(std::make_pair(__S(__i)[__n], __i));
__gnu_sequential::sort(sample.begin(), sample.end(), __gnu_sequential::sort(__sample.begin(), __sample.end(),
lcomp, sequential_tag()); __lcomp, sequential_tag());
// Conceptual infinity. // Conceptual infinity.
for (int i = 0; i < m; i++) for (int __i = 0; __i < __m; __i++)
if (n >= ns[i]) if (__n >= __ns[__i])
sample.push_back(std::make_pair(S(i)[0] /*dummy element*/, i)); __sample.push_back(std::make_pair(__S(__i)[0] /*__dummy element*/, __i));
difference_type localrank = rank * m / N ; _DifferenceType localrank = __rank * __m / __N ;
int j; int __j;
for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j) for (__j = 0; __j < localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j)
a[sample[j].second] += n + 1; __a[__sample[__j].second] += __n + 1;
for (; j < m; ++j) for (; __j < __m; ++__j)
b[sample[j].second] -= n + 1; __b[__sample[__j].second] -= __n + 1;
// Further refinement. // Further refinement.
while (n > 0) while (__n > 0)
{ {
n /= 2; __n /= 2;
const T* lmax = NULL; const _Tp* __lmax = NULL;
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
if (a[i] > 0) if (__a[__i] > 0)
{ {
if (!lmax) if (!__lmax)
lmax = &(S(i)[a[i] - 1]); __lmax = &(__S(__i)[__a[__i] - 1]);
else else
{ {
if (comp(*lmax, S(i)[a[i] - 1])) //max if (__comp(*__lmax, __S(__i)[__a[__i] - 1])) //max
lmax = &(S(i)[a[i] - 1]); __lmax = &(__S(__i)[__a[__i] - 1]);
} }
} }
} }
int i; int __i;
for (i = 0; i < m; i++) for (__i = 0; __i < __m; __i++)
{ {
difference_type middle = (b[i] + a[i]) / 2; _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
if (lmax && middle < ns[i] && comp(S(i)[middle], *lmax)) if (__lmax && __middle < __ns[__i] && __comp(__S(__i)[__middle], *__lmax))
a[i] = std::min(a[i] + n + 1, ns[i]); __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]);
else else
b[i] -= n + 1; __b[__i] -= __n + 1;
} }
difference_type leftsize = 0, total = 0; _DifferenceType __leftsize = 0, __total = 0;
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
leftsize += a[i] / (n + 1); __leftsize += __a[__i] / (__n + 1);
total += l / (n + 1); __total += __l / (__n + 1);
} }
difference_type skew = ((unsigned long long)total * rank / N _DifferenceType __skew = ((unsigned long long)__total * __rank / __N
- leftsize); - __leftsize);
if (skew > 0) if (__skew > 0)
{ {
// Move to the left, find smallest. // Move to the left, find smallest.
std::priority_queue<std::pair<T, int>, std::priority_queue<std::pair<_Tp, int>,
std::vector<std::pair<T, int> >, std::vector<std::pair<_Tp, int> >,
lexicographic_reverse<T, int, Comparator> > pq(lrcomp); _LexicographicReverse<_Tp, int, _Compare> > __pq(__lrcomp);
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
if (b[i] < ns[i]) if (__b[__i] < __ns[__i])
pq.push(std::make_pair(S(i)[b[i]], i)); __pq.push(std::make_pair(__S(__i)[__b[__i]], __i));
for (; skew != 0 && !pq.empty(); --skew) for (; __skew != 0 && !__pq.empty(); --__skew)
{ {
int source = pq.top().second; int source = __pq.top().second;
pq.pop(); __pq.pop();
a[source] = std::min(a[source] + n + 1, ns[source]); __a[source] = std::min(__a[source] + __n + 1, __ns[source]);
b[source] += n + 1; __b[source] += __n + 1;
if (b[source] < ns[source]) if (__b[source] < __ns[source])
pq.push(std::make_pair(S(source)[b[source]], source)); __pq.push(std::make_pair(__S(source)[__b[source]], source));
} }
} }
else if (skew < 0) else if (__skew < 0)
{ {
// Move to the right, find greatest. // Move to the right, find greatest.
std::priority_queue<std::pair<T, int>, std::priority_queue<std::pair<_Tp, int>,
std::vector<std::pair<T, int> >, std::vector<std::pair<_Tp, int> >,
lexicographic<T, int, Comparator> > pq(lcomp); _Lexicographic<_Tp, int, _Compare> > __pq(__lcomp);
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
if (a[i] > 0) if (__a[__i] > 0)
pq.push(std::make_pair(S(i)[a[i] - 1], i)); __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i));
for (; skew != 0; ++skew) for (; __skew != 0; ++__skew)
{ {
int source = pq.top().second; int source = __pq.top().second;
pq.pop(); __pq.pop();
a[source] -= n + 1; __a[source] -= __n + 1;
b[source] -= n + 1; __b[source] -= __n + 1;
if (a[source] > 0) if (__a[source] > 0)
pq.push(std::make_pair(S(source)[a[source] - 1], source)); __pq.push(std::make_pair(__S(source)[__a[source] - 1], source));
} }
} }
} }
// Postconditions: // Postconditions:
// a[i] == b[i] in most cases, except when a[i] has been clamped // __a[__i] == __b[__i] in most cases, except when __a[__i] has been clamped
// because of having reached the boundary // because of having reached the boundary
// Now return the result, calculate the offset. // Now return the result, calculate the offset.
...@@ -563,71 +563,71 @@ namespace __gnu_parallel ...@@ -563,71 +563,71 @@ namespace __gnu_parallel
// Compare the keys on both edges of the border. // Compare the keys on both edges of the border.
// Maximum of left edge, minimum of right edge. // Maximum of left edge, minimum of right edge.
bool maxleftset = false, minrightset = false; bool __maxleftset = false, __minrightset = false;
// Impossible to avoid the warning? // Impossible to avoid the warning?
T maxleft, minright; _Tp __maxleft, __minright;
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
if (a[i] > 0) if (__a[__i] > 0)
{ {
if (!maxleftset) if (!__maxleftset)
{ {
maxleft = S(i)[a[i] - 1]; __maxleft = __S(__i)[__a[__i] - 1];
maxleftset = true; __maxleftset = true;
} }
else else
{ {
// Max. // Max.
if (comp(maxleft, S(i)[a[i] - 1])) if (__comp(__maxleft, __S(__i)[__a[__i] - 1]))
maxleft = S(i)[a[i] - 1]; __maxleft = __S(__i)[__a[__i] - 1];
} }
} }
if (b[i] < ns[i]) if (__b[__i] < __ns[__i])
{ {
if (!minrightset) if (!__minrightset)
{ {
minright = S(i)[b[i]]; __minright = __S(__i)[__b[__i]];
minrightset = true; __minrightset = true;
} }
else else
{ {
// Min. // Min.
if (comp(S(i)[b[i]], minright)) if (__comp(__S(__i)[__b[__i]], __minright))
minright = S(i)[b[i]]; __minright = __S(__i)[__b[__i]];
} }
} }
} }
// Minright is the splitter, in any case. // Minright is the splitter, in any case.
if (!maxleftset || comp(minright, maxleft)) if (!__maxleftset || __comp(__minright, __maxleft))
{ {
// Good luck, everything is split unambiguously. // Good luck, everything is split unambiguously.
offset = 0; __offset = 0;
} }
else else
{ {
// We have to calculate an offset. // We have to calculate an offset.
offset = 0; __offset = 0;
for (int i = 0; i < m; ++i) for (int __i = 0; __i < __m; ++__i)
{ {
difference_type lb = std::lower_bound(S(i), S(i) + ns[i], _DifferenceType lb = std::lower_bound(__S(__i), __S(__i) + __ns[__i],
minright, __minright,
comp) - S(i); __comp) - __S(__i);
offset += a[i] - lb; __offset += __a[__i] - lb;
} }
} }
delete[] ns; delete[] __ns;
delete[] a; delete[] __a;
delete[] b; delete[] __b;
return minright; return __minright;
} }
} }
#undef S #undef __S
#endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */ #endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -44,431 +44,431 @@ namespace __gnu_parallel ...@@ -44,431 +44,431 @@ namespace __gnu_parallel
/** @brief Subsequence description. */ /** @brief Subsequence description. */
template<typename _DifferenceTp> template<typename _DifferenceTp>
struct Piece struct _Piece
{ {
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
/** @brief Begin of subsequence. */ /** @brief Begin of subsequence. */
difference_type begin; _DifferenceType __begin;
/** @brief End of subsequence. */ /** @brief End of subsequence. */
difference_type end; _DifferenceType __end;
}; };
/** @brief Data accessed by all threads. /** @brief Data accessed by all threads.
* *
* PMWMS = parallel multiway mergesort */ * PMWMS = parallel multiway mergesort */
template<typename RandomAccessIterator> template<typename _RAIter>
struct PMWMSSortingData struct _PMWMSSortingData
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
/** @brief Number of threads involved. */ /** @brief Number of threads involved. */
thread_index_t num_threads; _ThreadIndex __num_threads;
/** @brief Input begin. */ /** @brief Input __begin. */
RandomAccessIterator source; _RAIter _M_source;
/** @brief Start indices, per thread. */ /** @brief Start indices, per thread. */
difference_type* starts; _DifferenceType* _M_starts;
/** @brief Storage in which to sort. */ /** @brief Storage in which to sort. */
value_type** temporary; _ValueType** _M_temporary;
/** @brief Samples. */ /** @brief Samples. */
value_type* samples; _ValueType* _M_samples;
/** @brief Offsets to add to the found positions. */ /** @brief Offsets to add to the found positions. */
difference_type* offsets; _DifferenceType* _M_offsets;
/** @brief Pieces of data to merge @c [thread][sequence] */ /** @brief Pieces of data to merge @__c [thread][__sequence] */
std::vector<Piece<difference_type> >* pieces; std::vector<_Piece<_DifferenceType> >* _M_pieces;
}; };
/** /**
* @brief Select samples from a sequence. * @brief Select _M_samples from a sequence.
* @param sd Pointer to algorithm data. Result will be placed in * @param __sd Pointer to algorithm data. _Result will be placed in
* @c sd->samples. * @__c __sd->_M_samples.
* @param num_samples Number of samples to select. * @param __num_samples Number of _M_samples to select.
*/ */
template<typename RandomAccessIterator, typename _DifferenceTp> template<typename _RAIter, typename _DifferenceTp>
void void
determine_samples(PMWMSSortingData<RandomAccessIterator>* sd, __determine_samples(_PMWMSSortingData<_RAIter>* __sd,
_DifferenceTp num_samples) _DifferenceTp __num_samples)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type* es = new difference_type[num_samples + 2]; _DifferenceType* __es = new _DifferenceType[__num_samples + 2];
equally_split(sd->starts[iam + 1] - sd->starts[iam], equally_split(__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam],
num_samples + 1, es); __num_samples + 1, __es);
for (difference_type i = 0; i < num_samples; ++i) for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
::new(&(sd->samples[iam * num_samples + i])) ::new(&(__sd->_M_samples[__iam * __num_samples + __i]))
value_type(sd->source[sd->starts[iam] + es[i + 1]]); _ValueType(__sd->_M_source[__sd->_M_starts[__iam] + __es[__i + 1]]);
delete[] es; delete[] __es;
} }
/** @brief Split consistently. */ /** @brief Split consistently. */
template<bool exact, typename RandomAccessIterator, template<bool __exact, typename _RAIter,
typename Comparator, typename SortingPlacesIterator> typename _Compare, typename _SortingPlacesIterator>
struct split_consistently struct _SplitConsistently
{ {
}; };
/** @brief Split by exact splitting. */ /** @brief Split by exact splitting. */
template<typename RandomAccessIterator, typename Comparator, template<typename _RAIter, typename _Compare,
typename SortingPlacesIterator> typename _SortingPlacesIterator>
struct split_consistently struct _SplitConsistently
<true, RandomAccessIterator, Comparator, SortingPlacesIterator> <true, _RAIter, _Compare, _SortingPlacesIterator>
{ {
void operator()( void operator()(
const thread_index_t iam, const _ThreadIndex __iam,
PMWMSSortingData<RandomAccessIterator>* sd, _PMWMSSortingData<_RAIter>* __sd,
Comparator& comp, _Compare& __comp,
const typename const typename
std::iterator_traits<RandomAccessIterator>::difference_type std::iterator_traits<_RAIter>::difference_type
num_samples) __num_samples)
const const
{ {
# pragma omp barrier # pragma omp barrier
std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> > std::vector<std::pair<_SortingPlacesIterator, _SortingPlacesIterator> >
seqs(sd->num_threads); seqs(__sd->__num_threads);
for (thread_index_t s = 0; s < sd->num_threads; s++) for (_ThreadIndex __s = 0; __s < __sd->__num_threads; __s++)
seqs[s] = std::make_pair(sd->temporary[s], seqs[__s] = std::make_pair(__sd->_M_temporary[__s],
sd->temporary[s] __sd->_M_temporary[__s]
+ (sd->starts[s + 1] - sd->starts[s])); + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]));
std::vector<SortingPlacesIterator> offsets(sd->num_threads); std::vector<_SortingPlacesIterator> _M_offsets(__sd->__num_threads);
// if not last thread // if not last thread
if (iam < sd->num_threads - 1) if (__iam < __sd->__num_threads - 1)
multiseq_partition(seqs.begin(), seqs.end(), multiseq_partition(seqs.begin(), seqs.end(),
sd->starts[iam + 1], offsets.begin(), comp); __sd->_M_starts[__iam + 1], _M_offsets.begin(), __comp);
for (int seq = 0; seq < sd->num_threads; seq++) for (int __seq = 0; __seq < __sd->__num_threads; __seq++)
{ {
// for each sequence // for each sequence
if (iam < (sd->num_threads - 1)) if (__iam < (__sd->__num_threads - 1))
sd->pieces[iam][seq].end = offsets[seq] - seqs[seq].first; __sd->_M_pieces[__iam][__seq].__end = _M_offsets[__seq] - seqs[__seq].first;
else else
// very end of this sequence // very end of this sequence
sd->pieces[iam][seq].end = __sd->_M_pieces[__iam][__seq].__end =
sd->starts[seq + 1] - sd->starts[seq]; __sd->_M_starts[__seq + 1] - __sd->_M_starts[__seq];
} }
# pragma omp barrier # pragma omp barrier
for (thread_index_t seq = 0; seq < sd->num_threads; seq++) for (_ThreadIndex __seq = 0; __seq < __sd->__num_threads; __seq++)
{ {
// For each sequence. // For each sequence.
if (iam > 0) if (__iam > 0)
sd->pieces[iam][seq].begin = sd->pieces[iam - 1][seq].end; __sd->_M_pieces[__iam][__seq].__begin = __sd->_M_pieces[__iam - 1][__seq].__end;
else else
// Absolute beginning. // Absolute beginning.
sd->pieces[iam][seq].begin = 0; __sd->_M_pieces[__iam][__seq].__begin = 0;
} }
} }
}; };
/** @brief Split by sampling. */ /** @brief Split by sampling. */
template<typename RandomAccessIterator, typename Comparator, template<typename _RAIter, typename _Compare,
typename SortingPlacesIterator> typename _SortingPlacesIterator>
struct split_consistently<false, RandomAccessIterator, Comparator, struct _SplitConsistently<false, _RAIter, _Compare,
SortingPlacesIterator> _SortingPlacesIterator>
{ {
void operator()( void operator()(
const thread_index_t iam, const _ThreadIndex __iam,
PMWMSSortingData<RandomAccessIterator>* sd, _PMWMSSortingData<_RAIter>* __sd,
Comparator& comp, _Compare& __comp,
const typename const typename
std::iterator_traits<RandomAccessIterator>::difference_type std::iterator_traits<_RAIter>::difference_type
num_samples) __num_samples)
const const
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
determine_samples(sd, num_samples); __determine_samples(__sd, __num_samples);
# pragma omp barrier # pragma omp barrier
# pragma omp single # pragma omp single
__gnu_sequential::sort(sd->samples, __gnu_sequential::sort(__sd->_M_samples,
sd->samples + (num_samples * sd->num_threads), __sd->_M_samples + (__num_samples * __sd->__num_threads),
comp); __comp);
# pragma omp barrier # pragma omp barrier
for (thread_index_t s = 0; s < sd->num_threads; ++s) for (_ThreadIndex __s = 0; __s < __sd->__num_threads; ++__s)
{ {
// For each sequence. // For each sequence.
if (num_samples * iam > 0) if (__num_samples * __iam > 0)
sd->pieces[iam][s].begin = __sd->_M_pieces[__iam][__s].__begin =
std::lower_bound(sd->temporary[s], std::lower_bound(__sd->_M_temporary[__s],
sd->temporary[s] __sd->_M_temporary[__s]
+ (sd->starts[s + 1] - sd->starts[s]), + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]),
sd->samples[num_samples * iam], __sd->_M_samples[__num_samples * __iam],
comp) __comp)
- sd->temporary[s]; - __sd->_M_temporary[__s];
else else
// Absolute beginning. // Absolute beginning.
sd->pieces[iam][s].begin = 0; __sd->_M_pieces[__iam][__s].__begin = 0;
if ((num_samples * (iam + 1)) < (num_samples * sd->num_threads)) if ((__num_samples * (__iam + 1)) < (__num_samples * __sd->__num_threads))
sd->pieces[iam][s].end = __sd->_M_pieces[__iam][__s].__end =
std::lower_bound(sd->temporary[s], std::lower_bound(__sd->_M_temporary[__s],
sd->temporary[s] __sd->_M_temporary[__s]
+ (sd->starts[s + 1] - sd->starts[s]), + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]),
sd->samples[num_samples * (iam + 1)], __sd->_M_samples[__num_samples * (__iam + 1)],
comp) __comp)
- sd->temporary[s]; - __sd->_M_temporary[__s];
else else
// Absolute end. // Absolute __end.
sd->pieces[iam][s].end = sd->starts[s + 1] - sd->starts[s]; __sd->_M_pieces[__iam][__s].__end = __sd->_M_starts[__s + 1] - __sd->_M_starts[__s];
} }
} }
}; };
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
struct possibly_stable_sort struct __possibly_stable_sort
{ {
}; };
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
struct possibly_stable_sort<true, RandomAccessIterator, Comparator> struct __possibly_stable_sort<true, _RAIter, _Compare>
{ {
void operator()(const RandomAccessIterator& begin, void operator()(const _RAIter& __begin,
const RandomAccessIterator& end, Comparator& comp) const const _RAIter& __end, _Compare& __comp) const
{ {
__gnu_sequential::stable_sort(begin, end, comp); __gnu_sequential::stable_sort(__begin, __end, __comp);
} }
}; };
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
struct possibly_stable_sort<false, RandomAccessIterator, Comparator> struct __possibly_stable_sort<false, _RAIter, _Compare>
{ {
void operator()(const RandomAccessIterator begin, void operator()(const _RAIter __begin,
const RandomAccessIterator end, Comparator& comp) const const _RAIter __end, _Compare& __comp) const
{ {
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(__begin, __end, __comp);
} }
}; };
template<bool stable, typename SeqRandomAccessIterator, template<bool __stable, typename Seq_RAIter,
typename RandomAccessIterator, typename Comparator, typename _RAIter, typename _Compare,
typename DiffType> typename DiffType>
struct possibly_stable_multiway_merge struct __possibly_stable_multiway_merge
{ {
}; };
template<typename SeqRandomAccessIterator, typename RandomAccessIterator, template<typename Seq_RAIter, typename _RAIter,
typename Comparator, typename DiffType> typename _Compare, typename DiffType>
struct possibly_stable_multiway_merge struct __possibly_stable_multiway_merge
<true, SeqRandomAccessIterator, RandomAccessIterator, Comparator, <true, Seq_RAIter, _RAIter, _Compare,
DiffType> DiffType>
{ {
void operator()(const SeqRandomAccessIterator& seqs_begin, void operator()(const Seq_RAIter& __seqs_begin,
const SeqRandomAccessIterator& seqs_end, const Seq_RAIter& __seqs_end,
const RandomAccessIterator& target, const _RAIter& __target,
Comparator& comp, _Compare& __comp,
DiffType length_am) const DiffType __length_am) const
{ {
stable_multiway_merge(seqs_begin, seqs_end, target, length_am, comp, stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp,
sequential_tag()); sequential_tag());
} }
}; };
template<typename SeqRandomAccessIterator, typename RandomAccessIterator, template<typename Seq_RAIter, typename _RAIter,
typename Comparator, typename DiffType> typename _Compare, typename DiffType>
struct possibly_stable_multiway_merge struct __possibly_stable_multiway_merge
<false, SeqRandomAccessIterator, RandomAccessIterator, Comparator, <false, Seq_RAIter, _RAIter, _Compare,
DiffType> DiffType>
{ {
void operator()(const SeqRandomAccessIterator& seqs_begin, void operator()(const Seq_RAIter& __seqs_begin,
const SeqRandomAccessIterator& seqs_end, const Seq_RAIter& __seqs_end,
const RandomAccessIterator& target, const _RAIter& __target,
Comparator& comp, _Compare& __comp,
DiffType length_am) const DiffType __length_am) const
{ {
multiway_merge(seqs_begin, seqs_end, target, length_am, comp, multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp,
sequential_tag()); sequential_tag());
} }
}; };
/** @brief PMWMS code executed by each thread. /** @brief PMWMS code executed by each thread.
* @param sd Pointer to algorithm data. * @param __sd Pointer to algorithm data.
* @param comp Comparator. * @param __comp Comparator.
*/ */
template<bool stable, bool exact, typename RandomAccessIterator, template<bool __stable, bool __exact, typename _RAIter,
typename Comparator> typename _Compare>
void void
parallel_sort_mwms_pu(PMWMSSortingData<RandomAccessIterator>* sd, parallel_sort_mwms_pu(_PMWMSSortingData<_RAIter>* __sd,
Comparator& comp) _Compare& __comp)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// Length of this thread's chunk, before merging. // Length of this thread's chunk, before merging.
difference_type length_local = sd->starts[iam + 1] - sd->starts[iam]; _DifferenceType __length_local = __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam];
// Sort in temporary storage, leave space for sentinel. // Sort in temporary storage, leave space for sentinel.
typedef value_type* SortingPlacesIterator; typedef _ValueType* _SortingPlacesIterator;
sd->temporary[iam] = __sd->_M_temporary[__iam] =
static_cast<value_type*>( static_cast<_ValueType*>(
::operator new(sizeof(value_type) * (length_local + 1))); ::operator new(sizeof(_ValueType) * (__length_local + 1)));
// Copy there. // Copy there.
std::uninitialized_copy(sd->source + sd->starts[iam], std::uninitialized_copy(__sd->_M_source + __sd->_M_starts[__iam],
sd->source + sd->starts[iam] + length_local, __sd->_M_source + __sd->_M_starts[__iam] + __length_local,
sd->temporary[iam]); __sd->_M_temporary[__iam]);
possibly_stable_sort<stable, SortingPlacesIterator, Comparator>() __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>()
(sd->temporary[iam], sd->temporary[iam] + length_local, comp); (__sd->_M_temporary[__iam], __sd->_M_temporary[__iam] + __length_local, __comp);
// Invariant: locally sorted subsequence in sd->temporary[iam], // Invariant: locally sorted subsequence in sd->_M_temporary[__iam],
// sd->temporary[iam] + length_local. // __sd->_M_temporary[__iam] + __length_local.
// No barrier here: Synchronization is done by the splitting routine. // No barrier here: Synchronization is done by the splitting routine.
difference_type num_samples = _DifferenceType __num_samples =
_Settings::get().sort_mwms_oversampling * sd->num_threads - 1; _Settings::get().sort_mwms_oversampling * __sd->__num_threads - 1;
split_consistently _SplitConsistently
<exact, RandomAccessIterator, Comparator, SortingPlacesIterator>() <__exact, _RAIter, _Compare, _SortingPlacesIterator>()
(iam, sd, comp, num_samples); (__iam, __sd, __comp, __num_samples);
// Offset from target begin, length after merging. // Offset from __target __begin, __length after merging.
difference_type offset = 0, length_am = 0; _DifferenceType __offset = 0, __length_am = 0;
for (thread_index_t s = 0; s < sd->num_threads; s++) for (_ThreadIndex __s = 0; __s < __sd->__num_threads; __s++)
{ {
length_am += sd->pieces[iam][s].end - sd->pieces[iam][s].begin; __length_am += __sd->_M_pieces[__iam][__s].__end - __sd->_M_pieces[__iam][__s].__begin;
offset += sd->pieces[iam][s].begin; __offset += __sd->_M_pieces[__iam][__s].__begin;
} }
typedef std::vector< typedef std::vector<
std::pair<SortingPlacesIterator, SortingPlacesIterator> > std::pair<_SortingPlacesIterator, _SortingPlacesIterator> >
seq_vector_type; seq_vector_type;
seq_vector_type seqs(sd->num_threads); seq_vector_type seqs(__sd->__num_threads);
for (int s = 0; s < sd->num_threads; ++s) for (int __s = 0; __s < __sd->__num_threads; ++__s)
{ {
seqs[s] = seqs[__s] =
std::make_pair(sd->temporary[s] + sd->pieces[iam][s].begin, std::make_pair(__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s].__begin,
sd->temporary[s] + sd->pieces[iam][s].end); __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s].__end);
} }
possibly_stable_multiway_merge< __possibly_stable_multiway_merge<
stable, __stable,
typename seq_vector_type::iterator, typename seq_vector_type::iterator,
RandomAccessIterator, _RAIter,
Comparator, difference_type>() _Compare, _DifferenceType>()
(seqs.begin(), seqs.end(), (seqs.begin(), seqs.end(),
sd->source + offset, comp, __sd->_M_source + __offset, __comp,
length_am); __length_am);
# pragma omp barrier # pragma omp barrier
::operator delete(sd->temporary[iam]); ::operator delete(__sd->_M_temporary[__iam]);
} }
/** @brief PMWMS main call. /** @brief PMWMS main call.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param comp Comparator. * @param __comp Comparator.
* @param n Length of sequence. * @param __n Length of sequence.
* @param num_threads Number of threads to use. * @param __num_threads Number of threads to use.
*/ */
template<bool stable, bool exact, typename RandomAccessIterator, template<bool __stable, bool __exact, typename _RAIter,
typename Comparator> typename _Compare>
void void
parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort_mwms(_RAIter __begin, _RAIter __end,
Comparator comp, _Compare __comp,
thread_index_t num_threads) _ThreadIndex __num_threads)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
if (n <= 1) if (__n <= 1)
return; return;
// at least one element per thread // at least one element per thread
if (num_threads > n) if (__num_threads > __n)
num_threads = static_cast<thread_index_t>(n); __num_threads = static_cast<_ThreadIndex>(__n);
// shared variables // shared variables
PMWMSSortingData<RandomAccessIterator> sd; _PMWMSSortingData<_RAIter> __sd;
difference_type* starts; _DifferenceType* _M_starts;
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
num_threads = omp_get_num_threads(); //no more threads than requested __num_threads = omp_get_num_threads(); //no more threads than requested
# pragma omp single # pragma omp single
{ {
sd.num_threads = num_threads; __sd.__num_threads = __num_threads;
sd.source = begin; __sd._M_source = __begin;
sd.temporary = new value_type*[num_threads]; __sd._M_temporary = new _ValueType*[__num_threads];
if (!exact) if (!__exact)
{ {
difference_type size = _DifferenceType size =
(_Settings::get().sort_mwms_oversampling * num_threads - 1) (_Settings::get().sort_mwms_oversampling * __num_threads - 1)
* num_threads; * __num_threads;
sd.samples = static_cast<value_type*>( __sd._M_samples = static_cast<_ValueType*>(
::operator new(size * sizeof(value_type))); ::operator new(size * sizeof(_ValueType)));
} }
else else
sd.samples = NULL; __sd._M_samples = NULL;
sd.offsets = new difference_type[num_threads - 1]; __sd._M_offsets = new _DifferenceType[__num_threads - 1];
sd.pieces = new std::vector<Piece<difference_type> >[num_threads]; __sd._M_pieces = new std::vector<_Piece<_DifferenceType> >[__num_threads];
for (int s = 0; s < num_threads; ++s) for (int __s = 0; __s < __num_threads; ++__s)
sd.pieces[s].resize(num_threads); __sd._M_pieces[__s].resize(__num_threads);
starts = sd.starts = new difference_type[num_threads + 1]; _M_starts = __sd._M_starts = new _DifferenceType[__num_threads + 1];
difference_type chunk_length = n / num_threads; _DifferenceType __chunk_length = __n / __num_threads;
difference_type split = n % num_threads; _DifferenceType __split = __n % __num_threads;
difference_type pos = 0; _DifferenceType __pos = 0;
for (int i = 0; i < num_threads; ++i) for (int __i = 0; __i < __num_threads; ++__i)
{ {
starts[i] = pos; _M_starts[__i] = __pos;
pos += (i < split) ? (chunk_length + 1) : chunk_length; __pos += (__i < __split) ? (__chunk_length + 1) : __chunk_length;
} }
starts[num_threads] = pos; _M_starts[__num_threads] = __pos;
} //single } //single
// Now sort in parallel. // Now sort in parallel.
parallel_sort_mwms_pu<stable, exact>(&sd, comp); parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp);
} //parallel } //parallel
delete[] starts; delete[] _M_starts;
delete[] sd.temporary; delete[] __sd._M_temporary;
if (!exact) if (!__exact)
::operator delete(sd.samples); ::operator delete(__sd._M_samples);
delete[] sd.offsets; delete[] __sd._M_offsets;
delete[] sd.pieces; delete[] __sd._M_pieces;
} }
} //namespace __gnu_parallel } //namespace __gnu_parallel
......
...@@ -51,448 +51,448 @@ namespace std ...@@ -51,448 +51,448 @@ namespace std
namespace __parallel namespace __parallel
{ {
// Sequential fallback. // Sequential fallback.
template<typename InputIterator, typename T> template<typename _IIter, typename _Tp>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init, accumulate(_IIter __begin, _IIter __end, _Tp __init,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::accumulate(begin, end, init); } { return _GLIBCXX_STD_P::accumulate(__begin, __end, __init); }
template<typename InputIterator, typename T, typename BinaryOperation> template<typename _IIter, typename _Tp, typename _BinaryOperation>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init, accumulate(_IIter __begin, _IIter __end, _Tp __init,
BinaryOperation binary_op, __gnu_parallel::sequential_tag) _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); } { return _GLIBCXX_STD_P::accumulate(__begin, __end, __init, __binary_op); }
// Sequential fallback for input iterator case. // Sequential fallback for input iterator case.
template<typename InputIterator, typename T, typename IteratorTag> template<typename _IIter, typename _Tp, typename _IteratorTag>
inline T inline _Tp
accumulate_switch(InputIterator begin, InputIterator end, __accumulate_switch(_IIter __begin, _IIter __end,
T init, IteratorTag) _Tp __init, _IteratorTag)
{ return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); } { return accumulate(__begin, __end, __init, __gnu_parallel::sequential_tag()); }
template<typename InputIterator, typename T, typename BinaryOperation, template<typename _IIter, typename _Tp, typename _BinaryOperation,
typename IteratorTag> typename _IteratorTag>
inline T inline _Tp
accumulate_switch(InputIterator begin, InputIterator end, T init, __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init,
BinaryOperation binary_op, IteratorTag) _BinaryOperation __binary_op, _IteratorTag)
{ return accumulate(begin, end, init, binary_op, { return accumulate(__begin, __end, __init, __binary_op,
__gnu_parallel::sequential_tag()); } __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators. // Parallel algorithm for random access iterators.
template<typename _RandomAccessIterator, typename T, template<typename __RAIter, typename _Tp,
typename BinaryOperation> typename _BinaryOperation>
T _Tp
accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end, __accumulate_switch(__RAIter __begin, __RAIter __end,
T init, BinaryOperation binary_op, _Tp __init, _BinaryOperation __binary_op,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism_tag __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_unbalanced) = __gnu_parallel::parallel_unbalanced)
{ {
if (_GLIBCXX_PARALLEL_CONDITION( if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::sequence_index_t>(end - begin) static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().accumulate_minimal_n >= __gnu_parallel::_Settings::get().accumulate_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag))) && __gnu_parallel::__is_parallel(__parallelism_tag)))
{ {
T res = init; _Tp __res = __init;
__gnu_parallel::accumulate_selector<_RandomAccessIterator> __gnu_parallel::__accumulate_selector<__RAIter>
my_selector; __my_selector;
__gnu_parallel:: __gnu_parallel::
for_each_template_random_access_ed(begin, end, for_each_template_random_access_ed(__begin, __end,
__gnu_parallel::nothing(), __gnu_parallel::_Nothing(),
my_selector, __my_selector,
__gnu_parallel:: __gnu_parallel::
accumulate_binop_reduct __accumulate_binop_reduct
<BinaryOperation>(binary_op), <_BinaryOperation>(__binary_op),
res, res, -1); __res, __res, -1);
return res; return __res;
} }
else else
return accumulate(begin, end, init, binary_op, return accumulate(__begin, __end, __init, __binary_op,
__gnu_parallel::sequential_tag()); __gnu_parallel::sequential_tag());
} }
// Public interface. // Public interface.
template<typename InputIterator, typename T> template<typename _IIter, typename _Tp>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init, accumulate(_IIter __begin, _IIter __end, _Tp __init,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef std::iterator_traits<InputIterator> iterator_traits; typedef std::iterator_traits<_IIter> _IteratorTraits;
typedef typename iterator_traits::value_type value_type; typedef typename _IteratorTraits::value_type _ValueType;
typedef typename iterator_traits::iterator_category iterator_category; typedef typename _IteratorTraits::iterator_category _IteratorCategory;
return accumulate_switch(begin, end, init, return __accumulate_switch(__begin, __end, __init,
__gnu_parallel::plus<T, value_type>(), __gnu_parallel::_Plus<_Tp, _ValueType>(),
iterator_category(), parallelism_tag); _IteratorCategory(), __parallelism_tag);
} }
template<typename InputIterator, typename T> template<typename _IIter, typename _Tp>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init) accumulate(_IIter __begin, _IIter __end, _Tp __init)
{ {
typedef std::iterator_traits<InputIterator> iterator_traits; typedef std::iterator_traits<_IIter> _IteratorTraits;
typedef typename iterator_traits::value_type value_type; typedef typename _IteratorTraits::value_type _ValueType;
typedef typename iterator_traits::iterator_category iterator_category; typedef typename _IteratorTraits::iterator_category _IteratorCategory;
return accumulate_switch(begin, end, init, return __accumulate_switch(__begin, __end, __init,
__gnu_parallel::plus<T, value_type>(), __gnu_parallel::_Plus<_Tp, _ValueType>(),
iterator_category()); _IteratorCategory());
} }
template<typename InputIterator, typename T, typename BinaryOperation> template<typename _IIter, typename _Tp, typename _BinaryOperation>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init, accumulate(_IIter __begin, _IIter __end, _Tp __init,
BinaryOperation binary_op, _BinaryOperation __binary_op,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef iterator_traits<InputIterator> iterator_traits; typedef iterator_traits<_IIter> _IteratorTraits;
typedef typename iterator_traits::iterator_category iterator_category; typedef typename _IteratorTraits::iterator_category _IteratorCategory;
return accumulate_switch(begin, end, init, binary_op, return __accumulate_switch(__begin, __end, __init, __binary_op,
iterator_category(), parallelism_tag); _IteratorCategory(), __parallelism_tag);
} }
template<typename InputIterator, typename T, typename BinaryOperation> template<typename _IIter, typename _Tp, typename _BinaryOperation>
inline T inline _Tp
accumulate(InputIterator begin, InputIterator end, T init, accumulate(_IIter __begin, _IIter __end, _Tp __init,
BinaryOperation binary_op) _BinaryOperation __binary_op)
{ {
typedef iterator_traits<InputIterator> iterator_traits; typedef iterator_traits<_IIter> _IteratorTraits;
typedef typename iterator_traits::iterator_category iterator_category; typedef typename _IteratorTraits::iterator_category _IteratorCategory;
return accumulate_switch(begin, end, init, binary_op, return __accumulate_switch(__begin, __end, __init, __binary_op,
iterator_category()); _IteratorCategory());
} }
// Sequential fallback. // Sequential fallback.
template<typename InputIterator1, typename InputIterator2, typename T> template<typename _IIter1, typename _IIter2, typename _Tp>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, _IIter2 __first2, _Tp __init,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); } { return _GLIBCXX_STD_P::inner_product(__first1, __last1, __first2, __init); }
template<typename InputIterator1, typename InputIterator2, typename T, template<typename _IIter1, typename _IIter2, typename _Tp,
typename BinaryFunction1, typename BinaryFunction2> typename BinaryFunction1, typename BinaryFunction2>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, BinaryFunction1 binary_op1, _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag) BinaryFunction2 __binary_op2, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init, { return _GLIBCXX_STD_P::inner_product(__first1, __last1, __first2, __init,
binary_op1, binary_op2); } __binary_op1, __binary_op2); }
// Parallel algorithm for random access iterators. // Parallel algorithm for random access iterators.
template<typename RandomAccessIterator1, typename RandomAccessIterator2, template<typename _RAIter1, typename _RAIter2,
typename T, typename BinaryFunction1, typename BinaryFunction2> typename _Tp, typename BinaryFunction1, typename BinaryFunction2>
T _Tp
inner_product_switch(RandomAccessIterator1 first1, __inner_product_switch(_RAIter1 __first1,
RandomAccessIterator1 last1, _RAIter1 __last1,
RandomAccessIterator2 first2, T init, _RAIter2 __first2, _Tp __init,
BinaryFunction1 binary_op1, BinaryFunction1 __binary_op1,
BinaryFunction2 binary_op2, BinaryFunction2 __binary_op2,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism_tag __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_unbalanced) = __gnu_parallel::parallel_unbalanced)
{ {
if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1)
>= __gnu_parallel::_Settings::get(). >= __gnu_parallel::_Settings::get().
accumulate_minimal_n accumulate_minimal_n
&& __gnu_parallel:: && __gnu_parallel::
is_parallel(parallelism_tag))) __is_parallel(__parallelism_tag)))
{ {
T res = init; _Tp __res = __init;
__gnu_parallel:: __gnu_parallel::
inner_product_selector<RandomAccessIterator1, __inner_product_selector<_RAIter1,
RandomAccessIterator2, T> my_selector(first1, first2); _RAIter2, _Tp> __my_selector(__first1, __first2);
__gnu_parallel:: __gnu_parallel::
for_each_template_random_access_ed(first1, last1, binary_op2, for_each_template_random_access_ed(__first1, __last1, __binary_op2,
my_selector, binary_op1, __my_selector, __binary_op1,
res, res, -1); __res, __res, -1);
return res; return __res;
} }
else else
return inner_product(first1, last1, first2, init, return inner_product(__first1, __last1, __first2, __init,
__gnu_parallel::sequential_tag()); __gnu_parallel::sequential_tag());
} }
// No parallelism for input iterators. // No parallelism for input iterators.
template<typename InputIterator1, typename InputIterator2, typename T, template<typename _IIter1, typename _IIter2, typename _Tp,
typename BinaryFunction1, typename BinaryFunction2, typename BinaryFunction1, typename BinaryFunction2,
typename IteratorTag1, typename IteratorTag2> typename _IteratorTag1, typename _IteratorTag2>
inline T inline _Tp
inner_product_switch(InputIterator1 first1, InputIterator1 last1, __inner_product_switch(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, _IIter2 __first2, _Tp __init,
BinaryFunction1 binary_op1, BinaryFunction1 __binary_op1,
BinaryFunction2 binary_op2, BinaryFunction2 __binary_op2,
IteratorTag1, IteratorTag2) _IteratorTag1, _IteratorTag2)
{ return inner_product(first1, last1, first2, init, { return inner_product(__first1, __last1, __first2, __init,
binary_op1, binary_op2, __binary_op1, __binary_op2,
__gnu_parallel::sequential_tag()); } __gnu_parallel::sequential_tag()); }
template<typename InputIterator1, typename InputIterator2, typename T, template<typename _IIter1, typename _IIter2, typename _Tp,
typename BinaryFunction1, typename BinaryFunction2> typename BinaryFunction1, typename BinaryFunction2>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, BinaryFunction1 binary_op1, _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
BinaryFunction2 binary_op2, BinaryFunction2 __binary_op2,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef iterator_traits<InputIterator1> traits1_type; typedef iterator_traits<_IIter1> _TraitsType1;
typedef typename traits1_type::iterator_category iterator1_category; typedef typename _TraitsType1::iterator_category _IteratorCategory1;
typedef iterator_traits<InputIterator2> traits2_type; typedef iterator_traits<_IIter2> _TraitsType2;
typedef typename traits2_type::iterator_category iterator2_category; typedef typename _TraitsType2::iterator_category _IteratorCategory2;
return inner_product_switch(first1, last1, first2, init, binary_op1, return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1,
binary_op2, iterator1_category(), __binary_op2, _IteratorCategory1(),
iterator2_category(), parallelism_tag); _IteratorCategory2(), __parallelism_tag);
} }
template<typename InputIterator1, typename InputIterator2, typename T, template<typename _IIter1, typename _IIter2, typename _Tp,
typename BinaryFunction1, typename BinaryFunction2> typename BinaryFunction1, typename BinaryFunction2>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, BinaryFunction1 binary_op1, _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
BinaryFunction2 binary_op2) BinaryFunction2 __binary_op2)
{ {
typedef iterator_traits<InputIterator1> traits1_type; typedef iterator_traits<_IIter1> _TraitsType1;
typedef typename traits1_type::iterator_category iterator1_category; typedef typename _TraitsType1::iterator_category _IteratorCategory1;
typedef iterator_traits<InputIterator2> traits2_type; typedef iterator_traits<_IIter2> _TraitsType2;
typedef typename traits2_type::iterator_category iterator2_category; typedef typename _TraitsType2::iterator_category _IteratorCategory2;
return inner_product_switch(first1, last1, first2, init, binary_op1, return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1,
binary_op2, iterator1_category(), __binary_op2, _IteratorCategory1(),
iterator2_category()); _IteratorCategory2());
} }
template<typename InputIterator1, typename InputIterator2, typename T> template<typename _IIter1, typename _IIter2, typename _Tp>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init, _IIter2 __first2, _Tp __init,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef iterator_traits<InputIterator1> traits_type1; typedef iterator_traits<_IIter1> traits_type1;
typedef typename traits_type1::value_type value_type1; typedef typename traits_type1::value_type value_type1;
typedef iterator_traits<InputIterator2> traits_type2; typedef iterator_traits<_IIter2> traits_type2;
typedef typename traits_type2::value_type value_type2; typedef typename traits_type2::value_type value_type2;
typedef typename typedef typename
__gnu_parallel::multiplies<value_type1, value_type2>::result __gnu_parallel::_Multiplies<value_type1, value_type2>::__result
multiplies_result_type; _MultipliesResultType;
return inner_product(first1, last1, first2, init, return inner_product(__first1, __last1, __first2, __init,
__gnu_parallel::plus<T, multiplies_result_type>(), __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(),
__gnu_parallel:: __gnu_parallel::
multiplies<value_type1, value_type2>(), _Multiplies<value_type1, value_type2>(),
parallelism_tag); __parallelism_tag);
} }
template<typename InputIterator1, typename InputIterator2, typename T> template<typename _IIter1, typename _IIter2, typename _Tp>
inline T inline _Tp
inner_product(InputIterator1 first1, InputIterator1 last1, inner_product(_IIter1 __first1, _IIter1 __last1,
InputIterator2 first2, T init) _IIter2 __first2, _Tp __init)
{ {
typedef iterator_traits<InputIterator1> traits_type1; typedef iterator_traits<_IIter1> traits_type1;
typedef typename traits_type1::value_type value_type1; typedef typename traits_type1::value_type value_type1;
typedef iterator_traits<InputIterator2> traits_type2; typedef iterator_traits<_IIter2> traits_type2;
typedef typename traits_type2::value_type value_type2; typedef typename traits_type2::value_type value_type2;
typedef typename typedef typename
__gnu_parallel::multiplies<value_type1, value_type2>::result __gnu_parallel::_Multiplies<value_type1, value_type2>::__result
multiplies_result_type; _MultipliesResultType;
return inner_product(first1, last1, first2, init, return inner_product(__first1, __last1, __first2, __init,
__gnu_parallel::plus<T, multiplies_result_type>(), __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(),
__gnu_parallel:: __gnu_parallel::
multiplies<value_type1, value_type2>()); _Multiplies<value_type1, value_type2>());
} }
// Sequential fallback. // Sequential fallback.
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
inline OutputIterator inline _OutputIterator
partial_sum(InputIterator begin, InputIterator end, OutputIterator result, partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result); } { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result); }
// Sequential fallback. // Sequential fallback.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
inline OutputIterator inline _OutputIterator
partial_sum(InputIterator begin, InputIterator end, OutputIterator result, partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
BinaryOperation bin_op, __gnu_parallel::sequential_tag) _BinaryOperation __bin_op, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); } { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result, __bin_op); }
// Sequential fallback for input iterator case. // Sequential fallback for input iterator case.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation, typename IteratorTag1, typename _BinaryOperation, typename _IteratorTag1,
typename IteratorTag2> typename _IteratorTag2>
inline OutputIterator inline _OutputIterator
partial_sum_switch(InputIterator begin, InputIterator end, __partial_sum_switch(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
IteratorTag1, IteratorTag2) _IteratorTag1, _IteratorTag2)
{ return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); } { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result, __bin_op); }
// Parallel algorithm for random access iterators. // Parallel algorithm for random access iterators.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
OutputIterator _OutputIterator
partial_sum_switch(InputIterator begin, InputIterator end, __partial_sum_switch(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
random_access_iterator_tag, random_access_iterator_tag) random_access_iterator_tag, random_access_iterator_tag)
{ {
if (_GLIBCXX_PARALLEL_CONDITION( if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::sequence_index_t>(end - begin) static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().partial_sum_minimal_n)) >= __gnu_parallel::_Settings::get().partial_sum_minimal_n))
return __gnu_parallel::parallel_partial_sum(begin, end, return __gnu_parallel::__parallel_partial_sum(__begin, __end,
result, bin_op); __result, __bin_op);
else else
return partial_sum(begin, end, result, bin_op, return partial_sum(__begin, __end, __result, __bin_op,
__gnu_parallel::sequential_tag()); __gnu_parallel::sequential_tag());
} }
// Public interface. // Public interface.
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
inline OutputIterator inline _OutputIterator
partial_sum(InputIterator begin, InputIterator end, OutputIterator result) partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result)
{ {
typedef typename iterator_traits<InputIterator>::value_type value_type; typedef typename iterator_traits<_IIter>::value_type _ValueType;
return partial_sum(begin, end, result, std::plus<value_type>()); return partial_sum(__begin, __end, __result, std::plus<_ValueType>());
} }
// Public interface // Public interface
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
inline OutputIterator inline _OutputIterator
partial_sum(InputIterator begin, InputIterator end, OutputIterator result, partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
BinaryOperation binary_op) _BinaryOperation __binary_op)
{ {
typedef iterator_traits<InputIterator> traitsi_type; typedef iterator_traits<_IIter> traitsi_type;
typedef typename traitsi_type::iterator_category iteratori_category; typedef typename traitsi_type::iterator_category _IIteratorCategory;
typedef iterator_traits<OutputIterator> traitso_type; typedef iterator_traits<_OutputIterator> _OTraitsType;
typedef typename traitso_type::iterator_category iteratoro_category; typedef typename _OTraitsType::iterator_category _OIterCategory;
return partial_sum_switch(begin, end, result, binary_op, return __partial_sum_switch(__begin, __end, __result, __binary_op,
iteratori_category(), iteratoro_category()); _IIteratorCategory(), _OIterCategory());
} }
// Sequential fallback. // Sequential fallback.
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result, __gnu_parallel::sequential_tag) _OutputIterator __result, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); } { return _GLIBCXX_STD_P::adjacent_difference(__begin, __end, __result); }
// Sequential fallback. // Sequential fallback.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); } { return _GLIBCXX_STD_P::adjacent_difference(__begin, __end, __result, __bin_op); }
// Sequential fallback for input iterator case. // Sequential fallback for input iterator case.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation, typename IteratorTag1, typename _BinaryOperation, typename _IteratorTag1,
typename IteratorTag2> typename _IteratorTag2>
inline OutputIterator inline _OutputIterator
adjacent_difference_switch(InputIterator begin, InputIterator end, __adjacent_difference_switch(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
IteratorTag1, IteratorTag2) _IteratorTag1, _IteratorTag2)
{ return adjacent_difference(begin, end, result, bin_op, { return adjacent_difference(__begin, __end, __result, __bin_op,
__gnu_parallel::sequential_tag()); } __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators. // Parallel algorithm for random access iterators.
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
OutputIterator _OutputIterator
adjacent_difference_switch(InputIterator begin, InputIterator end, __adjacent_difference_switch(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism_tag __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced) = __gnu_parallel::parallel_balanced)
{ {
if (_GLIBCXX_PARALLEL_CONDITION( if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::sequence_index_t>(end - begin) static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag))) && __gnu_parallel::__is_parallel(__parallelism_tag)))
{ {
bool dummy = true; bool __dummy = true;
typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator, typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator,
random_access_iterator_tag> ip; random_access_iterator_tag> _ItTrip;
*result = *begin; *__result = *__begin;
ip begin_pair(begin + 1, result + 1), _ItTrip begin_pair(__begin + 1, __result + 1),
end_pair(end, result + (end - begin)); end_pair(__end, __result + (__end - __begin));
__gnu_parallel::adjacent_difference_selector<ip> functionality; __gnu_parallel::__adjacent_difference_selector<_ItTrip> __functionality;
__gnu_parallel:: __gnu_parallel::
for_each_template_random_access_ed(begin_pair, end_pair, bin_op, for_each_template_random_access_ed(begin_pair, end_pair, __bin_op,
functionality, __functionality,
__gnu_parallel::dummy_reduct(), __gnu_parallel::_DummyReduct(),
dummy, dummy, -1); __dummy, __dummy, -1);
return functionality.finish_iterator; return __functionality.finish_iterator;
} }
else else
return adjacent_difference(begin, end, result, bin_op, return adjacent_difference(__begin, __end, __result, __bin_op,
__gnu_parallel::sequential_tag()); __gnu_parallel::sequential_tag());
} }
// Public interface. // Public interface.
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result, _OutputIterator __result,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef iterator_traits<InputIterator> traits_type; typedef iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
return adjacent_difference(begin, end, result, std::minus<value_type>(), return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>(),
parallelism_tag); __parallelism_tag);
} }
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result) _OutputIterator __result)
{ {
typedef iterator_traits<InputIterator> traits_type; typedef iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
return adjacent_difference(begin, end, result, std::minus<value_type>()); return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>());
} }
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation binary_op, _OutputIterator __result, _BinaryOperation __binary_op,
__gnu_parallel::_Parallelism parallelism_tag) __gnu_parallel::_Parallelism __parallelism_tag)
{ {
typedef iterator_traits<InputIterator> traitsi_type; typedef iterator_traits<_IIter> traitsi_type;
typedef typename traitsi_type::iterator_category iteratori_category; typedef typename traitsi_type::iterator_category _IIteratorCategory;
typedef iterator_traits<OutputIterator> traitso_type; typedef iterator_traits<_OutputIterator> _OTraitsType;
typedef typename traitso_type::iterator_category iteratoro_category; typedef typename _OTraitsType::iterator_category _OIterCategory;
return adjacent_difference_switch(begin, end, result, binary_op, return __adjacent_difference_switch(__begin, __end, __result, __binary_op,
iteratori_category(), _IIteratorCategory(),
iteratoro_category(), parallelism_tag); _OIterCategory(), __parallelism_tag);
} }
template<typename InputIterator, typename OutputIterator, template<typename _IIter, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
inline OutputIterator inline _OutputIterator
adjacent_difference(InputIterator begin, InputIterator end, adjacent_difference(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation binary_op) _OutputIterator __result, _BinaryOperation __binary_op)
{ {
typedef iterator_traits<InputIterator> traitsi_type; typedef iterator_traits<_IIter> traitsi_type;
typedef typename traitsi_type::iterator_category iteratori_category; typedef typename traitsi_type::iterator_category _IIteratorCategory;
typedef iterator_traits<OutputIterator> traitso_type; typedef iterator_traits<_OutputIterator> _OTraitsType;
typedef typename traitso_type::iterator_category iteratoro_category; typedef typename _OTraitsType::iterator_category _OIterCategory;
return adjacent_difference_switch(begin, end, result, binary_op, return __adjacent_difference_switch(__begin, __end, __result, __binary_op,
iteratori_category(), _IIteratorCategory(),
iteratoro_category()); _OIterCategory());
} }
} // end namespace } // end namespace
} // end namespace } // end namespace
......
...@@ -52,7 +52,7 @@ namespace __parallel ...@@ -52,7 +52,7 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _Tag> template<typename _IIter, typename _Tp, typename _Tag>
_Tp _Tp
accumulate_switch(_IIter, _IIter, _Tp, _Tag); __accumulate_switch(_IIter, _IIter, _Tp, _Tag);
template<typename _IIter, typename _Tp, typename _BinaryOper> template<typename _IIter, typename _Tp, typename _BinaryOper>
_Tp _Tp
...@@ -71,13 +71,13 @@ namespace __parallel ...@@ -71,13 +71,13 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _BinaryOper, template<typename _IIter, typename _Tp, typename _BinaryOper,
typename _Tag> typename _Tag>
_Tp _Tp
accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag); __accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag);
template<typename _RAIter, typename _Tp, typename _BinaryOper> template<typename _RAIter, typename _Tp, typename _BinaryOper>
_Tp _Tp
accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper, __accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_unbalanced); = __gnu_parallel::parallel_unbalanced);
template<typename _IIter, typename _OIter> template<typename _IIter, typename _OIter>
...@@ -111,15 +111,15 @@ namespace __parallel ...@@ -111,15 +111,15 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _BinaryOper, template<typename _IIter, typename _OIter, typename _BinaryOper,
typename _Tag1, typename _Tag2> typename _Tag1, typename _Tag2>
_OIter _OIter
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
_Tag1, _Tag2); _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper> template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter _OIter
adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism parallelism __gnu_parallel::_Parallelism __parallelism
= __gnu_parallel::parallel_unbalanced); = __gnu_parallel::parallel_unbalanced);
template<typename _IIter1, typename _IIter2, typename _Tp> template<typename _IIter1, typename _IIter2, typename _Tp>
...@@ -157,7 +157,7 @@ namespace __parallel ...@@ -157,7 +157,7 @@ namespace __parallel
template<typename _RAIter1, typename _RAIter2, typename _Tp, template<typename _RAIter1, typename _RAIter2, typename _Tp,
typename BinaryFunction1, typename BinaryFunction2> typename BinaryFunction1, typename BinaryFunction2>
_Tp _Tp
inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1, __inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1,
BinaryFunction2, random_access_iterator_tag, BinaryFunction2, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism __gnu_parallel::_Parallelism
...@@ -167,7 +167,7 @@ namespace __parallel ...@@ -167,7 +167,7 @@ namespace __parallel
typename _BinaryFunction1, typename _BinaryFunction2, typename _BinaryFunction1, typename _BinaryFunction2,
typename _Tag1, typename _Tag2> typename _Tag1, typename _Tag2>
_Tp _Tp
inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, __inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
_BinaryFunction2, _Tag1, _Tag2); _BinaryFunction2, _Tag1, _Tag2);
...@@ -182,7 +182,7 @@ namespace __parallel ...@@ -182,7 +182,7 @@ namespace __parallel
template<typename _IIter, typename _OIter> template<typename _IIter, typename _OIter>
_OIter _OIter
partial_sum(_IIter, _IIter, _OIter result); partial_sum(_IIter, _IIter, _OIter __result);
template<typename _IIter, typename _OIter, typename _BinaryOper> template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter _OIter
...@@ -191,11 +191,11 @@ namespace __parallel ...@@ -191,11 +191,11 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _BinaryOper, template<typename _IIter, typename _OIter, typename _BinaryOper,
typename _Tag1, typename _Tag2> typename _Tag1, typename _Tag2>
_OIter _OIter
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper> template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter _OIter
partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper,
random_access_iterator_tag, random_access_iterator_tag); random_access_iterator_tag, random_access_iterator_tag);
} // end namespace } // end namespace
} // end namespace } // end namespace
......
...@@ -44,73 +44,73 @@ namespace __gnu_parallel ...@@ -44,73 +44,73 @@ namespace __gnu_parallel
/** @brief Embarrassingly parallel algorithm for random access /** @brief Embarrassingly parallel algorithm for random access
* iterators, using an OpenMP for loop. * iterators, using an OpenMP for loop.
* *
* @param begin Begin iterator of element sequence. * @param __begin Begin iterator of element __sequence.
* @param end End iterator of element sequence. * @param __end End iterator of element __sequence.
* @param o User-supplied functor (comparator, predicate, adding * @param __o User-supplied functor (comparator, predicate, adding
* functor, etc.). * functor, etc.).
* @param f Functor to "process" an element with op (depends on * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...). * desired functionality, e. g. for std::for_each(), ...).
* @param r Functor to "add" a single result to the already * @param __r Functor to "add" a single __result to the already
* processed elements (depends on functionality). * processed __elements (depends on functionality).
* @param base Base value for reduction. * @param __base Base value for reduction.
* @param output Pointer to position where final result is written to * @param __output Pointer to position where final result is written to
* @param bound Maximum number of elements processed (e. g. for * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()). * std::count_n()).
* @return User-supplied functor (that may contain a part of the result). * @return User-supplied functor (that may contain a part of the result).
*/ */
template<typename RandomAccessIterator, template<typename _RAIter,
typename Op, typename _Op,
typename Fu, typename _Fu,
typename Red, typename _Red,
typename Result> typename _Result>
Op _Op
for_each_template_random_access_omp_loop(RandomAccessIterator begin, for_each_template_random_access_omp_loop(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Op o, Fu& f, Red r, Result base, _Op __o, _Fu& __f, _Red __r, _Result __base,
Result& output, _Result& __output,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>:: <_RAIter>::
difference_type bound) difference_type __bound)
{ {
typedef typename typedef typename
std::iterator_traits<RandomAccessIterator>::difference_type std::iterator_traits<_RAIter>::difference_type
difference_type; _DifferenceType;
difference_type length = end - begin; _DifferenceType __length = __end - __begin;
thread_index_t num_threads = _ThreadIndex __num_threads =
__gnu_parallel::min<difference_type>(get_max_threads(), length); __gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length);
Result *thread_results; _Result *__thread_results;
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
thread_results = new Result[num_threads]; __thread_results = new _Result[__num_threads];
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
thread_results[i] = Result(); __thread_results[__i] = _Result();
} }
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
# pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size) # pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size)
for (difference_type pos = 0; pos < length; ++pos) for (_DifferenceType __pos = 0; __pos < __length; ++__pos)
thread_results[iam] = __thread_results[__iam] =
r(thread_results[iam], f(o, begin+pos)); __r(__thread_results[__iam], __f(__o, __begin+__pos));
} //parallel } //parallel
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
output = r(output, thread_results[i]); __output = __r(__output, __thread_results[__i]);
delete [] thread_results; delete [] __thread_results;
// Points to last element processed (needed as return value for // Points to last element processed (needed as return value for
// some algorithms like transform). // some algorithms like transform).
f.finish_iterator = begin + length; __f.finish_iterator = __begin + __length;
return o; return __o;
} }
} // end namespace } // end namespace
......
...@@ -44,72 +44,72 @@ namespace __gnu_parallel ...@@ -44,72 +44,72 @@ namespace __gnu_parallel
/** @brief Embarrassingly parallel algorithm for random access /** @brief Embarrassingly parallel algorithm for random access
* iterators, using an OpenMP for loop with static scheduling. * iterators, using an OpenMP for loop with static scheduling.
* *
* @param begin Begin iterator of element sequence. * @param __begin Begin iterator of element __sequence.
* @param end End iterator of element sequence. * @param __end End iterator of element __sequence.
* @param o User-supplied functor (comparator, predicate, adding * @param __o User-supplied functor (comparator, predicate, adding
* functor, ...). * functor, ...).
* @param f Functor to "process" an element with op (depends on * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...). * desired functionality, e. g. for std::for_each(), ...).
* @param r Functor to "add" a single result to the already processed * @param __r Functor to "add" a single __result to the already processed
* elements (depends on functionality). * __elements (depends on functionality).
* @param base Base value for reduction. * @param __base Base value for reduction.
* @param output Pointer to position where final result is written to * @param __output Pointer to position where final result is written to
* @param bound Maximum number of elements processed (e. g. for * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()). * std::count_n()).
* @return User-supplied functor (that may contain a part of the result). * @return User-supplied functor (that may contain a part of the result).
*/ */
template<typename RandomAccessIterator, template<typename _RAIter,
typename Op, typename _Op,
typename Fu, typename _Fu,
typename Red, typename _Red,
typename Result> typename _Result>
Op _Op
for_each_template_random_access_omp_loop_static(RandomAccessIterator begin, for_each_template_random_access_omp_loop_static(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Op o, Fu& f, Red r, _Op __o, _Fu& __f, _Red __r,
Result base, Result& output, _Result __base, _Result& __output,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>:: <_RAIter>::
difference_type bound) difference_type __bound)
{ {
typedef typename typedef typename
std::iterator_traits<RandomAccessIterator>::difference_type std::iterator_traits<_RAIter>::difference_type
difference_type; _DifferenceType;
difference_type length = end - begin; _DifferenceType __length = __end - __begin;
thread_index_t num_threads = _ThreadIndex __num_threads =
std::min<difference_type>(get_max_threads(), length); std::min<_DifferenceType>(__get_max_threads(), __length);
Result *thread_results; _Result *__thread_results;
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
thread_results = new Result[num_threads]; __thread_results = new _Result[__num_threads];
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
thread_results[i] = Result(); __thread_results[__i] = _Result();
} }
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
# pragma omp for schedule(static, _Settings::get().workstealing_chunk_size) # pragma omp for schedule(static, _Settings::get().workstealing_chunk_size)
for (difference_type pos = 0; pos < length; ++pos) for (_DifferenceType __pos = 0; __pos < __length; ++__pos)
thread_results[iam] = r(thread_results[iam], f(o, begin+pos)); __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos));
} //parallel } //parallel
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
output = r(output, thread_results[i]); __output = __r(__output, __thread_results[__i]);
delete [] thread_results; delete [] __thread_results;
// Points to last element processed (needed as return value for // Points to last element processed (needed as return value for
// some algorithms like transform). // some algorithms like transform).
f.finish_iterator = begin + length; __f.finish_iterator = __begin + __length;
return o; return __o;
} }
} // end namespace } // end namespace
......
...@@ -45,89 +45,89 @@ namespace __gnu_parallel ...@@ -45,89 +45,89 @@ namespace __gnu_parallel
* iterators, using hand-crafted parallelization by equal splitting * iterators, using hand-crafted parallelization by equal splitting
* the work. * the work.
* *
* @param begin Begin iterator of element sequence. * @param __begin Begin iterator of element __sequence.
* @param end End iterator of element sequence. * @param __end End iterator of element __sequence.
* @param o User-supplied functor (comparator, predicate, adding * @param __o User-supplied functor (comparator, predicate, adding
* functor, ...) * functor, ...)
* @param f Functor to "process" an element with op (depends on * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...). * desired functionality, e. g. for std::for_each(), ...).
* @param r Functor to "add" a single result to the already * @param __r Functor to "add" a single __result to the already
* processed elements (depends on functionality). * processed __elements (depends on functionality).
* @param base Base value for reduction. * @param __base Base value for reduction.
* @param output Pointer to position where final result is written to * @param __output Pointer to position where final result is written to
* @param bound Maximum number of elements processed (e. g. for * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()). * std::count_n()).
* @return User-supplied functor (that may contain a part of the result). * @return User-supplied functor (that may contain a part of the result).
*/ */
template<typename RandomAccessIterator, template<typename _RAIter,
typename Op, typename _Op,
typename Fu, typename _Fu,
typename Red, typename _Red,
typename Result> typename _Result>
Op _Op
for_each_template_random_access_ed(RandomAccessIterator begin, for_each_template_random_access_ed(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Op o, Fu& f, Red r, Result base, _Op __o, _Fu& __f, _Red __r, _Result __base,
Result& output, _Result& __output,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>:: <_RAIter>::
difference_type bound) difference_type __bound)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
const difference_type length = end - begin; const _DifferenceType __length = __end - __begin;
Result *thread_results; _Result *__thread_results;
bool* constructed; bool* __constructed;
thread_index_t num_threads = _ThreadIndex __num_threads =
__gnu_parallel::min<difference_type>(get_max_threads(), length); __gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length);
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
thread_results = static_cast<Result*>( __thread_results = static_cast<_Result*>(
::operator new(num_threads * sizeof(Result))); ::operator new(__num_threads * sizeof(_Result)));
constructed = new bool[num_threads]; __constructed = new bool[__num_threads];
} }
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// Neutral element. // Neutral element.
Result* reduct = static_cast<Result*>(::operator new(sizeof(Result))); _Result* __reduct = static_cast<_Result*>(::operator new(sizeof(_Result)));
difference_type _DifferenceType
start = equally_split_point(length, num_threads, iam), __start = equally_split_point(__length, __num_threads, __iam),
stop = equally_split_point(length, num_threads, iam + 1); __stop = equally_split_point(__length, __num_threads, __iam + 1);
if (start < stop) if (__start < __stop)
{ {
new(reduct) Result(f(o, begin + start)); new(__reduct) _Result(__f(__o, __begin + __start));
++start; ++__start;
constructed[iam] = true; __constructed[__iam] = true;
} }
else else
constructed[iam] = false; __constructed[__iam] = false;
for (; start < stop; ++start) for (; __start < __stop; ++__start)
*reduct = r(*reduct, f(o, begin + start)); *__reduct = __r(*__reduct, __f(__o, __begin + __start));
thread_results[iam] = *reduct; __thread_results[__iam] = *__reduct;
} //parallel } //parallel
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
if (constructed[i]) if (__constructed[__i])
output = r(output, thread_results[i]); __output = __r(__output, __thread_results[__i]);
// Points to last element processed (needed as return value for // Points to last element processed (needed as return value for
// some algorithms like transform). // some algorithms like transform).
f.finish_iterator = begin + length; __f.finish_iterator = __begin + __length;
delete[] thread_results; delete[] __thread_results;
delete[] constructed; delete[] __constructed;
return o; return __o;
} }
} // end namespace } // end namespace
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/partial_sum.h /** @file parallel/partial_sum.h
* @brief Parallel implementation of std::partial_sum(), i. e. prefix * @brief Parallel implementation of std::partial_sum(), i.e. prefix
* sums. * sums.
* This file is a GNU parallel extension to the Standard C++ Library. * This file is a GNU parallel extension to the Standard C++ Library.
*/ */
...@@ -44,175 +44,175 @@ namespace __gnu_parallel ...@@ -44,175 +44,175 @@ namespace __gnu_parallel
// Problem: there is no 0-element given. // Problem: there is no 0-element given.
/** @brief Base case prefix sum routine. /** @brief Base case prefix sum routine.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param result Begin iterator of output sequence. * @param __result Begin iterator of output sequence.
* @param bin_op Associative binary function. * @param __bin_op Associative binary function.
* @param value Start value. Must be passed since the neutral * @param __value Start value. Must be passed since the neutral
* element is unknown in general. * element is unknown in general.
* @return End iterator of output sequence. */ * @return End iterator of output sequence. */
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
OutputIterator _OutputIterator
parallel_partial_sum_basecase(InputIterator begin, InputIterator end, __parallel_partial_sum_basecase(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
typename std::iterator_traits typename std::iterator_traits
<InputIterator>::value_type value) <_IIter>::value_type __value)
{ {
if (begin == end) if (__begin == __end)
return result; return __result;
while (begin != end) while (__begin != __end)
{ {
value = bin_op(value, *begin); __value = __bin_op(__value, *__begin);
*result = value; *__result = __value;
++result; ++__result;
++begin; ++__begin;
} }
return result; return __result;
} }
/** @brief Parallel partial sum implementation, two-phase approach, /** @brief Parallel partial sum implementation, two-phase approach,
no recursion. no recursion.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param result Begin iterator of output sequence. * @param __result Begin iterator of output sequence.
* @param bin_op Associative binary function. * @param __bin_op Associative binary function.
* @param n Length of sequence. * @param __n Length of sequence.
* @param num_threads Number of threads to use. * @param __num_threads Number of threads to use.
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
OutputIterator _OutputIterator
parallel_partial_sum_linear(InputIterator begin, InputIterator end, __parallel_partial_sum_linear(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op, _OutputIterator __result, _BinaryOperation __bin_op,
typename std::iterator_traits typename std::iterator_traits
<InputIterator>::difference_type n) <_IIter>::difference_type __n)
{ {
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
if (begin == end) if (__begin == __end)
return result; return __result;
thread_index_t num_threads = _ThreadIndex __num_threads =
std::min<difference_type>(get_max_threads(), n - 1); std::min<_DifferenceType>(__get_max_threads(), __n - 1);
if (num_threads < 2) if (__num_threads < 2)
{ {
*result = *begin; *__result = *__begin;
return parallel_partial_sum_basecase( return __parallel_partial_sum_basecase(
begin + 1, end, result + 1, bin_op, *begin); __begin + 1, __end, __result + 1, __bin_op, *__begin);
} }
difference_type* borders; _DifferenceType* __borders;
value_type* sums; _ValueType* __sums;
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
borders = new difference_type[num_threads + 2]; __borders = new _DifferenceType[__num_threads + 2];
if (__s.partial_sum_dilation == 1.0f) if (__s.partial_sum_dilation == 1.0f)
equally_split(n, num_threads + 1, borders); equally_split(__n, __num_threads + 1, __borders);
else else
{ {
difference_type chunk_length = _DifferenceType __chunk_length =
((double)n ((double)__n
/ ((double)num_threads + __s.partial_sum_dilation)), / ((double)__num_threads + __s.partial_sum_dilation)),
borderstart = n - num_threads * chunk_length; __borderstart = __n - __num_threads * __chunk_length;
borders[0] = 0; __borders[0] = 0;
for (int i = 1; i < (num_threads + 1); ++i) for (int __i = 1; __i < (__num_threads + 1); ++__i)
{ {
borders[i] = borderstart; __borders[__i] = __borderstart;
borderstart += chunk_length; __borderstart += __chunk_length;
} }
borders[num_threads + 1] = n; __borders[__num_threads + 1] = __n;
} }
sums = static_cast<value_type*>(::operator new(sizeof(value_type) __sums = static_cast<_ValueType*>(::operator new(sizeof(_ValueType)
* num_threads)); * __num_threads));
OutputIterator target_end; _OutputIterator __target_end;
} //single } //single
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
if (iam == 0) if (__iam == 0)
{ {
*result = *begin; *__result = *__begin;
parallel_partial_sum_basecase(begin + 1, begin + borders[1], __parallel_partial_sum_basecase(__begin + 1, __begin + __borders[1],
result + 1, bin_op, *begin); __result + 1, __bin_op, *__begin);
::new(&(sums[iam])) value_type(*(result + borders[1] - 1)); ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1));
} }
else else
{ {
::new(&(sums[iam])) ::new(&(__sums[__iam]))
value_type(std::accumulate(begin + borders[iam] + 1, _ValueType(std::accumulate(__begin + __borders[__iam] + 1,
begin + borders[iam + 1], __begin + __borders[__iam + 1],
*(begin + borders[iam]), *(__begin + __borders[__iam]),
bin_op, __bin_op,
__gnu_parallel::sequential_tag())); __gnu_parallel::sequential_tag()));
} }
# pragma omp barrier # pragma omp barrier
# pragma omp single # pragma omp single
parallel_partial_sum_basecase( __parallel_partial_sum_basecase(
sums + 1, sums + num_threads, sums + 1, bin_op, sums[0]); __sums + 1, __sums + __num_threads, __sums + 1, __bin_op, __sums[0]);
# pragma omp barrier # pragma omp barrier
// Still same team. // Still same team.
parallel_partial_sum_basecase(begin + borders[iam + 1], __parallel_partial_sum_basecase(__begin + __borders[__iam + 1],
begin + borders[iam + 2], __begin + __borders[__iam + 2],
result + borders[iam + 1], bin_op, __result + __borders[__iam + 1], __bin_op,
sums[iam]); __sums[__iam]);
} //parallel } //parallel
::operator delete(sums); ::operator delete(__sums);
delete[] borders; delete[] __borders;
return result + n; return __result + __n;
} }
/** @brief Parallel partial sum front-end. /** @brief Parallel partial sum front-__end.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param result Begin iterator of output sequence. * @param __result Begin iterator of output sequence.
* @param bin_op Associative binary function. * @param __bin_op Associative binary function.
* @return End iterator of output sequence. */ * @return End iterator of output sequence. */
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename BinaryOperation> typename _BinaryOperation>
OutputIterator _OutputIterator
parallel_partial_sum(InputIterator begin, InputIterator end, __parallel_partial_sum(_IIter __begin, _IIter __end,
OutputIterator result, BinaryOperation bin_op) _OutputIterator __result, _BinaryOperation __bin_op)
{ {
_GLIBCXX_CALL(begin - end) _GLIBCXX_CALL(__begin - __end)
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
switch (_Settings::get().partial_sum_algorithm) switch (_Settings::get().partial_sum_algorithm)
{ {
case LINEAR: case LINEAR:
// Need an initial offset. // Need an initial __offset.
return parallel_partial_sum_linear(begin, end, result, bin_op, n); return __parallel_partial_sum_linear(__begin, __end, __result, __bin_op, __n);
default: default:
// Partial_sum algorithm not implemented. // Partial_sum algorithm not implemented.
_GLIBCXX_PARALLEL_ASSERT(0); _GLIBCXX_PARALLEL_ASSERT(0);
return result + n; return __result + __n;
} }
} }
} }
......
...@@ -45,231 +45,231 @@ ...@@ -45,231 +45,231 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Parallel implementation of std::partition. /** @brief Parallel implementation of std::partition.
* @param begin Begin iterator of input sequence to split. * @param __begin Begin iterator of input sequence to split.
* @param end End iterator of input sequence to split. * @param __end End iterator of input sequence to split.
* @param pred Partition predicate, possibly including some kind of pivot. * @param __pred Partition predicate, possibly including some kind of pivot.
* @param num_threads Maximum number of threads to use for this task. * @param __num_threads Maximum number of threads to use for this task.
* @return Number of elements not fulfilling the predicate. */ * @return Number of elements not fulfilling the predicate. */
template<typename RandomAccessIterator, typename Predicate> template<typename _RAIter, typename _Predicate>
typename std::iterator_traits<RandomAccessIterator>::difference_type typename std::iterator_traits<_RAIter>::difference_type
parallel_partition(RandomAccessIterator begin, RandomAccessIterator end, __parallel_partition(_RAIter __begin, _RAIter __end,
Predicate pred, thread_index_t num_threads) _Predicate __pred, _ThreadIndex __num_threads)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
_GLIBCXX_CALL(n) _GLIBCXX_CALL(__n)
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
// Shared. // Shared.
_GLIBCXX_VOLATILE difference_type left = 0, right = n - 1; _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1;
_GLIBCXX_VOLATILE difference_type leftover_left, leftover_right; _GLIBCXX_VOLATILE _DifferenceType __leftover_left, __leftover_right;
_GLIBCXX_VOLATILE difference_type leftnew, rightnew; _GLIBCXX_VOLATILE _DifferenceType __leftnew, __rightnew;
bool* reserved_left = NULL, * reserved_right = NULL; bool* __reserved_left = NULL, * __reserved_right = NULL;
difference_type chunk_size; _DifferenceType __chunk_size;
omp_lock_t result_lock; omp_lock_t __result_lock;
omp_init_lock(&result_lock); omp_init_lock(&__result_lock);
//at least two chunks per thread //at least two __chunks per thread
if(right - left + 1 >= 2 * num_threads * chunk_size) if(__right - __left + 1 >= 2 * __num_threads * __chunk_size)
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
reserved_left = new bool[num_threads]; __reserved_left = new bool[__num_threads];
reserved_right = new bool[num_threads]; __reserved_right = new bool[__num_threads];
if (__s.partition_chunk_share > 0.0) if (__s.partition_chunk_share > 0.0)
chunk_size = std::max<difference_type>(__s.partition_chunk_size, __chunk_size = std::max<_DifferenceType>(__s.partition_chunk_size,
(double)n * __s.partition_chunk_share (double)__n * __s.partition_chunk_share
/ (double)num_threads); / (double)__num_threads);
else else
chunk_size = __s.partition_chunk_size; __chunk_size = __s.partition_chunk_size;
} }
while (right - left + 1 >= 2 * num_threads * chunk_size) while (__right - __left + 1 >= 2 * __num_threads * __chunk_size)
{ {
# pragma omp single # pragma omp single
{ {
difference_type num_chunks = (right - left + 1) / chunk_size; _DifferenceType __num_chunks = (__right - __left + 1) / __chunk_size;
for (int r = 0; r < num_threads; ++r) for (int __r = 0; __r < __num_threads; ++__r)
{ {
reserved_left[r] = false; __reserved_left[__r] = false;
reserved_right[r] = false; __reserved_right[__r] = false;
} }
leftover_left = 0; __leftover_left = 0;
leftover_right = 0; __leftover_right = 0;
} //implicit barrier } //implicit barrier
// Private. // Private.
difference_type thread_left, thread_left_border, _DifferenceType __thread_left, __thread_left_border,
thread_right, thread_right_border; thread_right, __thread_right_border;
thread_left = left + 1; __thread_left = __left + 1;
// Just to satisfy the condition below. // Just to satisfy the condition below.
thread_left_border = thread_left - 1; __thread_left_border = __thread_left - 1;
thread_right = n - 1; thread_right = __n - 1;
thread_right_border = thread_right + 1; __thread_right_border = thread_right + 1;
bool iam_finished = false; bool __iam_finished = false;
while (!iam_finished) while (!__iam_finished)
{ {
if (thread_left > thread_left_border) if (__thread_left > __thread_left_border)
{ {
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
if (left + (chunk_size - 1) > right) if (__left + (__chunk_size - 1) > __right)
iam_finished = true; __iam_finished = true;
else else
{ {
thread_left = left; __thread_left = __left;
thread_left_border = left + (chunk_size - 1); __thread_left_border = __left + (__chunk_size - 1);
left += chunk_size; __left += __chunk_size;
} }
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
} }
if (thread_right < thread_right_border) if (thread_right < __thread_right_border)
{ {
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
if (left > right - (chunk_size - 1)) if (__left > __right - (__chunk_size - 1))
iam_finished = true; __iam_finished = true;
else else
{ {
thread_right = right; thread_right = __right;
thread_right_border = right - (chunk_size - 1); __thread_right_border = __right - (__chunk_size - 1);
right -= chunk_size; __right -= __chunk_size;
} }
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
} }
if (iam_finished) if (__iam_finished)
break; break;
// Swap as usual. // Swap as usual.
while (thread_left < thread_right) while (__thread_left < thread_right)
{ {
while (pred(begin[thread_left]) while (__pred(__begin[__thread_left])
&& thread_left <= thread_left_border) && __thread_left <= __thread_left_border)
++thread_left; ++__thread_left;
while (!pred(begin[thread_right]) while (!__pred(__begin[thread_right])
&& thread_right >= thread_right_border) && thread_right >= __thread_right_border)
--thread_right; --thread_right;
if (thread_left > thread_left_border if (__thread_left > __thread_left_border
|| thread_right < thread_right_border) || thread_right < __thread_right_border)
// Fetch new chunk(s). // Fetch new chunk(__s).
break; break;
std::swap(begin[thread_left], begin[thread_right]); std::swap(__begin[__thread_left], __begin[thread_right]);
++thread_left; ++__thread_left;
--thread_right; --thread_right;
} }
} }
// Now swap the leftover chunks to the right places. // Now swap the leftover chunks to the right places.
if (thread_left <= thread_left_border) if (__thread_left <= __thread_left_border)
# pragma omp atomic # pragma omp atomic
++leftover_left; ++__leftover_left;
if (thread_right >= thread_right_border) if (thread_right >= __thread_right_border)
# pragma omp atomic # pragma omp atomic
++leftover_right; ++__leftover_right;
# pragma omp barrier # pragma omp barrier
# pragma omp single # pragma omp single
{ {
leftnew = left - leftover_left * chunk_size; __leftnew = __left - __leftover_left * __chunk_size;
rightnew = right + leftover_right * chunk_size; __rightnew = __right + __leftover_right * __chunk_size;
} }
# pragma omp barrier # pragma omp barrier
// <=> thread_left_border + (chunk_size - 1) >= leftnew // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew
if (thread_left <= thread_left_border if (__thread_left <= __thread_left_border
&& thread_left_border >= leftnew) && __thread_left_border >= __leftnew)
{ {
// Chunk already in place, reserve spot. // Chunk already in place, reserve spot.
reserved_left[(left - (thread_left_border + 1)) / chunk_size] __reserved_left[(__left - (__thread_left_border + 1)) / __chunk_size]
= true; = true;
} }
// <=> thread_right_border - (chunk_size - 1) <= rightnew // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew
if (thread_right >= thread_right_border if (thread_right >= __thread_right_border
&& thread_right_border <= rightnew) && __thread_right_border <= __rightnew)
{ {
// Chunk already in place, reserve spot. // Chunk already in place, reserve spot.
reserved_right[((thread_right_border - 1) - right) __reserved_right[((__thread_right_border - 1) - __right)
/ chunk_size] = true; / __chunk_size] = true;
} }
# pragma omp barrier # pragma omp barrier
if (thread_left <= thread_left_border if (__thread_left <= __thread_left_border
&& thread_left_border < leftnew) && __thread_left_border < __leftnew)
{ {
// Find spot and swap. // Find spot and swap.
difference_type swapstart = -1; _DifferenceType __swapstart = -1;
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
for (int r = 0; r < leftover_left; ++r) for (int __r = 0; __r < __leftover_left; ++__r)
if (!reserved_left[r]) if (!__reserved_left[__r])
{ {
reserved_left[r] = true; __reserved_left[__r] = true;
swapstart = left - (r + 1) * chunk_size; __swapstart = __left - (__r + 1) * __chunk_size;
break; break;
} }
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1); _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif #endif
std::swap_ranges(begin + thread_left_border std::swap_ranges(__begin + __thread_left_border
- (chunk_size - 1), - (__chunk_size - 1),
begin + thread_left_border + 1, __begin + __thread_left_border + 1,
begin + swapstart); __begin + __swapstart);
} }
if (thread_right >= thread_right_border if (thread_right >= __thread_right_border
&& thread_right_border > rightnew) && __thread_right_border > __rightnew)
{ {
// Find spot and swap // Find spot and swap
difference_type swapstart = -1; _DifferenceType __swapstart = -1;
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
for (int r = 0; r < leftover_right; ++r) for (int __r = 0; __r < __leftover_right; ++__r)
if (!reserved_right[r]) if (!__reserved_right[__r])
{ {
reserved_right[r] = true; __reserved_right[__r] = true;
swapstart = right + r * chunk_size + 1; __swapstart = __right + __r * __chunk_size + 1;
break; break;
} }
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1); _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif #endif
std::swap_ranges(begin + thread_right_border, std::swap_ranges(__begin + __thread_right_border,
begin + thread_right_border + chunk_size, __begin + __thread_right_border + __chunk_size,
begin + swapstart); __begin + __swapstart);
} }
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
# pragma omp barrier # pragma omp barrier
# pragma omp single # pragma omp single
{ {
for (int r = 0; r < leftover_left; ++r) for (int __r = 0; __r < __leftover_left; ++__r)
_GLIBCXX_PARALLEL_ASSERT(reserved_left[r]); _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r]);
for (int r = 0; r < leftover_right; ++r) for (int __r = 0; __r < __leftover_right; ++__r)
_GLIBCXX_PARALLEL_ASSERT(reserved_right[r]); _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r]);
} }
# pragma omp barrier # pragma omp barrier
...@@ -277,149 +277,149 @@ template<typename RandomAccessIterator, typename Predicate> ...@@ -277,149 +277,149 @@ template<typename RandomAccessIterator, typename Predicate>
# pragma omp barrier # pragma omp barrier
left = leftnew; __left = __leftnew;
right = rightnew; __right = __rightnew;
} }
# pragma omp flush(left, right) # pragma omp flush(__left, __right)
} // end "recursion" //parallel } // end "recursion" //parallel
difference_type final_left = left, final_right = right; _DifferenceType __final_left = __left, __final_right = __right;
while (final_left < final_right) while (__final_left < __final_right)
{ {
// Go right until key is geq than pivot. // Go right until key is geq than pivot.
while (pred(begin[final_left]) && final_left < final_right) while (__pred(__begin[__final_left]) && __final_left < __final_right)
++final_left; ++__final_left;
// Go left until key is less than pivot. // Go left until key is less than pivot.
while (!pred(begin[final_right]) && final_left < final_right) while (!__pred(__begin[__final_right]) && __final_left < __final_right)
--final_right; --__final_right;
if (final_left == final_right) if (__final_left == __final_right)
break; break;
std::swap(begin[final_left], begin[final_right]); std::swap(__begin[__final_left], __begin[__final_right]);
++final_left; ++__final_left;
--final_right; --__final_right;
} }
// All elements on the left side are < piv, all elements on the // All elements on the left side are < piv, all elements on the
// right are >= piv // right are >= piv
delete[] reserved_left; delete[] __reserved_left;
delete[] reserved_right; delete[] __reserved_right;
omp_destroy_lock(&result_lock); omp_destroy_lock(&__result_lock);
// Element "between" final_left and final_right might not have // Element "between" __final_left and __final_right might not have
// been regarded yet // been regarded yet
if (final_left < n && !pred(begin[final_left])) if (__final_left < __n && !__pred(__begin[__final_left]))
// Really swapped. // Really swapped.
return final_left; return __final_left;
else else
return final_left + 1; return __final_left + 1;
} }
/** /**
* @brief Parallel implementation of std::nth_element(). * @brief Parallel implementation of std::nth_element().
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param nth Iterator of element that must be in position afterwards. * @param __nth _Iterator of element that must be in position afterwards.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
parallel_nth_element(RandomAccessIterator begin, RandomAccessIterator nth, parallel_nth_element(_RAIter __begin, _RAIter __nth,
RandomAccessIterator end, Comparator comp) _RAIter __end, _Compare __comp)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
RandomAccessIterator split; _RAIter __split;
random_number rng; _RandomNumber __rng;
difference_type minimum_length = _DifferenceType minimum_length =
std::max<difference_type>(2, _Settings::get().partition_minimal_n); std::max<_DifferenceType>(2, _Settings::get().partition_minimal_n);
// Break if input range to small. // Break if input range to small.
while (static_cast<sequence_index_t>(end - begin) >= minimum_length) while (static_cast<_SequenceIndex>(__end - __begin) >= minimum_length)
{ {
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
RandomAccessIterator pivot_pos = begin + rng(n); _RAIter __pivot_pos = __begin + __rng(__n);
// Swap pivot_pos value to end. // Swap __pivot_pos value to end.
if (pivot_pos != (end - 1)) if (__pivot_pos != (__end - 1))
std::swap(*pivot_pos, *(end - 1)); std::swap(*__pivot_pos, *(__end - 1));
pivot_pos = end - 1; __pivot_pos = __end - 1;
// XXX Comparator must have first_value_type, second_value_type, // XXX _Compare must have first__ValueType, second__ValueType,
// result_type // _ResultType
// Comparator == __gnu_parallel::lexicographic<S, int, // _Compare == __gnu_parallel::_Lexicographic<S, int,
// __gnu_parallel::less<S, S> > // __gnu_parallel::_Less<S, S> >
// pivot_pos == std::pair<S, int>* // __pivot_pos == std::pair<S, int>*
// XXX binder2nd only for RandomAccessIterators?? // XXX binder2nd only for _RAIters??
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
pred(comp, *pivot_pos); __pred(__comp, *__pivot_pos);
// Divide, leave pivot unchanged in last place. // Divide, leave pivot unchanged in last place.
RandomAccessIterator split_pos1, split_pos2; _RAIter __split_pos1, __split_pos2;
split_pos1 = begin + parallel_partition(begin, end - 1, pred, __split_pos1 = __begin + __parallel_partition(__begin, __end - 1, __pred,
get_max_threads()); __get_max_threads());
// Left side: < pivot_pos; right side: >= pivot_pos // Left side: < __pivot_pos; __right side: >= __pivot_pos
// Swap pivot back to middle. // Swap pivot back to middle.
if (split_pos1 != pivot_pos) if (__split_pos1 != __pivot_pos)
std::swap(*split_pos1, *pivot_pos); std::swap(*__split_pos1, *__pivot_pos);
pivot_pos = split_pos1; __pivot_pos = __split_pos1;
// In case all elements are equal, split_pos1 == 0 // In case all elements are equal, __split_pos1 == 0
if ((split_pos1 + 1 - begin) < (n >> 7) if ((__split_pos1 + 1 - __begin) < (__n >> 7)
|| (end - split_pos1) < (n >> 7)) || (__end - __split_pos1) < (__n >> 7))
{ {
// Very unequal split, one part smaller than one 128th // Very unequal split, one part smaller than one 128th
// elements not strictly larger than the pivot. // elements not strictly larger than the pivot.
__gnu_parallel::unary_negate<__gnu_parallel:: __gnu_parallel::__unary_negate<__gnu_parallel::
binder1st<Comparator, value_type, value_type, bool>, value_type> __binder1st<_Compare, _ValueType, _ValueType, bool>, _ValueType>
pred(__gnu_parallel::binder1st<Comparator, value_type, __pred(__gnu_parallel::__binder1st<_Compare, _ValueType,
value_type, bool>(comp, *pivot_pos)); _ValueType, bool>(__comp, *__pivot_pos));
// Find other end of pivot-equal range. // Find other end of pivot-equal range.
split_pos2 = __gnu_sequential::partition(split_pos1 + 1, __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1,
end, pred); __end, __pred);
} }
else else
// Only skip the pivot. // Only skip the pivot.
split_pos2 = split_pos1 + 1; __split_pos2 = __split_pos1 + 1;
// Compare iterators. // Compare iterators.
if (split_pos2 <= nth) if (__split_pos2 <= __nth)
begin = split_pos2; __begin = __split_pos2;
else if (nth < split_pos1) else if (__nth < __split_pos1)
end = split_pos1; __end = __split_pos1;
else else
break; break;
} }
// Only at most _Settings::partition_minimal_n elements left. // Only at most _Settings::partition_minimal_n __elements __left.
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(__begin, __end, __comp);
} }
/** @brief Parallel implementation of std::partial_sort(). /** @brief Parallel implementation of std::partial_sort().
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param middle Sort until this position. * @param __middle Sort until this position.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. */ * @param __comp Comparator. */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
parallel_partial_sort(RandomAccessIterator begin, parallel_partial_sort(_RAIter __begin,
RandomAccessIterator middle, _RAIter __middle,
RandomAccessIterator end, Comparator comp) _RAIter __end, _Compare __comp)
{ {
parallel_nth_element(begin, middle, end, comp); parallel_nth_element(__begin, __middle, __end, __comp);
std::sort(begin, middle, comp); std::sort(__begin, __middle, __comp);
} }
} //namespace __gnu_parallel } //namespace __gnu_parallel
......
...@@ -45,99 +45,99 @@ namespace __gnu_parallel ...@@ -45,99 +45,99 @@ namespace __gnu_parallel
* atomic access. push_front() and pop_front() must not be called * atomic access. push_front() and pop_front() must not be called
* concurrently to each other, while pop_back() can be called * concurrently to each other, while pop_back() can be called
* concurrently at all times. * concurrently at all times.
* @c empty(), @c size(), and @c top() are intentionally not provided. * @__c empty(), @__c size(), and @__c top() are intentionally not provided.
* Calling them would not make sense in a concurrent setting. * Calling them would not make sense in a concurrent setting.
* @param T Contained element type. */ * @param _Tp Contained element type. */
template<typename T> template<typename _Tp>
class RestrictedBoundedConcurrentQueue class _RestrictedBoundedConcurrentQueue
{ {
private: private:
/** @brief Array of elements, seen as cyclic buffer. */ /** @brief Array of elements, seen as cyclic buffer. */
T* base; _Tp* _M_base;
/** @brief Maximal number of elements contained at the same time. */ /** @brief Maximal number of elements contained at the same time. */
sequence_index_t max_size; _SequenceIndex _M_max_size;
/** @brief Cyclic begin and end pointers contained in one /** @brief Cyclic __begin and __end pointers contained in one
atomically changeable value. */ atomically changeable value. */
_GLIBCXX_VOLATILE lcas_t borders; _GLIBCXX_VOLATILE _CASable _M_borders;
public: public:
/** @brief Constructor. Not to be called concurrent, of course. /** @brief Constructor. Not to be called concurrent, of course.
* @param max_size Maximal number of elements to be contained. */ * @param _M_max_size Maximal number of elements to be contained. */
RestrictedBoundedConcurrentQueue(sequence_index_t max_size) _RestrictedBoundedConcurrentQueue(_SequenceIndex _M_max_size)
{ {
this->max_size = max_size; this->_M_max_size = _M_max_size;
base = new T[max_size]; _M_base = new _Tp[_M_max_size];
borders = encode2(0, 0); _M_borders = __encode2(0, 0);
#pragma omp flush #pragma omp flush
} }
/** @brief Destructor. Not to be called concurrent, of course. */ /** @brief Destructor. Not to be called concurrent, of course. */
~RestrictedBoundedConcurrentQueue() ~_RestrictedBoundedConcurrentQueue()
{ delete[] base; } { delete[] _M_base; }
/** @brief Pushes one element into the queue at the front end. /** @brief Pushes one element into the queue at the front __end.
* Must not be called concurrently with pop_front(). */ * Must not be called concurrently with pop_front(). */
void void
push_front(const T& t) push_front(const _Tp& __t)
{ {
lcas_t former_borders = borders; _CASable __former_borders = _M_borders;
int former_front, former_back; int __former_front, __former_back;
decode2(former_borders, former_front, former_back); decode2(__former_borders, __former_front, __former_back);
*(base + former_front % max_size) = t; *(_M_base + __former_front % _M_max_size) = __t;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
// Otherwise: front - back > max_size eventually. // Otherwise: front - back > _M_max_size eventually.
_GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back) _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back)
<= max_size); <= _M_max_size);
#endif #endif
fetch_and_add(&borders, encode2(1, 0)); __fetch_and_add(&_M_borders, __encode2(1, 0));
} }
/** @brief Pops one element from the queue at the front end. /** @brief Pops one element from the queue at the front __end.
* Must not be called concurrently with pop_front(). */ * Must not be called concurrently with pop_front(). */
bool bool
pop_front(T& t) pop_front(_Tp& __t)
{ {
int former_front, former_back; int __former_front, __former_back;
#pragma omp flush #pragma omp flush
decode2(borders, former_front, former_back); decode2(_M_borders, __former_front, __former_back);
while (former_front > former_back) while (__former_front > __former_back)
{ {
// Chance. // Chance.
lcas_t former_borders = encode2(former_front, former_back); _CASable __former_borders = __encode2(__former_front, __former_back);
lcas_t new_borders = encode2(former_front - 1, former_back); _CASable __new_borders = __encode2(__former_front - 1, __former_back);
if (compare_and_swap(&borders, former_borders, new_borders)) if (__compare_and_swap(&_M_borders, __former_borders, __new_borders))
{ {
t = *(base + (former_front - 1) % max_size); __t = *(_M_base + (__former_front - 1) % _M_max_size);
return true; return true;
} }
#pragma omp flush #pragma omp flush
decode2(borders, former_front, former_back); decode2(_M_borders, __former_front, __former_back);
} }
return false; return false;
} }
/** @brief Pops one element from the queue at the front end. /** @brief Pops one element from the queue at the front __end.
* Must not be called concurrently with pop_front(). */ * Must not be called concurrently with pop_front(). */
bool bool
pop_back(T& t) //queue behavior pop_back(_Tp& __t) //queue behavior
{ {
int former_front, former_back; int __former_front, __former_back;
#pragma omp flush #pragma omp flush
decode2(borders, former_front, former_back); decode2(_M_borders, __former_front, __former_back);
while (former_front > former_back) while (__former_front > __former_back)
{ {
// Chance. // Chance.
lcas_t former_borders = encode2(former_front, former_back); _CASable __former_borders = __encode2(__former_front, __former_back);
lcas_t new_borders = encode2(former_front, former_back + 1); _CASable __new_borders = __encode2(__former_front, __former_back + 1);
if (compare_and_swap(&borders, former_borders, new_borders)) if (__compare_and_swap(&_M_borders, __former_borders, __new_borders))
{ {
t = *(base + former_back % max_size); __t = *(_M_base + __former_back % _M_max_size);
return true; return true;
} }
#pragma omp flush #pragma omp flush
decode2(borders, former_front, former_back); decode2(_M_borders, __former_front, __former_back);
} }
return false; return false;
} }
......
...@@ -38,140 +38,140 @@ ...@@ -38,140 +38,140 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Unbalanced quicksort divide step. /** @brief Unbalanced quicksort divide step.
* @param begin Begin iterator of subsequence. * @param __begin Begin iterator of subsequence.
* @param end End iterator of subsequence. * @param __end End iterator of subsequence.
* @param comp Comparator. * @param __comp Comparator.
* @param pivot_rank Desired rank of the pivot. * @param __pivot_rank Desired __rank of the pivot.
* @param num_samples Choose pivot from that many samples. * @param __num_samples Choose pivot from that many samples.
* @param num_threads Number of threads that are allowed to work on * @param __num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
typename std::iterator_traits<RandomAccessIterator>::difference_type typename std::iterator_traits<_RAIter>::difference_type
parallel_sort_qs_divide(RandomAccessIterator begin, __parallel_sort_qs_divide(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Comparator comp, typename std::iterator_traits _Compare __comp, typename std::iterator_traits
<RandomAccessIterator>::difference_type pivot_rank, <_RAIter>::difference_type __pivot_rank,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>::difference_type <_RAIter>::difference_type
num_samples, thread_index_t num_threads) __num_samples, _ThreadIndex __num_threads)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
num_samples = std::min(num_samples, n); __num_samples = std::min(__num_samples, __n);
// Allocate uninitialized, to avoid default constructor. // Allocate uninitialized, to avoid default constructor.
value_type* samples = _ValueType* __samples =
static_cast<value_type*>(::operator new(num_samples static_cast<_ValueType*>(::operator new(__num_samples
* sizeof(value_type))); * sizeof(_ValueType)));
for (difference_type s = 0; s < num_samples; ++s) for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
{ {
const unsigned long long index = static_cast<unsigned long long>(s) const unsigned long long __index = static_cast<unsigned long long>(__s)
* n / num_samples; * __n / __num_samples;
::new(&(samples[s])) value_type(begin[index]); ::new(&(__samples[__s])) _ValueType(__begin[__index]);
} }
__gnu_sequential::sort(samples, samples + num_samples, comp); __gnu_sequential::sort(__samples, __samples + __num_samples, __comp);
value_type& pivot = samples[pivot_rank * num_samples / n]; _ValueType& pivot = __samples[__pivot_rank * __num_samples / __n];
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
pred(comp, pivot); __pred(__comp, pivot);
difference_type split = _DifferenceType __split =
parallel_partition(begin, end, pred, num_threads); __parallel_partition(__begin, __end, __pred, __num_threads);
::operator delete(samples); ::operator delete(__samples);
return split; return __split;
} }
/** @brief Unbalanced quicksort conquer step. /** @brief Unbalanced quicksort conquer step.
* @param begin Begin iterator of subsequence. * @param __begin Begin iterator of subsequence.
* @param end End iterator of subsequence. * @param __end End iterator of subsequence.
* @param comp Comparator. * @param __comp Comparator.
* @param num_threads Number of threads that are allowed to work on * @param __num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
parallel_sort_qs_conquer(RandomAccessIterator begin, __parallel_sort_qs_conquer(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Comparator comp, _Compare __comp,
thread_index_t num_threads) _ThreadIndex __num_threads)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
if (num_threads <= 1) if (__num_threads <= 1)
{ {
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(__begin, __end, __comp);
return; return;
} }
difference_type n = end - begin, pivot_rank; _DifferenceType __n = __end - __begin, __pivot_rank;
if (n <= 1) if (__n <= 1)
return; return;
thread_index_t num_threads_left; _ThreadIndex __num_threads_left;
if ((num_threads % 2) == 1) if ((__num_threads % 2) == 1)
num_threads_left = num_threads / 2 + 1; __num_threads_left = __num_threads / 2 + 1;
else else
num_threads_left = num_threads / 2; __num_threads_left = __num_threads / 2;
pivot_rank = n * num_threads_left / num_threads; __pivot_rank = __n * __num_threads_left / __num_threads;
difference_type split = _DifferenceType __split =
parallel_sort_qs_divide(begin, end, comp, pivot_rank, __parallel_sort_qs_divide(__begin, __end, __comp, __pivot_rank,
_Settings::get().sort_qs_num_samples_preset, _Settings::get().sort_qs_num_samples_preset,
num_threads); __num_threads);
#pragma omp parallel sections num_threads(2) #pragma omp parallel sections num_threads(2)
{ {
#pragma omp section #pragma omp section
parallel_sort_qs_conquer(begin, begin + split, __parallel_sort_qs_conquer(__begin, __begin + __split,
comp, num_threads_left); __comp, __num_threads_left);
#pragma omp section #pragma omp section
parallel_sort_qs_conquer(begin + split, end, __parallel_sort_qs_conquer(__begin + __split, __end,
comp, num_threads - num_threads_left); __comp, __num_threads - __num_threads_left);
} }
} }
/** @brief Unbalanced quicksort main call. /** @brief Unbalanced quicksort main call.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator input sequence, ignored. * @param __end End iterator input sequence, ignored.
* @param comp Comparator. * @param __comp Comparator.
* @param num_threads Number of threads that are allowed to work on * @param __num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
template<typename RandomAccessIterator, typename Comparator> template<typename _RAIter, typename _Compare>
void void
parallel_sort_qs(RandomAccessIterator begin, __parallel_sort_qs(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Comparator comp, _Compare __comp,
thread_index_t num_threads) _ThreadIndex __num_threads)
{ {
_GLIBCXX_CALL(n) _GLIBCXX_CALL(__n)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
// At least one element per processor. // At least one element per processor.
if (num_threads > n) if (__num_threads > __n)
num_threads = static_cast<thread_index_t>(n); __num_threads = static_cast<_ThreadIndex>(__n);
parallel_sort_qs_conquer(begin, begin + n, comp, num_threads); __parallel_sort_qs_conquer(__begin, __begin + __n, __comp, __num_threads);
} }
} //namespace __gnu_parallel } //namespace __gnu_parallel
......
...@@ -38,84 +38,84 @@ ...@@ -38,84 +38,84 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Random number generator, based on the Mersenne twister. */ /** @brief Random number generator, based on the Mersenne twister. */
class random_number class _RandomNumber
{ {
private: private:
std::tr1::mt19937 mt; std::tr1::mt19937 _M_mt;
uint64 supremum; uint64 _M_supremum;
uint64 RAND_SUP; uint64 _RAND_SUP;
double supremum_reciprocal; double _M_supremum_reciprocal;
double RAND_SUP_REC; double _RAND_SUP_REC;
// Assumed to be twice as long as the usual random number. // Assumed to be twice as long as the usual random number.
uint64 cache; uint64 __cache;
// Bit results. // Bit results.
int bits_left; int __bits_left;
static uint32 static uint32
scale_down(uint64 x, __scale_down(uint64 __x,
#if _GLIBCXX_SCALE_DOWN_FPU #if _GLIBCXX_SCALE_DOWN_FPU
uint64 /*supremum*/, double supremum_reciprocal) uint64 /*_M_supremum*/, double _M_supremum_reciprocal)
#else #else
uint64 supremum, double /*supremum_reciprocal*/) uint64 _M_supremum, double /*_M_supremum_reciprocal*/)
#endif #endif
{ {
#if _GLIBCXX_SCALE_DOWN_FPU #if _GLIBCXX_SCALE_DOWN_FPU
return uint32(x * supremum_reciprocal); return uint32(__x * _M_supremum_reciprocal);
#else #else
return static_cast<uint32>(x % supremum); return static_cast<uint32>(__x % _M_supremum);
#endif #endif
} }
public: public:
/** @brief Default constructor. Seed with 0. */ /** @brief Default constructor. Seed with 0. */
random_number() _RandomNumber()
: mt(0), supremum(0x100000000ULL), : _M_mt(0), _M_supremum(0x100000000ULL),
RAND_SUP(1ULL << (sizeof(uint32) * 8)), _RAND_SUP(1ULL << (sizeof(uint32) * 8)),
supremum_reciprocal(double(supremum) / double(RAND_SUP)), _M_supremum_reciprocal(double(_M_supremum) / double(_RAND_SUP)),
RAND_SUP_REC(1.0 / double(RAND_SUP)), _RAND_SUP_REC(1.0 / double(_RAND_SUP)),
cache(0), bits_left(0) { } __cache(0), __bits_left(0) { }
/** @brief Constructor. /** @brief Constructor.
* @param seed Random seed. * @param __seed Random __seed.
* @param supremum Generate integer random numbers in the * @param _M_supremum Generate integer random numbers in the
* interval @c [0,supremum). */ * interval @__c [0,_M_supremum). */
random_number(uint32 seed, uint64 supremum = 0x100000000ULL) _RandomNumber(uint32 __seed, uint64 _M_supremum = 0x100000000ULL)
: mt(seed), supremum(supremum), : _M_mt(__seed), _M_supremum(_M_supremum),
RAND_SUP(1ULL << (sizeof(uint32) * 8)), _RAND_SUP(1ULL << (sizeof(uint32) * 8)),
supremum_reciprocal(double(supremum) / double(RAND_SUP)), _M_supremum_reciprocal(double(_M_supremum) / double(_RAND_SUP)),
RAND_SUP_REC(1.0 / double(RAND_SUP)), _RAND_SUP_REC(1.0 / double(_RAND_SUP)),
cache(0), bits_left(0) { } __cache(0), __bits_left(0) { }
/** @brief Generate unsigned random 32-bit integer. */ /** @brief Generate unsigned random 32-bit integer. */
uint32 uint32
operator()() operator()()
{ return scale_down(mt(), supremum, supremum_reciprocal); } { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); }
/** @brief Generate unsigned random 32-bit integer in the /** @brief Generate unsigned random 32-bit integer in the
interval @c [0,local_supremum). */ interval @__c [0,local_supremum). */
uint32 uint32
operator()(uint64 local_supremum) operator()(uint64 local_supremum)
{ {
return scale_down(mt(), local_supremum, return __scale_down(_M_mt(), local_supremum,
double(local_supremum * RAND_SUP_REC)); double(local_supremum * _RAND_SUP_REC));
} }
/** @brief Generate a number of random bits, run-time parameter. /** @brief Generate a number of random bits, run-time parameter.
* @param bits Number of bits to generate. */ * @param bits Number of bits to generate. */
unsigned long unsigned long
genrand_bits(int bits) __genrand_bits(int bits)
{ {
unsigned long res = cache & ((1 << bits) - 1); unsigned long __res = __cache & ((1 << bits) - 1);
cache = cache >> bits; __cache = __cache >> bits;
bits_left -= bits; __bits_left -= bits;
if (bits_left < 32) if (__bits_left < 32)
{ {
cache |= ((uint64(mt())) << bits_left); __cache |= ((uint64(_M_mt())) << __bits_left);
bits_left += 32; __bits_left += 32;
} }
return res; return __res;
} }
}; };
......
...@@ -41,477 +41,477 @@ namespace __gnu_parallel ...@@ -41,477 +41,477 @@ namespace __gnu_parallel
{ {
/** @brief Type to hold the index of a bin. /** @brief Type to hold the index of a bin.
* *
* Since many variables of this type are allocated, it should be * Since many variables of this _Self are allocated, it should be
* chosen as small as possible. * chosen as small as possible.
*/ */
typedef unsigned short bin_index; typedef unsigned short _BinIndex;
/** @brief Data known to every thread participating in /** @brief Data known to every thread participating in
__gnu_parallel::parallel_random_shuffle(). */ __gnu_parallel::__parallel_random_shuffle(). */
template<typename RandomAccessIterator> template<typename _RAIter>
struct DRandomShufflingGlobalData struct _DRandomShufflingGlobalData
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
/** @brief Begin iterator of the source. */ /** @brief Begin iterator of the _M_source. */
RandomAccessIterator& source; _RAIter& _M_source;
/** @brief Temporary arrays for each thread. */ /** @brief Temporary arrays for each thread. */
value_type** temporaries; _ValueType** _M_temporaries;
/** @brief Two-dimensional array to hold the thread-bin distribution. /** @brief Two-dimensional array to hold the thread-bin distribution.
* *
* Dimensions (num_threads + 1) x (num_bins + 1). */ * Dimensions (__num_threads + 1) __x (_M_num_bins + 1). */
difference_type** dist; _DifferenceType** _M_dist;
/** @brief Start indexes of the threads' chunks. */ /** @brief Start indexes of the threads' __chunks. */
difference_type* starts; _DifferenceType* _M_starts;
/** @brief Number of the thread that will further process the /** @brief Number of the thread that will further process the
corresponding bin. */ corresponding bin. */
thread_index_t* bin_proc; _ThreadIndex* _M_bin_proc;
/** @brief Number of bins to distribute to. */ /** @brief Number of bins to distribute to. */
int num_bins; int _M_num_bins;
/** @brief Number of bits needed to address the bins. */ /** @brief Number of bits needed to address the bins. */
int num_bits; int _M_num_bits;
/** @brief Constructor. */ /** @brief Constructor. */
DRandomShufflingGlobalData(RandomAccessIterator& _source) _DRandomShufflingGlobalData(_RAIter& _source)
: source(_source) { } : _M_source(_source) { }
}; };
/** @brief Local data for a thread participating in /** @brief Local data for a thread participating in
__gnu_parallel::parallel_random_shuffle(). __gnu_parallel::__parallel_random_shuffle().
*/ */
template<typename RandomAccessIterator, typename RandomNumberGenerator> template<typename _RAIter, typename RandomNumberGenerator>
struct DRSSorterPU struct _DRSSorterPU
{ {
/** @brief Number of threads participating in total. */ /** @brief Number of threads participating in total. */
int num_threads; int __num_threads;
/** @brief Begin index for bins taken care of by this thread. */ /** @brief Begin __index for bins taken care of by this thread. */
bin_index bins_begin; _BinIndex _M_bins_begin;
/** @brief End index for bins taken care of by this thread. */ /** @brief End __index for bins taken care of by this thread. */
bin_index bins_end; _BinIndex __bins_end;
/** @brief Random seed for this thread. */ /** @brief Random _M_seed for this thread. */
uint32 seed; uint32 _M_seed;
/** @brief Pointer to global data. */ /** @brief Pointer to global data. */
DRandomShufflingGlobalData<RandomAccessIterator>* sd; _DRandomShufflingGlobalData<_RAIter>* _M_sd;
}; };
/** @brief Generate a random number in @c [0,2^logp). /** @brief Generate a random number in @__c [0,2^logp).
* @param logp Logarithm (basis 2) of the upper range bound. * @param logp Logarithm (basis 2) of the upper range __bound.
* @param rng Random number generator to use. * @param __rng Random number generator to use.
*/ */
template<typename RandomNumberGenerator> template<typename RandomNumberGenerator>
inline int inline int
random_number_pow2(int logp, RandomNumberGenerator& rng) __random_number_pow2(int logp, RandomNumberGenerator& __rng)
{ return rng.genrand_bits(logp); } { return __rng.__genrand_bits(logp); }
/** @brief Random shuffle code executed by each thread. /** @brief Random shuffle code executed by each thread.
* @param pus Array of thread-local data records. */ * @param __pus Array of thread-local data records. */
template<typename RandomAccessIterator, typename RandomNumberGenerator> template<typename _RAIter, typename RandomNumberGenerator>
void void
parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator, __parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter,
RandomNumberGenerator>* pus) RandomNumberGenerator>* __pus)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
DRSSorterPU<RandomAccessIterator, RandomNumberGenerator>* d = &pus[iam]; _DRSSorterPU<_RAIter, RandomNumberGenerator>* d = &__pus[__iam];
DRandomShufflingGlobalData<RandomAccessIterator>* sd = d->sd; _DRandomShufflingGlobalData<_RAIter>* _M_sd = d->_M_sd;
// Indexing: dist[bin][processor] // Indexing: _M_dist[bin][processor]
difference_type length = sd->starts[iam + 1] - sd->starts[iam]; _DifferenceType __length = _M_sd->_M_starts[__iam + 1] - _M_sd->_M_starts[__iam];
bin_index* oracles = new bin_index[length]; _BinIndex* __oracles = new _BinIndex[__length];
difference_type* dist = new difference_type[sd->num_bins + 1]; _DifferenceType* _M_dist = new _DifferenceType[_M_sd->_M_num_bins + 1];
bin_index* bin_proc = new bin_index[sd->num_bins]; _BinIndex* _M_bin_proc = new _BinIndex[_M_sd->_M_num_bins];
value_type** temporaries = new value_type*[d->num_threads]; _ValueType** _M_temporaries = new _ValueType*[d->__num_threads];
// Compute oracles and count appearances. // Compute oracles and count appearances.
for (bin_index b = 0; b < sd->num_bins + 1; ++b) for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
dist[b] = 0; _M_dist[__b] = 0;
int num_bits = sd->num_bits; int _M_num_bits = _M_sd->_M_num_bits;
random_number rng(d->seed); _RandomNumber __rng(d->_M_seed);
// First main loop. // First main loop.
for (difference_type i = 0; i < length; ++i) for (_DifferenceType __i = 0; __i < __length; ++__i)
{ {
bin_index oracle = random_number_pow2(num_bits, rng); _BinIndex __oracle = __random_number_pow2(_M_num_bits, __rng);
oracles[i] = oracle; __oracles[__i] = __oracle;
// To allow prefix (partial) sum. // To allow prefix (partial) sum.
++(dist[oracle + 1]); ++(_M_dist[__oracle + 1]);
} }
for (bin_index b = 0; b < sd->num_bins + 1; ++b) for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
sd->dist[b][iam + 1] = dist[b]; _M_sd->_M_dist[__b][__iam + 1] = _M_dist[__b];
# pragma omp barrier # pragma omp barrier
# pragma omp single # pragma omp single
{ {
// Sum up bins, sd->dist[s + 1][d->num_threads] now contains the // Sum up bins, _M_sd->_M_dist[__s + 1][d->__num_threads] now contains the
// total number of items in bin s // total number of items in bin __s
for (bin_index s = 0; s < sd->num_bins; ++s) for (_BinIndex __s = 0; __s < _M_sd->_M_num_bins; ++__s)
__gnu_sequential::partial_sum(sd->dist[s + 1], __gnu_sequential::partial_sum(_M_sd->_M_dist[__s + 1],
sd->dist[s + 1] + d->num_threads + 1, _M_sd->_M_dist[__s + 1] + d->__num_threads + 1,
sd->dist[s + 1]); _M_sd->_M_dist[__s + 1]);
} }
# pragma omp barrier # pragma omp barrier
sequence_index_t offset = 0, global_offset = 0; _SequenceIndex __offset = 0, __global_offset = 0;
for (bin_index s = 0; s < d->bins_begin; ++s) for (_BinIndex __s = 0; __s < d->_M_bins_begin; ++__s)
global_offset += sd->dist[s + 1][d->num_threads]; __global_offset += _M_sd->_M_dist[__s + 1][d->__num_threads];
# pragma omp barrier # pragma omp barrier
for (bin_index s = d->bins_begin; s < d->bins_end; ++s) for (_BinIndex __s = d->_M_bins_begin; __s < d->__bins_end; ++__s)
{ {
for (int t = 0; t < d->num_threads + 1; ++t) for (int __t = 0; __t < d->__num_threads + 1; ++__t)
sd->dist[s + 1][t] += offset; _M_sd->_M_dist[__s + 1][__t] += __offset;
offset = sd->dist[s + 1][d->num_threads]; __offset = _M_sd->_M_dist[__s + 1][d->__num_threads];
} }
sd->temporaries[iam] = static_cast<value_type*>( _M_sd->_M_temporaries[__iam] = static_cast<_ValueType*>(
::operator new(sizeof(value_type) * offset)); ::operator new(sizeof(_ValueType) * __offset));
# pragma omp barrier # pragma omp barrier
// Draw local copies to avoid false sharing. // Draw local copies to avoid false sharing.
for (bin_index b = 0; b < sd->num_bins + 1; ++b) for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
dist[b] = sd->dist[b][iam]; _M_dist[__b] = _M_sd->_M_dist[__b][__iam];
for (bin_index b = 0; b < sd->num_bins; ++b) for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins; ++__b)
bin_proc[b] = sd->bin_proc[b]; _M_bin_proc[__b] = _M_sd->_M_bin_proc[__b];
for (thread_index_t t = 0; t < d->num_threads; ++t) for (_ThreadIndex __t = 0; __t < d->__num_threads; ++__t)
temporaries[t] = sd->temporaries[t]; _M_temporaries[__t] = _M_sd->_M_temporaries[__t];
RandomAccessIterator source = sd->source; _RAIter _M_source = _M_sd->_M_source;
difference_type start = sd->starts[iam]; _DifferenceType __start = _M_sd->_M_starts[__iam];
// Distribute according to oracles, second main loop. // Distribute according to oracles, second main loop.
for (difference_type i = 0; i < length; ++i) for (_DifferenceType __i = 0; __i < __length; ++__i)
{ {
bin_index target_bin = oracles[i]; _BinIndex target_bin = __oracles[__i];
thread_index_t target_p = bin_proc[target_bin]; _ThreadIndex target_p = _M_bin_proc[target_bin];
// Last column [d->num_threads] stays unchanged. // Last column [d->__num_threads] stays unchanged.
::new(&(temporaries[target_p][dist[target_bin + 1]++])) ::new(&(_M_temporaries[target_p][_M_dist[target_bin + 1]++]))
value_type(*(source + i + start)); _ValueType(*(_M_source + __i + __start));
} }
delete[] oracles; delete[] __oracles;
delete[] dist; delete[] _M_dist;
delete[] bin_proc; delete[] _M_bin_proc;
delete[] temporaries; delete[] _M_temporaries;
# pragma omp barrier # pragma omp barrier
// Shuffle bins internally. // Shuffle bins internally.
for (bin_index b = d->bins_begin; b < d->bins_end; ++b) for (_BinIndex __b = d->_M_bins_begin; __b < d->__bins_end; ++__b)
{ {
value_type* begin = _ValueType* __begin =
sd->temporaries[iam] + _M_sd->_M_temporaries[__iam] +
((b == d->bins_begin) ? 0 : sd->dist[b][d->num_threads]), ((__b == d->_M_bins_begin) ? 0 : _M_sd->_M_dist[__b][d->__num_threads]),
* end = * __end =
sd->temporaries[iam] + sd->dist[b + 1][d->num_threads]; _M_sd->_M_temporaries[__iam] + _M_sd->_M_dist[__b + 1][d->__num_threads];
sequential_random_shuffle(begin, end, rng); __sequential_random_shuffle(__begin, __end, __rng);
std::copy(begin, end, sd->source + global_offset + std::copy(__begin, __end, _M_sd->_M_source + __global_offset +
((b == d->bins_begin) ? 0 : sd->dist[b][d->num_threads])); ((__b == d->_M_bins_begin) ? 0 : _M_sd->_M_dist[__b][d->__num_threads]));
} }
::operator delete(sd->temporaries[iam]); ::operator delete(_M_sd->_M_temporaries[__iam]);
} }
/** @brief Round up to the next greater power of 2. /** @brief Round up to the next greater power of 2.
* @param x Integer to round up */ * @param __x _Integer to round up */
template<typename T> template<typename _Tp>
T _Tp
round_up_to_pow2(T x) __round_up_to_pow2(_Tp __x)
{ {
if (x <= 1) if (__x <= 1)
return 1; return 1;
else else
return (T)1 << (__log2(x - 1) + 1); return (_Tp)1 << (__log2(__x - 1) + 1);
} }
/** @brief Main parallel random shuffle step. /** @brief Main parallel random shuffle step.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param n Length of sequence. * @param __n Length of sequence.
* @param num_threads Number of threads to use. * @param __num_threads Number of threads to use.
* @param rng Random number generator to use. * @param __rng Random number generator to use.
*/ */
template<typename RandomAccessIterator, typename RandomNumberGenerator> template<typename _RAIter, typename RandomNumberGenerator>
void void
parallel_random_shuffle_drs(RandomAccessIterator begin, __parallel_random_shuffle_drs(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>::difference_type n, <_RAIter>::difference_type __n,
thread_index_t num_threads, _ThreadIndex __num_threads,
RandomNumberGenerator& rng) RandomNumberGenerator& __rng)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
_GLIBCXX_CALL(n) _GLIBCXX_CALL(__n)
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
if (num_threads > n) if (__num_threads > __n)
num_threads = static_cast<thread_index_t>(n); __num_threads = static_cast<_ThreadIndex>(__n);
bin_index num_bins, num_bins_cache; _BinIndex _M_num_bins, __num_bins_cache;
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
// Try the L1 cache first. // Try the L1 cache first.
// Must fit into L1. // Must fit into L1.
num_bins_cache = std::max<difference_type>( __num_bins_cache = std::max<_DifferenceType>(
1, n / (__s.L1_cache_size_lb / sizeof(value_type))); 1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType)));
num_bins_cache = round_up_to_pow2(num_bins_cache); __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2 // No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size. // Power of 2 and at least one element per bin, at most the TLB size.
num_bins = std::min<difference_type>(n, num_bins_cache); _M_num_bins = std::min<_DifferenceType>(__n, __num_bins_cache);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin. // 2 TLB entries needed per bin.
num_bins = std::min<difference_type>(__s.TLB_size / 2, num_bins); _M_num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, _M_num_bins);
#endif #endif
num_bins = round_up_to_pow2(num_bins); _M_num_bins = __round_up_to_pow2(_M_num_bins);
if (num_bins < num_bins_cache) if (_M_num_bins < __num_bins_cache)
{ {
#endif #endif
// Now try the L2 cache // Now try the L2 cache
// Must fit into L2 // Must fit into L2
num_bins_cache = static_cast<bin_index>(std::max<difference_type>( __num_bins_cache = static_cast<_BinIndex>(std::max<_DifferenceType>(
1, n / (__s.L2_cache_size / sizeof(value_type)))); 1, __n / (__s.L2_cache_size / sizeof(_ValueType))));
num_bins_cache = round_up_to_pow2(num_bins_cache); __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2. // No more buckets than TLB entries, power of 2.
num_bins = static_cast<bin_index>( _M_num_bins = static_cast<_BinIndex>(
std::min(n, static_cast<difference_type>(num_bins_cache))); std::min(__n, static_cast<_DifferenceType>(__num_bins_cache)));
// Power of 2 and at least one element per bin, at most the TLB size. // Power of 2 and at least one element per bin, at most the TLB size.
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin. // 2 TLB entries needed per bin.
num_bins = std::min( _M_num_bins = std::min(
static_cast<difference_type>(__s.TLB_size / 2), num_bins); static_cast<_DifferenceType>(__s.TLB_size / 2), _M_num_bins);
#endif #endif
num_bins = round_up_to_pow2(num_bins); _M_num_bins = __round_up_to_pow2(_M_num_bins);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
} }
#endif #endif
num_threads = std::min<bin_index>(num_threads, num_bins); __num_threads = std::min<_BinIndex>(__num_threads, _M_num_bins);
if (num_threads <= 1) if (__num_threads <= 1)
return sequential_random_shuffle(begin, end, rng); return __sequential_random_shuffle(__begin, __end, __rng);
DRandomShufflingGlobalData<RandomAccessIterator> sd(begin); _DRandomShufflingGlobalData<_RAIter> _M_sd(__begin);
DRSSorterPU<RandomAccessIterator, random_number >* pus; _DRSSorterPU<_RAIter, _RandomNumber >* __pus;
difference_type* starts; _DifferenceType* _M_starts;
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
thread_index_t num_threads = omp_get_num_threads(); _ThreadIndex __num_threads = omp_get_num_threads();
# pragma omp single # pragma omp single
{ {
pus = new DRSSorterPU<RandomAccessIterator, random_number> __pus = new _DRSSorterPU<_RAIter, _RandomNumber>
[num_threads]; [__num_threads];
sd.temporaries = new value_type*[num_threads]; _M_sd._M_temporaries = new _ValueType*[__num_threads];
sd.dist = new difference_type*[num_bins + 1]; _M_sd._M_dist = new _DifferenceType*[_M_num_bins + 1];
sd.bin_proc = new thread_index_t[num_bins]; _M_sd._M_bin_proc = new _ThreadIndex[_M_num_bins];
for (bin_index b = 0; b < num_bins + 1; ++b) for (_BinIndex __b = 0; __b < _M_num_bins + 1; ++__b)
sd.dist[b] = new difference_type[num_threads + 1]; _M_sd._M_dist[__b] = new _DifferenceType[__num_threads + 1];
for (bin_index b = 0; b < (num_bins + 1); ++b) for (_BinIndex __b = 0; __b < (_M_num_bins + 1); ++__b)
{ {
sd.dist[0][0] = 0; _M_sd._M_dist[0][0] = 0;
sd.dist[b][0] = 0; _M_sd._M_dist[__b][0] = 0;
} }
starts = sd.starts = new difference_type[num_threads + 1]; _M_starts = _M_sd._M_starts = new _DifferenceType[__num_threads + 1];
int bin_cursor = 0; int bin_cursor = 0;
sd.num_bins = num_bins; _M_sd._M_num_bins = _M_num_bins;
sd.num_bits = __log2(num_bins); _M_sd._M_num_bits = __log2(_M_num_bins);
difference_type chunk_length = n / num_threads, _DifferenceType __chunk_length = __n / __num_threads,
split = n % num_threads, start = 0; __split = __n % __num_threads, __start = 0;
difference_type bin_chunk_length = num_bins / num_threads, _DifferenceType bin_chunk_length = _M_num_bins / __num_threads,
bin_split = num_bins % num_threads; bin_split = _M_num_bins % __num_threads;
for (thread_index_t i = 0; i < num_threads; ++i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
{ {
starts[i] = start; _M_starts[__i] = __start;
start += (i < split) ? (chunk_length + 1) : chunk_length; __start += (__i < __split) ? (__chunk_length + 1) : __chunk_length;
int j = pus[i].bins_begin = bin_cursor; int __j = __pus[__i]._M_bins_begin = bin_cursor;
// Range of bins for this processor. // Range of bins for this processor.
bin_cursor += (i < bin_split) ? bin_cursor += (__i < bin_split) ?
(bin_chunk_length + 1) : bin_chunk_length; (bin_chunk_length + 1) : bin_chunk_length;
pus[i].bins_end = bin_cursor; __pus[__i].__bins_end = bin_cursor;
for (; j < bin_cursor; ++j) for (; __j < bin_cursor; ++__j)
sd.bin_proc[j] = i; _M_sd._M_bin_proc[__j] = __i;
pus[i].num_threads = num_threads; __pus[__i].__num_threads = __num_threads;
pus[i].seed = rng(std::numeric_limits<uint32>::max()); __pus[__i]._M_seed = __rng(std::numeric_limits<uint32>::max());
pus[i].sd = &sd; __pus[__i]._M_sd = &_M_sd;
} }
starts[num_threads] = start; _M_starts[__num_threads] = __start;
} //single } //single
// Now shuffle in parallel. // Now shuffle in parallel.
parallel_random_shuffle_drs_pu(pus); __parallel_random_shuffle_drs_pu(__pus);
} // parallel } // parallel
delete[] starts; delete[] _M_starts;
delete[] sd.bin_proc; delete[] _M_sd._M_bin_proc;
for (int s = 0; s < (num_bins + 1); ++s) for (int __s = 0; __s < (_M_num_bins + 1); ++__s)
delete[] sd.dist[s]; delete[] _M_sd._M_dist[__s];
delete[] sd.dist; delete[] _M_sd._M_dist;
delete[] sd.temporaries; delete[] _M_sd._M_temporaries;
delete[] pus; delete[] __pus;
} }
/** @brief Sequential cache-efficient random shuffle. /** @brief Sequential __cache-efficient random shuffle.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param rng Random number generator to use. * @param __rng Random number generator to use.
*/ */
template<typename RandomAccessIterator, typename RandomNumberGenerator> template<typename _RAIter, typename RandomNumberGenerator>
void void
sequential_random_shuffle(RandomAccessIterator begin, __sequential_random_shuffle(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
RandomNumberGenerator& rng) RandomNumberGenerator& __rng)
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
bin_index num_bins, num_bins_cache; _BinIndex _M_num_bins, __num_bins_cache;
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
// Try the L1 cache first, must fit into L1. // Try the L1 cache first, must fit into L1.
num_bins_cache = __num_bins_cache =
std::max<difference_type> std::max<_DifferenceType>
(1, n / (__s.L1_cache_size_lb / sizeof(value_type))); (1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType)));
num_bins_cache = round_up_to_pow2(num_bins_cache); __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2 // No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size // Power of 2 and at least one element per bin, at most the TLB size
num_bins = std::min(n, (difference_type)num_bins_cache); _M_num_bins = std::min(__n, (_DifferenceType)__num_bins_cache);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin // 2 TLB entries needed per bin
num_bins = std::min((difference_type)__s.TLB_size / 2, num_bins); _M_num_bins = std::min((_DifferenceType)__s.TLB_size / 2, _M_num_bins);
#endif #endif
num_bins = round_up_to_pow2(num_bins); _M_num_bins = __round_up_to_pow2(_M_num_bins);
if (num_bins < num_bins_cache) if (_M_num_bins < __num_bins_cache)
{ {
#endif #endif
// Now try the L2 cache, must fit into L2. // Now try the L2 cache, must fit into L2.
num_bins_cache = __num_bins_cache =
static_cast<bin_index>(std::max<difference_type>( static_cast<_BinIndex>(std::max<_DifferenceType>(
1, n / (__s.L2_cache_size / sizeof(value_type)))); 1, __n / (__s.L2_cache_size / sizeof(_ValueType))));
num_bins_cache = round_up_to_pow2(num_bins_cache); __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2 // No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size. // Power of 2 and at least one element per bin, at most the TLB size.
num_bins = static_cast<bin_index> _M_num_bins = static_cast<_BinIndex>
(std::min(n, static_cast<difference_type>(num_bins_cache))); (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache)));
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin // 2 TLB entries needed per bin
num_bins = _M_num_bins =
std::min<difference_type>(__s.TLB_size / 2, num_bins); std::min<_DifferenceType>(__s.TLB_size / 2, _M_num_bins);
#endif #endif
num_bins = round_up_to_pow2(num_bins); _M_num_bins = __round_up_to_pow2(_M_num_bins);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
} }
#endif #endif
int num_bits = __log2(num_bins); int _M_num_bits = __log2(_M_num_bins);
if (num_bins > 1) if (_M_num_bins > 1)
{ {
value_type* target = static_cast<value_type*>( _ValueType* __target = static_cast<_ValueType*>(
::operator new(sizeof(value_type) * n)); ::operator new(sizeof(_ValueType) * __n));
bin_index* oracles = new bin_index[n]; _BinIndex* __oracles = new _BinIndex[__n];
difference_type* dist0 = new difference_type[num_bins + 1], _DifferenceType* __dist0 = new _DifferenceType[_M_num_bins + 1],
* dist1 = new difference_type[num_bins + 1]; * __dist1 = new _DifferenceType[_M_num_bins + 1];
for (int b = 0; b < num_bins + 1; ++b) for (int __b = 0; __b < _M_num_bins + 1; ++__b)
dist0[b] = 0; __dist0[__b] = 0;
random_number bitrng(rng(0xFFFFFFFF)); _RandomNumber bitrng(__rng(0xFFFFFFFF));
for (difference_type i = 0; i < n; ++i) for (_DifferenceType __i = 0; __i < __n; ++__i)
{ {
bin_index oracle = random_number_pow2(num_bits, bitrng); _BinIndex __oracle = __random_number_pow2(_M_num_bits, bitrng);
oracles[i] = oracle; __oracles[__i] = __oracle;
// To allow prefix (partial) sum. // To allow prefix (partial) sum.
++(dist0[oracle + 1]); ++(__dist0[__oracle + 1]);
} }
// Sum up bins. // Sum up bins.
__gnu_sequential::partial_sum(dist0, dist0 + num_bins + 1, dist0); __gnu_sequential::partial_sum(__dist0, __dist0 + _M_num_bins + 1, __dist0);
for (int b = 0; b < num_bins + 1; ++b) for (int __b = 0; __b < _M_num_bins + 1; ++__b)
dist1[b] = dist0[b]; __dist1[__b] = __dist0[__b];
// Distribute according to oracles. // Distribute according to oracles.
for (difference_type i = 0; i < n; ++i) for (_DifferenceType __i = 0; __i < __n; ++__i)
::new(&(target[(dist0[oracles[i]])++])) value_type(*(begin + i)); ::new(&(__target[(__dist0[__oracles[__i]])++])) _ValueType(*(__begin + __i));
for (int b = 0; b < num_bins; ++b) for (int __b = 0; __b < _M_num_bins; ++__b)
{ {
sequential_random_shuffle(target + dist1[b], __sequential_random_shuffle(__target + __dist1[__b],
target + dist1[b + 1], __target + __dist1[__b + 1],
rng); __rng);
} }
// Copy elements back. // Copy elements back.
std::copy(target, target + n, begin); std::copy(__target, __target + __n, __begin);
delete[] dist0; delete[] __dist0;
delete[] dist1; delete[] __dist1;
delete[] oracles; delete[] __oracles;
::operator delete(target); ::operator delete(__target);
} }
else else
__gnu_sequential::random_shuffle(begin, end, rng); __gnu_sequential::random_shuffle(__begin, __end, __rng);
} }
/** @brief Parallel random public call. /** @brief Parallel random public call.
* @param begin Begin iterator of sequence. * @param __begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param __end End iterator of sequence.
* @param rng Random number generator to use. * @param __rng Random number generator to use.
*/ */
template<typename RandomAccessIterator, typename RandomNumberGenerator> template<typename _RAIter, typename RandomNumberGenerator>
inline void inline void
parallel_random_shuffle(RandomAccessIterator begin, __parallel_random_shuffle(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
RandomNumberGenerator rng = random_number()) RandomNumberGenerator __rng = _RandomNumber())
{ {
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type n = end - begin; _DifferenceType __n = __end - __begin;
parallel_random_shuffle_drs(begin, end, n, get_max_threads(), rng) ; __parallel_random_shuffle_drs(__begin, __end, __n, __get_max_threads(), __rng) ;
} }
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
/** @file parallel/search.h /** @file parallel/search.h
* @brief Parallel implementation base for std::search() and * @brief Parallel implementation __base for std::search() and
* std::search_n(). * std::search_n().
* This file is a GNU parallel extension to the Standard C++ Library. * This file is a GNU parallel extension to the Standard C++ Library.
*/ */
...@@ -42,130 +42,130 @@ ...@@ -42,130 +42,130 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** /**
* @brief Precalculate advances for Knuth-Morris-Pratt algorithm. * @brief Precalculate __advances for Knuth-Morris-Pratt algorithm.
* @param elements Begin iterator of sequence to search for. * @param __elements Begin iterator of sequence to search for.
* @param length Length of sequence to search for. * @param __length Length of sequence to search for.
* @param advances Returned offsets. * @param __advances Returned __offsets.
*/ */
template<typename RandomAccessIterator, typename _DifferenceTp> template<typename _RAIter, typename _DifferenceTp>
void void
calc_borders(RandomAccessIterator elements, _DifferenceTp length, __calc_borders(_RAIter __elements, _DifferenceTp __length,
_DifferenceTp* off) _DifferenceTp* __off)
{ {
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
off[0] = -1; __off[0] = -1;
if (length > 1) if (__length > 1)
off[1] = 0; __off[1] = 0;
difference_type k = 0; _DifferenceType __k = 0;
for (difference_type j = 2; j <= length; j++) for (_DifferenceType __j = 2; __j <= __length; __j++)
{ {
while ((k >= 0) && !(elements[k] == elements[j-1])) while ((__k >= 0) && !(__elements[__k] == __elements[__j-1]))
k = off[k]; __k = __off[__k];
off[j] = ++k; __off[__j] = ++__k;
} }
} }
// Generic parallel find algorithm (requires random access iterator). // Generic parallel find algorithm (requires random access iterator).
/** @brief Parallel std::search. /** @brief Parallel std::search.
* @param begin1 Begin iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param end1 End iterator of first sequence. * @param __end1 End iterator of first sequence.
* @param begin2 Begin iterator of second sequence. * @param __begin2 Begin iterator of second sequence.
* @param end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param pred Find predicate. * @param __pred Find predicate.
* @return Place of finding in first sequences. */ * @return Place of finding in first sequences. */
template<typename _RandomAccessIterator1, template<typename __RAIter1,
typename _RandomAccessIterator2, typename __RAIter2,
typename Pred> typename _Pred>
_RandomAccessIterator1 __RAIter1
search_template(_RandomAccessIterator1 begin1, _RandomAccessIterator1 end1, __search_template(__RAIter1 __begin1, __RAIter1 __end1,
_RandomAccessIterator2 begin2, _RandomAccessIterator2 end2, __RAIter2 __begin2, __RAIter2 __end2,
Pred pred) _Pred __pred)
{ {
typedef std::iterator_traits<_RandomAccessIterator1> traits_type; typedef std::iterator_traits<__RAIter1> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
_GLIBCXX_CALL((end1 - begin1) + (end2 - begin2)); _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2));
difference_type pattern_length = end2 - begin2; _DifferenceType __pattern_length = __end2 - __begin2;
// Pattern too short. // Pattern too short.
if(pattern_length <= 0) if(__pattern_length <= 0)
return end1; return __end1;
// Last point to start search. // Last point to start search.
difference_type input_length = (end1 - begin1) - pattern_length; _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length;
// Where is first occurrence of pattern? defaults to end. // Where is first occurrence of pattern? defaults to end.
difference_type result = (end1 - begin1); _DifferenceType __result = (__end1 - __begin1);
difference_type *splitters; _DifferenceType *__splitters;
// Pattern too long. // Pattern too long.
if (input_length < 0) if (__input_length < 0)
return end1; return __end1;
omp_lock_t result_lock; omp_lock_t __result_lock;
omp_init_lock(&result_lock); omp_init_lock(&__result_lock);
thread_index_t num_threads = _ThreadIndex __num_threads =
std::max<difference_type>(1, std::max<_DifferenceType>(1,
std::min<difference_type>(input_length, get_max_threads())); std::min<_DifferenceType>(__input_length, __get_max_threads()));
difference_type advances[pattern_length]; _DifferenceType __advances[__pattern_length];
calc_borders(begin2, pattern_length, advances); __calc_borders(__begin2, __pattern_length, __advances);
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
splitters = new difference_type[num_threads + 1]; __splitters = new _DifferenceType[__num_threads + 1];
equally_split(input_length, num_threads, splitters); equally_split(__input_length, __num_threads, __splitters);
} }
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type start = splitters[iam], stop = splitters[iam + 1]; _DifferenceType __start = __splitters[__iam], __stop = __splitters[__iam + 1];
difference_type pos_in_pattern = 0; _DifferenceType __pos_in_pattern = 0;
bool found_pattern = false; bool __found_pattern = false;
while (start <= stop && !found_pattern) while (__start <= __stop && !__found_pattern)
{ {
// Get new value of result. // Get new value of result.
#pragma omp flush(result) #pragma omp flush(__result)
// No chance for this thread to find first occurrence. // No chance for this thread to find first occurrence.
if (result < start) if (__result < __start)
break; break;
while (pred(begin1[start + pos_in_pattern], while (__pred(__begin1[__start + __pos_in_pattern],
begin2[pos_in_pattern])) __begin2[__pos_in_pattern]))
{ {
++pos_in_pattern; ++__pos_in_pattern;
if (pos_in_pattern == pattern_length) if (__pos_in_pattern == __pattern_length)
{ {
// Found new candidate for result. // Found new candidate for result.
omp_set_lock(&result_lock); omp_set_lock(&__result_lock);
result = std::min(result, start); __result = std::min(__result, __start);
omp_unset_lock(&result_lock); omp_unset_lock(&__result_lock);
found_pattern = true; __found_pattern = true;
break; break;
} }
} }
// Make safe jump. // Make safe jump.
start += (pos_in_pattern - advances[pos_in_pattern]); __start += (__pos_in_pattern - __advances[__pos_in_pattern]);
pos_in_pattern = __pos_in_pattern =
(advances[pos_in_pattern] < 0) ? 0 : advances[pos_in_pattern]; (__advances[__pos_in_pattern] < 0) ? 0 : __advances[__pos_in_pattern];
} }
} //parallel } //parallel
omp_destroy_lock(&result_lock); omp_destroy_lock(&__result_lock);
delete[] splitters; delete[] __splitters;
// Return iterator on found element. // Return iterator on found element.
return (begin1 + result); return (__begin1 + __result);
} }
} // end namespace } // end namespace
......
...@@ -41,482 +41,482 @@ ...@@ -41,482 +41,482 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
template<typename InputIterator, typename OutputIterator> template<typename _IIter, typename _OutputIterator>
OutputIterator _OutputIterator
copy_tail(std::pair<InputIterator, InputIterator> b, copy_tail(std::pair<_IIter, _IIter> __b,
std::pair<InputIterator, InputIterator> e, OutputIterator r) std::pair<_IIter, _IIter> __e, _OutputIterator __r)
{ {
if (b.first != e.first) if (__b.first != __e.first)
{ {
do do
{ {
*r++ = *b.first++; *__r++ = *__b.first++;
} }
while (b.first != e.first); while (__b.first != __e.first);
} }
else else
{ {
while (b.second != e.second) while (__b.second != __e.second)
*r++ = *b.second++; *__r++ = *__b.second++;
} }
return r; return __r;
} }
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
struct symmetric_difference_func struct symmetric_difference_func
{ {
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename std::pair<InputIterator, InputIterator> iterator_pair; typedef typename std::pair<_IIter, _IIter> _IteratorPair;
symmetric_difference_func(Comparator c) : comp(c) {} symmetric_difference_func(_Compare __c) : __comp(__c) {}
Comparator comp; _Compare __comp;
OutputIterator _OutputIterator
invoke(InputIterator a, InputIterator b, _M_invoke(_IIter __a, _IIter __b,
InputIterator c, InputIterator d, _IIter __c, _IIter d,
OutputIterator r) const _OutputIterator __r) const
{ {
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ {
*r = *a; *__r = *__a;
++a; ++__a;
++r; ++__r;
} }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ {
*r = *c; *__r = *__c;
++c; ++__c;
++r; ++__r;
} }
else else
{ {
++a; ++__a;
++c; ++__c;
} }
} }
return std::copy(c, d, std::copy(a, b, r)); return std::copy(__c, d, std::copy(__a, __b, __r));
} }
difference_type _DifferenceType
count(InputIterator a, InputIterator b, __count(_IIter __a, _IIter __b,
InputIterator c, InputIterator d) const _IIter __c, _IIter d) const
{ {
difference_type counter = 0; _DifferenceType __counter = 0;
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ {
++a; ++__a;
++counter; ++__counter;
} }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ {
++c; ++__c;
++counter; ++__counter;
} }
else else
{ {
++a; ++__a;
++c; ++__c;
} }
} }
return counter + (b - a) + (d - c); return __counter + (__b - __a) + (d - __c);
} }
OutputIterator _OutputIterator
first_empty(InputIterator c, InputIterator d, OutputIterator out) const __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
{ return std::copy(c, d, out); } { return std::copy(__c, d, __out); }
OutputIterator _OutputIterator
second_empty(InputIterator a, InputIterator b, OutputIterator out) const __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
{ return std::copy(a, b, out); } { return std::copy(__a, __b, __out); }
}; };
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
struct difference_func struct __difference_func
{ {
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename std::pair<InputIterator, InputIterator> iterator_pair; typedef typename std::pair<_IIter, _IIter> _IteratorPair;
difference_func(Comparator c) : comp(c) {} __difference_func(_Compare __c) : __comp(__c) {}
Comparator comp; _Compare __comp;
OutputIterator _OutputIterator
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d, _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter d,
OutputIterator r) const _OutputIterator __r) const
{ {
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ {
*r = *a; *__r = *__a;
++a; ++__a;
++r; ++__r;
} }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ ++c; } { ++__c; }
else else
{ {
++a; ++__a;
++c; ++__c;
} }
} }
return std::copy(a, b, r); return std::copy(__a, __b, __r);
} }
difference_type _DifferenceType
count(InputIterator a, InputIterator b, __count(_IIter __a, _IIter __b,
InputIterator c, InputIterator d) const _IIter __c, _IIter d) const
{ {
difference_type counter = 0; _DifferenceType __counter = 0;
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ {
++a; ++__a;
++counter; ++__counter;
} }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ ++c; } { ++__c; }
else else
{ ++a; ++c; } { ++__a; ++__c; }
} }
return counter + (b - a); return __counter + (__b - __a);
} }
inline OutputIterator inline _OutputIterator
first_empty(InputIterator c, InputIterator d, OutputIterator out) const __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
{ return out; } { return __out; }
inline OutputIterator inline _OutputIterator
second_empty(InputIterator a, InputIterator b, OutputIterator out) const __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
{ return std::copy(a, b, out); } { return std::copy(__a, __b, __out); }
}; };
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
struct intersection_func struct __intersection_func
{ {
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename std::pair<InputIterator, InputIterator> iterator_pair; typedef typename std::pair<_IIter, _IIter> _IteratorPair;
intersection_func(Comparator c) : comp(c) {} __intersection_func(_Compare __c) : __comp(__c) {}
Comparator comp; _Compare __comp;
OutputIterator _OutputIterator
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d, _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter d,
OutputIterator r) const _OutputIterator __r) const
{ {
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ ++a; } { ++__a; }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ ++c; } { ++__c; }
else else
{ {
*r = *a; *__r = *__a;
++a; ++__a;
++c; ++__c;
++r; ++__r;
} }
} }
return r; return __r;
} }
difference_type _DifferenceType
count(InputIterator a, InputIterator b, __count(_IIter __a, _IIter __b,
InputIterator c, InputIterator d) const _IIter __c, _IIter d) const
{ {
difference_type counter = 0; _DifferenceType __counter = 0;
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ ++a; } { ++__a; }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ ++c; } { ++__c; }
else else
{ {
++a; ++__a;
++c; ++__c;
++counter; ++__counter;
} }
} }
return counter; return __counter;
} }
inline OutputIterator inline _OutputIterator
first_empty(InputIterator c, InputIterator d, OutputIterator out) const __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
{ return out; } { return __out; }
inline OutputIterator inline _OutputIterator
second_empty(InputIterator a, InputIterator b, OutputIterator out) const __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
{ return out; } { return __out; }
}; };
template<class InputIterator, class OutputIterator, class Comparator> template<class _IIter, class _OutputIterator, class _Compare>
struct union_func struct __union_func
{ {
typedef typename std::iterator_traits<InputIterator>::difference_type typedef typename std::iterator_traits<_IIter>::difference_type
difference_type; _DifferenceType;
union_func(Comparator c) : comp(c) {} __union_func(_Compare __c) : __comp(__c) {}
Comparator comp; _Compare __comp;
OutputIterator _OutputIterator
invoke(InputIterator a, const InputIterator b, InputIterator c, _M_invoke(_IIter __a, const _IIter __b, _IIter __c,
const InputIterator d, OutputIterator r) const const _IIter d, _OutputIterator __r) const
{ {
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ {
*r = *a; *__r = *__a;
++a; ++__a;
} }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ {
*r = *c; *__r = *__c;
++c; ++__c;
} }
else else
{ {
*r = *a; *__r = *__a;
++a; ++__a;
++c; ++__c;
} }
++r; ++__r;
} }
return std::copy(c, d, std::copy(a, b, r)); return std::copy(__c, d, std::copy(__a, __b, __r));
} }
difference_type _DifferenceType
count(InputIterator a, InputIterator b, __count(_IIter __a, _IIter __b,
InputIterator c, InputIterator d) const _IIter __c, _IIter d) const
{ {
difference_type counter = 0; _DifferenceType __counter = 0;
while (a != b && c != d) while (__a != __b && __c != d)
{ {
if (comp(*a, *c)) if (__comp(*__a, *__c))
{ ++a; } { ++__a; }
else if (comp(*c, *a)) else if (__comp(*__c, *__a))
{ ++c; } { ++__c; }
else else
{ {
++a; ++__a;
++c; ++__c;
} }
++counter; ++__counter;
} }
counter += (b - a); __counter += (__b - __a);
counter += (d - c); __counter += (d - __c);
return counter; return __counter;
} }
inline OutputIterator inline _OutputIterator
first_empty(InputIterator c, InputIterator d, OutputIterator out) const __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
{ return std::copy(c, d, out); } { return std::copy(__c, d, __out); }
inline OutputIterator inline _OutputIterator
second_empty(InputIterator a, InputIterator b, OutputIterator out) const __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
{ return std::copy(a, b, out); } { return std::copy(__a, __b, __out); }
}; };
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Operation> typename Operation>
OutputIterator _OutputIterator
parallel_set_operation(InputIterator begin1, InputIterator end1, __parallel_set_operation(_IIter __begin1, _IIter __end1,
InputIterator begin2, InputIterator end2, _IIter __begin2, _IIter __end2,
OutputIterator result, Operation op) _OutputIterator __result, Operation __op)
{ {
_GLIBCXX_CALL((end1 - begin1) + (end2 - begin2)) _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2))
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
typedef typename std::pair<InputIterator, InputIterator> iterator_pair; typedef typename std::pair<_IIter, _IIter> _IteratorPair;
if (begin1 == end1) if (__begin1 == __end1)
return op.first_empty(begin2, end2, result); return __op.__first_empty(__begin2, __end2, __result);
if (begin2 == end2) if (__begin2 == __end2)
return op.second_empty(begin1, end1, result); return __op.__second_empty(__begin1, __end1, __result);
const difference_type size = (end1 - begin1) + (end2 - begin2); const _DifferenceType size = (__end1 - __begin1) + (__end2 - __begin2);
const iterator_pair sequence[ 2 ] = const _IteratorPair __sequence[ 2 ] =
{ std::make_pair(begin1, end1), std::make_pair(begin2, end2) } ; { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) } ;
OutputIterator return_value = result; _OutputIterator return_value = __result;
difference_type *borders; _DifferenceType *__borders;
iterator_pair *block_begins; _IteratorPair *__block_begins;
difference_type* lengths; _DifferenceType* __lengths;
thread_index_t num_threads = _ThreadIndex __num_threads =
std::min<difference_type>(get_max_threads(), std::min<_DifferenceType>(__get_max_threads(),
std::min(end1 - begin1, end2 - begin2)); std::min(__end1 - __begin1, __end2 - __begin2));
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
borders = new difference_type[num_threads + 2]; __borders = new _DifferenceType[__num_threads + 2];
equally_split(size, num_threads + 1, borders); equally_split(size, __num_threads + 1, __borders);
block_begins = new iterator_pair[num_threads + 1]; __block_begins = new _IteratorPair[__num_threads + 1];
// Very start. // Very __start.
block_begins[0] = std::make_pair(begin1, begin2); __block_begins[0] = std::make_pair(__begin1, __begin2);
lengths = new difference_type[num_threads]; __lengths = new _DifferenceType[__num_threads];
} //single } //single
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// Result from multiseq_partition. // _Result from multiseq_partition.
InputIterator offset[2]; _IIter __offset[2];
const difference_type rank = borders[iam + 1]; const _DifferenceType __rank = __borders[__iam + 1];
multiseq_partition(sequence, sequence + 2, rank, offset, op.comp); multiseq_partition(__sequence, __sequence + 2, __rank, __offset, __op.__comp);
// allowed to read? // allowed to read?
// together // together
// *(offset[ 0 ] - 1) == *offset[ 1 ] // *(__offset[ 0 ] - 1) == *__offset[ 1 ]
if (offset[ 0 ] != begin1 && offset[ 1 ] != end2 if (__offset[ 0 ] != __begin1 && __offset[ 1 ] != __end2
&& !op.comp(*(offset[ 0 ] - 1), *offset[ 1 ]) && !__op.__comp(*(__offset[ 0 ] - 1), *__offset[ 1 ])
&& !op.comp(*offset[ 1 ], *(offset[ 0 ] - 1))) && !__op.__comp(*__offset[ 1 ], *(__offset[ 0 ] - 1)))
{ {
// Avoid split between globally equal elements: move one to // Avoid split between globally equal elements: move one to
// front in first sequence. // front in first sequence.
--offset[ 0 ]; --__offset[ 0 ];
} }
iterator_pair block_end = block_begins[ iam + 1 ] = _IteratorPair block_end = __block_begins[ __iam + 1 ] =
iterator_pair(offset[ 0 ], offset[ 1 ]); _IteratorPair(__offset[ 0 ], __offset[ 1 ]);
// Make sure all threads have their block_begin result written out. // Make sure all threads have their block_begin result written out.
# pragma omp barrier # pragma omp barrier
iterator_pair block_begin = block_begins[ iam ]; _IteratorPair __block_begin = __block_begins[ __iam ];
// Begin working for the first block, while the others except // Begin working for the first block, while the others except
// the last start to count. // the last start to count.
if (iam == 0) if (__iam == 0)
{ {
// The first thread can copy already. // The first thread can copy already.
lengths[ iam ] = op.invoke(block_begin.first, block_end.first, __lengths[ __iam ] = __op._M_invoke(__block_begin.first, block_end.first,
block_begin.second, block_end.second, __block_begin.second, block_end.second,
result) __result)
- result; - __result;
} }
else else
{ {
lengths[ iam ] = op.count(block_begin.first, block_end.first, __lengths[ __iam ] = __op.__count(__block_begin.first, block_end.first,
block_begin.second, block_end.second); __block_begin.second, block_end.second);
} }
// Make sure everyone wrote their lengths. // Make sure everyone wrote their lengths.
# pragma omp barrier # pragma omp barrier
OutputIterator r = result; _OutputIterator __r = __result;
if (iam == 0) if (__iam == 0)
{ {
// Do the last block. // Do the last block.
for (int i = 0; i < num_threads; ++i) for (int __i = 0; __i < __num_threads; ++__i)
r += lengths[i]; __r += __lengths[__i];
block_begin = block_begins[num_threads]; __block_begin = __block_begins[__num_threads];
// Return the result iterator of the last block. // Return the result iterator of the last block.
return_value = op.invoke( return_value = __op._M_invoke(
block_begin.first, end1, block_begin.second, end2, r); __block_begin.first, __end1, __block_begin.second, __end2, __r);
} }
else else
{ {
for (int i = 0; i < iam; ++i) for (int __i = 0; __i < __iam; ++__i)
r += lengths[ i ]; __r += __lengths[ __i ];
// Reset begins for copy pass. // Reset begins for copy pass.
op.invoke(block_begin.first, block_end.first, __op._M_invoke(__block_begin.first, block_end.first,
block_begin.second, block_end.second, r); __block_begin.second, block_end.second, __r);
} }
} }
return return_value; return return_value;
} }
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
inline OutputIterator inline _OutputIterator
parallel_set_union(InputIterator begin1, InputIterator end1, __parallel_set_union(_IIter __begin1, _IIter __end1,
InputIterator begin2, InputIterator end2, _IIter __begin2, _IIter __end2,
OutputIterator result, Comparator comp) _OutputIterator __result, _Compare __comp)
{ {
return parallel_set_operation(begin1, end1, begin2, end2, result, return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result,
union_func< InputIterator, OutputIterator, Comparator>(comp)); __union_func< _IIter, _OutputIterator, _Compare>(__comp));
} }
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
inline OutputIterator inline _OutputIterator
parallel_set_intersection(InputIterator begin1, InputIterator end1, __parallel_set_intersection(_IIter __begin1, _IIter __end1,
InputIterator begin2, InputIterator end2, _IIter __begin2, _IIter __end2,
OutputIterator result, Comparator comp) _OutputIterator __result, _Compare __comp)
{ {
return parallel_set_operation(begin1, end1, begin2, end2, result, return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result,
intersection_func<InputIterator, OutputIterator, Comparator>(comp)); __intersection_func<_IIter, _OutputIterator, _Compare>(__comp));
} }
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
inline OutputIterator inline _OutputIterator
parallel_set_difference(InputIterator begin1, InputIterator end1, __parallel_set_difference(_IIter __begin1, _IIter __end1,
InputIterator begin2, InputIterator end2, _IIter __begin2, _IIter __end2,
OutputIterator result, Comparator comp) _OutputIterator __result, _Compare __comp)
{ {
return parallel_set_operation(begin1, end1, begin2, end2, result, return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result,
difference_func<InputIterator, OutputIterator, Comparator>(comp)); __difference_func<_IIter, _OutputIterator, _Compare>(__comp));
} }
template<typename InputIterator, template<typename _IIter,
typename OutputIterator, typename _OutputIterator,
typename Comparator> typename _Compare>
inline OutputIterator inline _OutputIterator
parallel_set_symmetric_difference(InputIterator begin1, InputIterator end1, __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1,
InputIterator begin2, InputIterator end2, _IIter __begin2, _IIter __end2,
OutputIterator result, Comparator comp) _OutputIterator __result, _Compare __comp)
{ {
return parallel_set_operation(begin1, end1, begin2, end2, result, return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result,
symmetric_difference_func<InputIterator, OutputIterator, Comparator> symmetric_difference_func<_IIter, _OutputIterator, _Compare>
(comp)); (__comp));
} }
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* @section parallelization_decision * @section parallelization_decision
* The decision whether to run an algorithm in parallel. * The decision whether to run an algorithm in parallel.
* *
* There are several ways the user can switch on and off the parallel * There are several ways the user can switch on and __off the parallel
* execution of an algorithm, both at compile- and run-time. * execution of an algorithm, both at compile- and run-time.
* *
* Only sequential execution can be forced at compile-time. This * Only sequential execution can be forced at compile-time. This
...@@ -46,11 +46,11 @@ ...@@ -46,11 +46,11 @@
* *
* To force sequential execution of an algorithm ultimately at * To force sequential execution of an algorithm ultimately at
* compile-time, the user must add the tag * compile-time, the user must add the tag
* __gnu_parallel::sequential_tag() to the end of the parameter list, * gnu_parallel::sequential_tag() to the end of the parameter list,
* e. g. * e. g.
* *
* \code * \code
* std::sort(v.begin(), v.end(), __gnu_parallel::sequential_tag()); * std::sort(__v.begin(), __v.end(), __gnu_parallel::sequential_tag());
* \endcode * \endcode
* *
* This is compatible with all overloaded algorithm variants. No * This is compatible with all overloaded algorithm variants. No
...@@ -60,18 +60,18 @@ ...@@ -60,18 +60,18 @@
* If the algorithm call is not forced to be executed sequentially * If the algorithm call is not forced to be executed sequentially
* at compile-time, the decision is made at run-time. * at compile-time, the decision is made at run-time.
* The global variable __gnu_parallel::_Settings::algorithm_strategy * The global variable __gnu_parallel::_Settings::algorithm_strategy
* is checked. It is a tristate variable corresponding to: * is checked. _It is a tristate variable corresponding to:
* *
* a. force_sequential, meaning the sequential algorithm is executed. * a. force_sequential, meaning the sequential algorithm is executed.
* b. force_parallel, meaning the parallel algorithm is executed. * b. force_parallel, meaning the parallel algorithm is executed.
* c. heuristic * c. heuristic
* *
* For heuristic, the parallel algorithm implementation is called * For heuristic, the parallel algorithm implementation is called
* only if the input size is sufficiently large. For most * only if the input size is sufficiently large. For most
* algorithms, the input size is the (combined) length of the input * algorithms, the input size is the (combined) length of the input
* sequence(s). The threshold can be set by the user, individually * sequence(__s). The threshold can be set by the user, individually
* for each algorithm. The according variables are called * for each algorithm. The according variables are called
* __gnu_parallel::_Settings::[algorithm]_minimal_n . * gnu_parallel::_Settings::[algorithm]_minimal_n .
* *
* For some of the algorithms, there are even more tuning options, * For some of the algorithms, there are even more tuning options,
* e. g. the ability to choose from multiple algorithm variants. See * e. g. the ability to choose from multiple algorithm variants. See
...@@ -88,24 +88,24 @@ ...@@ -88,24 +88,24 @@
/** /**
* @brief Determine at compile(?)-time if the parallel variant of an * @brief Determine at compile(?)-time if the parallel variant of an
* algorithm should be called. * algorithm should be called.
* @param c A condition that is convertible to bool that is overruled by * @param __c A condition that is convertible to bool that is overruled by
* __gnu_parallel::_Settings::algorithm_strategy. Usually a decision * __gnu_parallel::_Settings::algorithm_strategy. Usually a decision
* based on the input size. * based on the input size.
*/ */
#define _GLIBCXX_PARALLEL_CONDITION(c) (__gnu_parallel::_Settings::get().algorithm_strategy != __gnu_parallel::force_sequential && ((__gnu_parallel::get_max_threads() > 1 && (c)) || __gnu_parallel::_Settings::get().algorithm_strategy == __gnu_parallel::force_parallel)) #define _GLIBCXX_PARALLEL_CONDITION(__c) (__gnu_parallel::_Settings::get().algorithm_strategy != __gnu_parallel::force_sequential && ((__gnu_parallel::__get_max_threads() > 1 && (__c)) || __gnu_parallel::_Settings::get().algorithm_strategy == __gnu_parallel::force_parallel))
/* /*
inline bool inline bool
parallel_condition(bool c) parallel_condition(bool __c)
{ {
bool ret = false; bool ret = false;
const _Settings& s = _Settings::get(); const _Settings& __s = _Settings::get();
if (s.algorithm_strategy != force_seqential) if (__s.algorithm_strategy != force_seqential)
{ {
if (s.algorithm_strategy == force_parallel) if (__s.algorithm_strategy == force_parallel)
ret = true; ret = true;
else else
ret = get_max_threads() > 1 && c; ret = __get_max_threads() > 1 && __c;
} }
return ret; return ret;
} }
...@@ -131,49 +131,49 @@ namespace __gnu_parallel ...@@ -131,49 +131,49 @@ namespace __gnu_parallel
// Per-algorithm settings. // Per-algorithm settings.
/// Minimal input size for accumulate. /// Minimal input size for accumulate.
sequence_index_t accumulate_minimal_n; _SequenceIndex accumulate_minimal_n;
/// Minimal input size for adjacent_difference. /// Minimal input size for adjacent_difference.
unsigned int adjacent_difference_minimal_n; unsigned int adjacent_difference_minimal_n;
/// Minimal input size for count and count_if. /// Minimal input size for count and count_if.
sequence_index_t count_minimal_n; _SequenceIndex count_minimal_n;
/// Minimal input size for fill. /// Minimal input size for fill.
sequence_index_t fill_minimal_n; _SequenceIndex fill_minimal_n;
/// Block size increase factor for find. /// Block size increase factor for find.
double find_increasing_factor; double find_increasing_factor;
/// Initial block size for find. /// Initial block size for find.
sequence_index_t find_initial_block_size; _SequenceIndex find_initial_block_size;
/// Maximal block size for find. /// Maximal block size for find.
sequence_index_t find_maximum_block_size; _SequenceIndex find_maximum_block_size;
/// Start with looking for this many elements sequentially, for find. /// Start with looking for this many elements sequentially, for find.
sequence_index_t find_sequential_search_size; _SequenceIndex find_sequential_search_size;
/// Minimal input size for for_each. /// Minimal input size for for_each.
sequence_index_t for_each_minimal_n; _SequenceIndex for_each_minimal_n;
/// Minimal input size for generate. /// Minimal input size for generate.
sequence_index_t generate_minimal_n; _SequenceIndex generate_minimal_n;
/// Minimal input size for max_element. /// Minimal input size for max_element.
sequence_index_t max_element_minimal_n; _SequenceIndex max_element_minimal_n;
/// Minimal input size for merge. /// Minimal input size for merge.
sequence_index_t merge_minimal_n; _SequenceIndex merge_minimal_n;
/// Oversampling factor for merge. /// Oversampling factor for merge.
unsigned int merge_oversampling; unsigned int merge_oversampling;
/// Minimal input size for min_element. /// Minimal input size for min_element.
sequence_index_t min_element_minimal_n; _SequenceIndex min_element_minimal_n;
/// Minimal input size for multiway_merge. /// Minimal input size for multiway_merge.
sequence_index_t multiway_merge_minimal_n; _SequenceIndex multiway_merge_minimal_n;
/// Oversampling factor for multiway_merge. /// Oversampling factor for multiway_merge.
int multiway_merge_minimal_k; int multiway_merge_minimal_k;
...@@ -182,22 +182,22 @@ namespace __gnu_parallel ...@@ -182,22 +182,22 @@ namespace __gnu_parallel
unsigned int multiway_merge_oversampling; unsigned int multiway_merge_oversampling;
/// Minimal input size for nth_element. /// Minimal input size for nth_element.
sequence_index_t nth_element_minimal_n; _SequenceIndex nth_element_minimal_n;
/// Chunk size for partition. /// Chunk size for partition.
sequence_index_t partition_chunk_size; _SequenceIndex partition_chunk_size;
/// Chunk size for partition, relative to input size. If > 0.0, /// Chunk size for partition, relative to input size. If > 0.0,
/// this value overrides partition_chunk_size. /// this value overrides partition_chunk_size.
double partition_chunk_share; double partition_chunk_share;
/// Minimal input size for partition. /// Minimal input size for partition.
sequence_index_t partition_minimal_n; _SequenceIndex partition_minimal_n;
/// Minimal input size for partial_sort. /// Minimal input size for partial_sort.
sequence_index_t partial_sort_minimal_n; _SequenceIndex partial_sort_minimal_n;
/// Ratio for partial_sum. Assume "sum and write result" to be /// Ratio for partial_sum. Assume "sum and write __result" to be
/// this factor slower than just "sum". /// this factor slower than just "sum".
float partial_sum_dilation; float partial_sum_dilation;
...@@ -208,22 +208,22 @@ namespace __gnu_parallel ...@@ -208,22 +208,22 @@ namespace __gnu_parallel
unsigned int random_shuffle_minimal_n; unsigned int random_shuffle_minimal_n;
/// Minimal input size for replace and replace_if. /// Minimal input size for replace and replace_if.
sequence_index_t replace_minimal_n; _SequenceIndex replace_minimal_n;
/// Minimal input size for set_difference. /// Minimal input size for set_difference.
sequence_index_t set_difference_minimal_n; _SequenceIndex set_difference_minimal_n;
/// Minimal input size for set_intersection. /// Minimal input size for set_intersection.
sequence_index_t set_intersection_minimal_n; _SequenceIndex set_intersection_minimal_n;
/// Minimal input size for set_symmetric_difference. /// Minimal input size for set_symmetric_difference.
sequence_index_t set_symmetric_difference_minimal_n; _SequenceIndex set_symmetric_difference_minimal_n;
/// Minimal input size for set_union. /// Minimal input size for set_union.
sequence_index_t set_union_minimal_n; _SequenceIndex set_union_minimal_n;
/// Minimal input size for parallel sorting. /// Minimal input size for parallel sorting.
sequence_index_t sort_minimal_n; _SequenceIndex sort_minimal_n;
/// Oversampling factor for parallel std::sort (MWMS). /// Oversampling factor for parallel std::sort (MWMS).
unsigned int sort_mwms_oversampling; unsigned int sort_mwms_oversampling;
...@@ -231,38 +231,38 @@ namespace __gnu_parallel ...@@ -231,38 +231,38 @@ namespace __gnu_parallel
/// Such many samples to take to find a good pivot (quicksort). /// Such many samples to take to find a good pivot (quicksort).
unsigned int sort_qs_num_samples_preset; unsigned int sort_qs_num_samples_preset;
/// Maximal subsequence length to switch to unbalanced base case. /// Maximal subsequence __length to switch to unbalanced __base case.
/// Applies to std::sort with dynamically load-balanced quicksort. /// Applies to std::sort with dynamically load-balanced quicksort.
sequence_index_t sort_qsb_base_case_maximal_n; _SequenceIndex sort_qsb_base_case_maximal_n;
/// Minimal input size for parallel std::transform. /// Minimal input size for parallel std::transform.
sequence_index_t transform_minimal_n; _SequenceIndex transform_minimal_n;
/// Minimal input size for unique_copy. /// Minimal input size for unique_copy.
sequence_index_t unique_copy_minimal_n; _SequenceIndex unique_copy_minimal_n;
sequence_index_t workstealing_chunk_size; _SequenceIndex workstealing_chunk_size;
// Hardware dependent tuning parameters. // Hardware dependent tuning parameters.
/// Size of the L1 cache in bytes (underestimation). /// size of the L1 cache in bytes (underestimation).
unsigned long long L1_cache_size; unsigned long long L1_cache_size;
/// Size of the L2 cache in bytes (underestimation). /// size of the L2 cache in bytes (underestimation).
unsigned long long L2_cache_size; unsigned long long L2_cache_size;
/// Size of the Translation Lookaside Buffer (underestimation). /// size of the Translation Lookaside Buffer (underestimation).
unsigned int TLB_size; unsigned int TLB_size;
/// Overestimation of cache line size. Used to avoid false /// Overestimation of cache line size. Used to avoid false
/// sharing, i. e. elements of different threads are at least this /// sharing, i.e. elements of different threads are at least this
/// amount apart. /// amount apart.
unsigned int cache_line_size; unsigned int cache_line_size;
// Statistics. // Statistics.
/// The number of stolen ranges in load-balanced quicksort. /// The number of stolen ranges in load-balanced quicksort.
sequence_index_t qsb_steals; _SequenceIndex qsb_steals;
/// Get the global settings. /// Get the global settings.
_GLIBCXX_CONST static const _Settings& _GLIBCXX_CONST static const _Settings&
......
...@@ -55,174 +55,174 @@ ...@@ -55,174 +55,174 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
//prototype //prototype
template<bool stable, typename RandomAccessIterator, template<bool __stable, typename _RAIter,
typename Comparator, typename Parallelism> typename _Compare, typename _Parallelism>
void void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, Parallelism parallelism); _Compare __comp, _Parallelism __parallelism);
/** /**
* @brief Choose multiway mergesort, splitting variant at run-time, * @brief Choose multiway mergesort, splitting variant at run-time,
* for parallel sorting. * for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, multiway_mergesort_tag parallelism) _Compare __comp, multiway_mergesort_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
if(_Settings::get().sort_splitting == EXACT) if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<stable, true> parallel_sort_mwms<__stable, true>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
else else
parallel_sort_mwms<stable, false> parallel_sort_mwms<__stable, false>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose multiway mergesort with exact splitting, * @brief Choose multiway mergesort with __exact splitting,
* for parallel sorting. * for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, multiway_mergesort_exact_tag parallelism) _Compare __comp, multiway_mergesort_exact_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
parallel_sort_mwms<stable, true> parallel_sort_mwms<__stable, true>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose multiway mergesort with splitting by sampling, * @brief Choose multiway mergesort with splitting by sampling,
* for parallel sorting. * for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, multiway_mergesort_sampling_tag parallelism) _Compare __comp, multiway_mergesort_sampling_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
parallel_sort_mwms<stable, false> parallel_sort_mwms<__stable, false>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose quicksort for parallel sorting. * @brief Choose quicksort for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, quicksort_tag parallelism) _Compare __comp, quicksort_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
_GLIBCXX_PARALLEL_ASSERT(stable == false); _GLIBCXX_PARALLEL_ASSERT(__stable == false);
parallel_sort_qs(begin, end, comp, parallelism.get_num_threads()); __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose balanced quicksort for parallel sorting. * @brief Choose balanced quicksort for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @param stable Sort stable. * @param __stable Sort __stable.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, balanced_quicksort_tag parallelism) _Compare __comp, balanced_quicksort_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
_GLIBCXX_PARALLEL_ASSERT(stable == false); _GLIBCXX_PARALLEL_ASSERT(__stable == false);
parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads()); __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose multiway mergesort with exact splitting, * @brief Choose multiway mergesort with __exact splitting,
* for parallel sorting. * for parallel sorting.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, default_parallel_tag parallelism) _Compare __comp, default_parallel_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
parallel_sort<stable> parallel_sort<__stable>
(begin, end, comp, (__begin, __end, __comp,
multiway_mergesort_exact_tag(parallelism.get_num_threads())); multiway_mergesort_exact_tag(__parallelism.__get_num_threads()));
} }
/** /**
* @brief Choose a parallel sorting algorithm. * @brief Choose a parallel sorting algorithm.
* @param begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param end End iterator of input sequence. * @param __end End iterator of input sequence.
* @param comp Comparator. * @param __comp Comparator.
* @param stable Sort stable. * @param __stable Sort __stable.
* @callgraph * @callgraph
*/ */
template<bool stable, typename RandomAccessIterator, typename Comparator> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(_RAIter __begin, _RAIter __end,
Comparator comp, parallel_tag parallelism) _Compare __comp, parallel_tag __parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
if (false) ; if (false) ;
#if _GLIBCXX_MERGESORT #if _GLIBCXX_MERGESORT
else if (stable || _Settings::get().sort_algorithm == MWMS) else if (__stable || _Settings::get().sort_algorithm == MWMS)
{ {
if(_Settings::get().sort_splitting == EXACT) if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<stable, true> parallel_sort_mwms<__stable, true>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
else else
parallel_sort_mwms<false, false> parallel_sort_mwms<false, false>
(begin, end, comp, parallelism.get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
#endif #endif
#if _GLIBCXX_QUICKSORT #if _GLIBCXX_QUICKSORT
else if (_Settings::get().sort_algorithm == QS) else if (_Settings::get().sort_algorithm == QS)
parallel_sort_qs(begin, end, comp, parallelism.get_num_threads()); __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads());
#endif #endif
#if _GLIBCXX_BAL_QUICKSORT #if _GLIBCXX_BAL_QUICKSORT
else if (_Settings::get().sort_algorithm == QS_BALANCED) else if (_Settings::get().sort_algorithm == QS_BALANCED)
parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads()); __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads());
#endif #endif
else else
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(__begin, __end, __comp);
} }
} // end namespace __gnu_parallel } // end namespace __gnu_parallel
......
...@@ -46,37 +46,37 @@ namespace __gnu_parallel ...@@ -46,37 +46,37 @@ namespace __gnu_parallel
struct parallel_tag struct parallel_tag
{ {
private: private:
thread_index_t num_threads; _ThreadIndex __num_threads;
public: public:
/** @brief Default constructor. Use default number of threads. */ /** @brief Default constructor. Use default number of threads. */
parallel_tag() parallel_tag()
{ {
this->num_threads = 0; this->__num_threads = 0;
} }
/** @brief Default constructor. Recommend number of threads to use. /** @brief Default constructor. Recommend number of threads to use.
* @param num_threads Desired number of threads. */ * @param __num_threads Desired number of threads. */
parallel_tag(thread_index_t num_threads) parallel_tag(_ThreadIndex __num_threads)
{ {
this->num_threads = num_threads; this->__num_threads = __num_threads;
} }
/** @brief Find out desired number of threads. /** @brief Find __out desired number of threads.
* @return Desired number of threads. */ * @return Desired number of threads. */
inline thread_index_t get_num_threads() inline _ThreadIndex __get_num_threads()
{ {
if(num_threads == 0) if(__num_threads == 0)
return omp_get_max_threads(); return omp_get_max_threads();
else else
return num_threads; return __num_threads;
} }
/** @brief Set the desired number of threads. /** @brief Set the desired number of threads.
* @param num_threads Desired number of threads. */ * @param __num_threads Desired number of threads. */
inline void set_num_threads(thread_index_t num_threads) inline void set_num_threads(_ThreadIndex __num_threads)
{ {
this->num_threads = num_threads; this->__num_threads = __num_threads;
} }
}; };
...@@ -85,8 +85,8 @@ namespace __gnu_parallel ...@@ -85,8 +85,8 @@ namespace __gnu_parallel
struct default_parallel_tag : public parallel_tag struct default_parallel_tag : public parallel_tag
{ {
default_parallel_tag() { } default_parallel_tag() { }
default_parallel_tag(thread_index_t num_threads) default_parallel_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Recommends parallel execution using dynamic /** @brief Recommends parallel execution using dynamic
...@@ -111,21 +111,21 @@ namespace __gnu_parallel ...@@ -111,21 +111,21 @@ namespace __gnu_parallel
/** @brief Forces parallel merging /** @brief Forces parallel merging
* with exact splitting, at compile time. */ * with __exact splitting, at compile time. */
struct exact_tag : public parallel_tag struct exact_tag : public parallel_tag
{ {
exact_tag() { } exact_tag() { }
exact_tag(thread_index_t num_threads) exact_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel merging /** @brief Forces parallel merging
* with exact splitting, at compile time. */ * with __exact splitting, at compile time. */
struct sampling_tag : public parallel_tag struct sampling_tag : public parallel_tag
{ {
sampling_tag() { } sampling_tag() { }
sampling_tag(thread_index_t num_threads) sampling_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
...@@ -134,17 +134,17 @@ namespace __gnu_parallel ...@@ -134,17 +134,17 @@ namespace __gnu_parallel
struct multiway_mergesort_tag : public parallel_tag struct multiway_mergesort_tag : public parallel_tag
{ {
multiway_mergesort_tag() { } multiway_mergesort_tag() { }
multiway_mergesort_tag(thread_index_t num_threads) multiway_mergesort_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using multiway mergesort /** @brief Forces parallel sorting using multiway mergesort
* with exact splitting at compile time. */ * with __exact splitting at compile time. */
struct multiway_mergesort_exact_tag : public parallel_tag struct multiway_mergesort_exact_tag : public parallel_tag
{ {
multiway_mergesort_exact_tag() { } multiway_mergesort_exact_tag() { }
multiway_mergesort_exact_tag(thread_index_t num_threads) multiway_mergesort_exact_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using multiway mergesort /** @brief Forces parallel sorting using multiway mergesort
...@@ -152,8 +152,8 @@ namespace __gnu_parallel ...@@ -152,8 +152,8 @@ namespace __gnu_parallel
struct multiway_mergesort_sampling_tag : public parallel_tag struct multiway_mergesort_sampling_tag : public parallel_tag
{ {
multiway_mergesort_sampling_tag() { } multiway_mergesort_sampling_tag() { }
multiway_mergesort_sampling_tag(thread_index_t num_threads) multiway_mergesort_sampling_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using unbalanced quicksort /** @brief Forces parallel sorting using unbalanced quicksort
...@@ -161,8 +161,8 @@ namespace __gnu_parallel ...@@ -161,8 +161,8 @@ namespace __gnu_parallel
struct quicksort_tag : public parallel_tag struct quicksort_tag : public parallel_tag
{ {
quicksort_tag() { } quicksort_tag() { }
quicksort_tag(thread_index_t num_threads) quicksort_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using balanced quicksort /** @brief Forces parallel sorting using balanced quicksort
...@@ -170,8 +170,8 @@ namespace __gnu_parallel ...@@ -170,8 +170,8 @@ namespace __gnu_parallel
struct balanced_quicksort_tag : public parallel_tag struct balanced_quicksort_tag : public parallel_tag
{ {
balanced_quicksort_tag() { } balanced_quicksort_tag() { }
balanced_quicksort_tag(thread_index_t num_threads) balanced_quicksort_tag(_ThreadIndex __num_threads)
: parallel_tag(num_threads) { } : parallel_tag(__num_threads) { }
}; };
......
...@@ -79,7 +79,7 @@ namespace __gnu_parallel ...@@ -79,7 +79,7 @@ namespace __gnu_parallel
}; };
/// Merging algorithms: /// Merging algorithms:
// bubblesort-alike, loser-tree variants, enum sentinel. // bubblesort-alike, loser-tree variants, enum __sentinel.
enum _MultiwayMergeAlgorithm enum _MultiwayMergeAlgorithm
{ {
LOSER_TREE LOSER_TREE
...@@ -92,7 +92,7 @@ namespace __gnu_parallel ...@@ -92,7 +92,7 @@ namespace __gnu_parallel
LINEAR LINEAR
}; };
/// Sorting/merging algorithms: sampling, exact. /// Sorting/merging algorithms: sampling, __exact.
enum _SplittingAlgorithm enum _SplittingAlgorithm
{ {
SAMPLING, SAMPLING,
...@@ -108,7 +108,7 @@ namespace __gnu_parallel ...@@ -108,7 +108,7 @@ namespace __gnu_parallel
EQUAL_SPLIT EQUAL_SPLIT
}; };
/// Integer Types. /// _Integer Types.
// XXX need to use <cstdint> // XXX need to use <cstdint>
/** @brief 16-bit signed integer. */ /** @brief 16-bit signed integer. */
typedef short int16; typedef short int16;
...@@ -129,27 +129,27 @@ namespace __gnu_parallel ...@@ -129,27 +129,27 @@ namespace __gnu_parallel
typedef unsigned long long uint64; typedef unsigned long long uint64;
/** /**
* @brief Unsigned integer to index elements. * @brief Unsigned integer to index __elements.
* The total number of elements for each algorithm must fit into this type. * The total number of elements for each algorithm must fit into this type.
*/ */
typedef uint64 sequence_index_t; typedef uint64 _SequenceIndex;
/** /**
* @brief Unsigned integer to index a thread number. * @brief Unsigned integer to index a thread number.
* The maximum thread number (for each processor) must fit into this type. * The maximum thread number (for each processor) must fit into this type.
*/ */
typedef uint16 thread_index_t; typedef uint16 _ThreadIndex;
// XXX atomics interface? // XXX atomics interface?
/// Longest compare-and-swappable integer type on this platform. /// Longest compare-and-swappable integer type on this platform.
typedef int64 lcas_t; typedef int64 _CASable;
// XXX numeric_limits::digits? // XXX numeric_limits::digits?
/// Number of bits of ::lcas_t. /// Number of bits of ::_CASable.
static const int lcas_t_bits = sizeof(lcas_t) * 8; static const int _CASable_bits = sizeof(_CASable) * 8;
/// ::lcas_t with the right half of bits set to 1. /// ::_CASable with the right half of bits set to 1.
static const lcas_t lcas_t_mask = ((lcas_t(1) << (lcas_t_bits / 2)) - 1); static const _CASable _CASable_mask = ((_CASable(1) << (_CASable_bits / 2)) - 1);
} }
#endif /* _GLIBCXX_PARALLEL_TYPES_H */ #endif /* _GLIBCXX_PARALLEL_TYPES_H */
...@@ -38,153 +38,153 @@ ...@@ -38,153 +38,153 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Parallel std::unique_copy(), w/o explicit equality predicate. /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate.
* @param first Begin iterator of input sequence. * @param __first Begin iterator of input sequence.
* @param last End iterator of input sequence. * @param __last End iterator of input sequence.
* @param result Begin iterator of result sequence. * @param __result Begin iterator of result __sequence.
* @param binary_pred Equality predicate. * @param __binary_pred Equality predicate.
* @return End iterator of result sequence. */ * @return End iterator of result __sequence. */
template<typename InputIterator, template<typename _IIter,
class OutputIterator, class _OutputIterator,
class BinaryPredicate> class _BinaryPredicate>
OutputIterator _OutputIterator
parallel_unique_copy(InputIterator first, InputIterator last, __parallel_unique_copy(_IIter __first, _IIter __last,
OutputIterator result, BinaryPredicate binary_pred) _OutputIterator __result, _BinaryPredicate __binary_pred)
{ {
_GLIBCXX_CALL(last - first) _GLIBCXX_CALL(__last - __first)
typedef std::iterator_traits<InputIterator> traits_type; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename traits_type::value_type value_type; typedef typename _TraitsType::value_type _ValueType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
difference_type size = last - first; _DifferenceType size = __last - __first;
if (size == 0) if (size == 0)
return result; return __result;
// Let the first thread process two parts. // Let the first thread process two parts.
difference_type *counter; _DifferenceType *__counter;
difference_type *borders; _DifferenceType *__borders;
thread_index_t num_threads = get_max_threads(); _ThreadIndex __num_threads = __get_max_threads();
// First part contains at least one element. // First part contains at least one element.
# pragma omp parallel num_threads(num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
borders = new difference_type[num_threads + 2]; __borders = new _DifferenceType[__num_threads + 2];
equally_split(size, num_threads + 1, borders); equally_split(size, __num_threads + 1, __borders);
counter = new difference_type[num_threads + 1]; __counter = new _DifferenceType[__num_threads + 1];
} }
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
difference_type begin, end; _DifferenceType __begin, __end;
// Check for length without duplicates // Check for length without duplicates
// Needed for position in output // Needed for position in output
difference_type i = 0; _DifferenceType __i = 0;
OutputIterator out = result; _OutputIterator __out = __result;
if (iam == 0) if (__iam == 0)
{ {
begin = borders[0] + 1; // == 1 __begin = __borders[0] + 1; // == 1
end = borders[iam + 1]; __end = __borders[__iam + 1];
++i; ++__i;
*out++ = *first; *__out++ = *__first;
for (InputIterator iter = first + begin; iter < first + end; ++iter) for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{ {
if (!binary_pred(*iter, *(iter-1))) if (!__binary_pred(*iter, *(iter-1)))
{ {
++i; ++__i;
*out++ = *iter; *__out++ = *iter;
} }
} }
} }
else else
{ {
begin = borders[iam]; //one part __begin = __borders[__iam]; //one part
end = borders[iam + 1]; __end = __borders[__iam + 1];
for (InputIterator iter = first + begin; iter < first + end; ++iter) for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{ {
if (!binary_pred(*iter, *(iter - 1))) if (!__binary_pred(*iter, *(iter - 1)))
++i; ++__i;
} }
} }
counter[iam] = i; __counter[__iam] = __i;
// Last part still untouched. // Last part still untouched.
difference_type begin_output; _DifferenceType __begin_output;
# pragma omp barrier # pragma omp barrier
// Store result in output on calculated positions. // Store result in output on calculated positions.
begin_output = 0; __begin_output = 0;
if (iam == 0) if (__iam == 0)
{ {
for (int t = 0; t < num_threads; ++t) for (int __t = 0; __t < __num_threads; ++__t)
begin_output += counter[t]; __begin_output += __counter[__t];
i = 0; __i = 0;
OutputIterator iter_out = result + begin_output; _OutputIterator __iter_out = __result + __begin_output;
begin = borders[num_threads]; __begin = __borders[__num_threads];
end = size; __end = size;
for (InputIterator iter = first + begin; iter < first + end; ++iter) for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{ {
if (iter == first || !binary_pred(*iter, *(iter - 1))) if (iter == __first || !__binary_pred(*iter, *(iter - 1)))
{ {
++i; ++__i;
*iter_out++ = *iter; *__iter_out++ = *iter;
} }
} }
counter[num_threads] = i; __counter[__num_threads] = __i;
} }
else else
{ {
for (int t = 0; t < iam; t++) for (int __t = 0; __t < __iam; __t++)
begin_output += counter[t]; __begin_output += __counter[__t];
OutputIterator iter_out = result + begin_output; _OutputIterator __iter_out = __result + __begin_output;
for (InputIterator iter = first + begin; iter < first + end; ++iter) for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{ {
if (!binary_pred(*iter, *(iter-1))) if (!__binary_pred(*iter, *(iter-1)))
*iter_out++ = *iter; *__iter_out++ = *iter;
} }
} }
} }
difference_type end_output = 0; _DifferenceType __end_output = 0;
for (int t = 0; t < num_threads + 1; t++) for (int __t = 0; __t < __num_threads + 1; __t++)
end_output += counter[t]; __end_output += __counter[__t];
delete[] borders; delete[] __borders;
return result + end_output; return __result + __end_output;
} }
/** @brief Parallel std::unique_copy(), without explicit equality predicate /** @brief Parallel std::unique_copy(), without explicit equality predicate
* @param first Begin iterator of input sequence. * @param __first Begin iterator of input sequence.
* @param last End iterator of input sequence. * @param __last End iterator of input sequence.
* @param result Begin iterator of result sequence. * @param __result Begin iterator of result __sequence.
* @return End iterator of result sequence. */ * @return End iterator of result __sequence. */
template<typename InputIterator, class OutputIterator> template<typename _IIter, class _OutputIterator>
inline OutputIterator inline _OutputIterator
parallel_unique_copy(InputIterator first, InputIterator last, __parallel_unique_copy(_IIter __first, _IIter __last,
OutputIterator result) _OutputIterator __result)
{ {
typedef typename std::iterator_traits<InputIterator>::value_type typedef typename std::iterator_traits<_IIter>::value_type
value_type; _ValueType;
return parallel_unique_copy(first, last, result, return __parallel_unique_copy(__first, __last, __result,
std::equal_to<value_type>()); std::equal_to<_ValueType>());
} }
}//namespace __gnu_parallel }//namespace __gnu_parallel
......
...@@ -49,257 +49,257 @@ namespace __gnu_parallel ...@@ -49,257 +49,257 @@ namespace __gnu_parallel
#define _GLIBCXX_JOB_VOLATILE volatile #define _GLIBCXX_JOB_VOLATILE volatile
/** @brief One job for a certain thread. */ /** @brief One __job for a certain thread. */
template<typename _DifferenceTp> template<typename _DifferenceTp>
struct Job struct _Job
{ {
typedef _DifferenceTp difference_type; typedef _DifferenceTp _DifferenceType;
/** @brief First element. /** @brief First element.
* *
* Changed by owning and stealing thread. By stealing thread, * Changed by owning and stealing thread. By stealing thread,
* always incremented. */ * always incremented. */
_GLIBCXX_JOB_VOLATILE difference_type first; _GLIBCXX_JOB_VOLATILE _DifferenceType __first;
/** @brief Last element. /** @brief Last element.
* *
* Changed by owning thread only. */ * Changed by owning thread only. */
_GLIBCXX_JOB_VOLATILE difference_type last; _GLIBCXX_JOB_VOLATILE _DifferenceType __last;
/** @brief Number of elements, i. e. @c last-first+1. /** @brief Number of elements, i.e. @__c __last-__first+1.
* *
* Changed by owning thread only. */ * Changed by owning thread only. */
_GLIBCXX_JOB_VOLATILE difference_type load; _GLIBCXX_JOB_VOLATILE _DifferenceType __load;
}; };
/** @brief Work stealing algorithm for random access iterators. /** @brief Work stealing algorithm for random access iterators.
* *
* Uses O(1) additional memory. Synchronization at job lists is * Uses O(1) additional memory. Synchronization at __job lists is
* done with atomic operations. * done with atomic operations.
* @param begin Begin iterator of element sequence. * @param __begin Begin iterator of element __sequence.
* @param end End iterator of element sequence. * @param __end End iterator of element __sequence.
* @param op User-supplied functor (comparator, predicate, adding * @param __op User-supplied functor (comparator, predicate, adding
* functor, ...). * functor, ...).
* @param f Functor to "process" an element with op (depends on * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...). * desired functionality, e. g. for std::for_each(), ...).
* @param r Functor to "add" a single result to the already * @param __r Functor to "add" a single __result to the already
* processed elements (depends on functionality). * processed __elements (depends on functionality).
* @param base Base value for reduction. * @param __base Base value for reduction.
* @param output Pointer to position where final result is written to * @param __output Pointer to position where final result is written to
* @param bound Maximum number of elements processed (e. g. for * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()). * std::count_n()).
* @return User-supplied functor (that may contain a part of the result). * @return User-supplied functor (that may contain a part of the result).
*/ */
template<typename RandomAccessIterator, template<typename _RAIter,
typename Op, typename _Op,
typename Fu, typename _Fu,
typename Red, typename _Red,
typename Result> typename _Result>
Op _Op
for_each_template_random_access_workstealing(RandomAccessIterator begin, for_each_template_random_access_workstealing(_RAIter __begin,
RandomAccessIterator end, _RAIter __end,
Op op, Fu& f, Red r, _Op __op, _Fu& __f, _Red __r,
Result base, Result& output, _Result __base, _Result& __output,
typename std::iterator_traits typename std::iterator_traits
<RandomAccessIterator>:: <_RAIter>::
difference_type bound) difference_type __bound)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(__end - __begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename traits_type::difference_type difference_type; typedef typename _TraitsType::difference_type _DifferenceType;
const _Settings& __s = _Settings::get(); const _Settings& __s = _Settings::get();
difference_type chunk_size = static_cast<difference_type>(__s.workstealing_chunk_size); _DifferenceType __chunk_size = static_cast<_DifferenceType>(__s.workstealing_chunk_size);
// How many jobs? // How many jobs?
difference_type length = (bound < 0) ? (end - begin) : bound; _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound;
// To avoid false sharing in a cache line. // To avoid false sharing in a cache line.
const int stride = __s.cache_line_size * 10 / sizeof(Job<difference_type>) + 1; const int __stride = __s.cache_line_size * 10 / sizeof(_Job<_DifferenceType>) + 1;
// Total number of threads currently working. // Total number of threads currently working.
thread_index_t busy = 0; _ThreadIndex __busy = 0;
Job<difference_type> *job; _Job<_DifferenceType> *__job;
omp_lock_t output_lock; omp_lock_t __output_lock;
omp_init_lock(&output_lock); omp_init_lock(&__output_lock);
// Write base value to output. // Write __base __value to output.
output = base; __output = __base;
// No more threads than jobs, at least one thread. // No more threads than jobs, at least one thread.
thread_index_t num_threads = _ThreadIndex __num_threads =
__gnu_parallel::max<thread_index_t>(1, __gnu_parallel::max<_ThreadIndex>(1,
__gnu_parallel::min<difference_type>(length, get_max_threads())); __gnu_parallel::min<_DifferenceType>(__length, __get_max_threads()));
# pragma omp parallel shared(busy) num_threads(num_threads) # pragma omp parallel shared(__busy) num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
// Create job description array. // Create __job description array.
job = new Job<difference_type>[num_threads * stride]; __job = new _Job<_DifferenceType>[__num_threads * __stride];
} }
// Initialization phase. // Initialization phase.
// Flags for every thread if it is doing productive work. // Flags for every thread if it is doing productive work.
bool iam_working = false; bool __iam_working = false;
// Thread id. // Thread id.
thread_index_t iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// This job. // This __job.
Job<difference_type>& my_job = job[iam * stride]; _Job<_DifferenceType>& __my_job = __job[__iam * __stride];
// Random number (for work stealing). // Random number (for work stealing).
thread_index_t victim; _ThreadIndex __victim;
// Local value for reduction. // Local value for reduction.
Result result = Result(); _Result __result = _Result();
// Number of elements to steal in one attempt. // Number of elements to steal in one attempt.
difference_type steal; _DifferenceType __steal;
// Every thread has its own random number generator // Every thread has its own random number generator
// (modulo num_threads). // (modulo __num_threads).
random_number rand_gen(iam, num_threads); _RandomNumber rand_gen(__iam, __num_threads);
// This thread is currently working. // This thread is currently working.
# pragma omp atomic # pragma omp atomic
++busy; ++__busy;
iam_working = true; __iam_working = true;
// How many jobs per thread? last thread gets the rest. // How many jobs per thread? last thread gets the rest.
my_job.first = __my_job.__first =
static_cast<difference_type>(iam * (length / num_threads)); static_cast<_DifferenceType>(__iam * (__length / __num_threads));
my_job.last = (iam == (num_threads - 1)) ? __my_job.__last = (__iam == (__num_threads - 1)) ?
(length - 1) : ((iam + 1) * (length / num_threads) - 1); (__length - 1) : ((__iam + 1) * (__length / __num_threads) - 1);
my_job.load = my_job.last - my_job.first + 1; __my_job.__load = __my_job.__last - __my_job.__first + 1;
// Init result with first value (to have a base value for reduction). // Init __result with __first __value (to have a base value for reduction).
if (my_job.first <= my_job.last) if (__my_job.__first <= __my_job.__last)
{ {
// Cannot use volatile variable directly. // Cannot use volatile variable directly.
difference_type my_first = my_job.first; _DifferenceType __my_first = __my_job.__first;
result = f(op, begin + my_first); __result = __f(__op, __begin + __my_first);
++my_job.first; ++__my_job.__first;
--my_job.load; --__my_job.__load;
} }
RandomAccessIterator current; _RAIter __current;
# pragma omp barrier # pragma omp barrier
// Actual work phase // Actual work phase
// Work on own or stolen start // Work on own or stolen __start
while (busy > 0) while (__busy > 0)
{ {
// Work until no productive thread left. // Work until no productive thread __left.
# pragma omp flush(busy) # pragma omp flush(__busy)
// Thread has own work to do // Thread has own work to do
while (my_job.first <= my_job.last) while (__my_job.__first <= __my_job.__last)
{ {
// fetch-and-add call // fetch-and-add call
// Reserve current job block (size chunk_size) in my queue. // Reserve __current __job block (size __chunk_size) in my queue.
difference_type current_job = _DifferenceType current_job =
fetch_and_add<difference_type>(&(my_job.first), chunk_size); __fetch_and_add<_DifferenceType>(&(__my_job.__first), __chunk_size);
// Update load, to make the three values consistent, // Update __load, to make the three values consistent,
// first might have been changed in the meantime // __first might have been changed in the meantime
my_job.load = my_job.last - my_job.first + 1; __my_job.__load = __my_job.__last - __my_job.__first + 1;
for (difference_type job_counter = 0; for (_DifferenceType job_counter = 0;
job_counter < chunk_size && current_job <= my_job.last; job_counter < __chunk_size && current_job <= __my_job.__last;
++job_counter) ++job_counter)
{ {
// Yes: process it! // Yes: process it!
current = begin + current_job; __current = __begin + current_job;
++current_job; ++current_job;
// Do actual work. // Do actual work.
result = r(result, f(op, current)); __result = __r(__result, __f(__op, __current));
} }
# pragma omp flush(busy) # pragma omp flush(__busy)
} }
// After reaching this point, a thread's job list is empty. // After reaching this point, a thread's __job list is empty.
if (iam_working) if (__iam_working)
{ {
// This thread no longer has work. // This thread no longer has work.
# pragma omp atomic # pragma omp atomic
--busy; --__busy;
iam_working = false; __iam_working = false;
} }
difference_type supposed_first, supposed_last, supposed_load; _DifferenceType __supposed_first, __supposed_last, __supposed_load;
do do
{ {
// Find random nonempty deque (not own), do consistency check. // Find random nonempty deque (not own), do consistency check.
yield(); __yield();
# pragma omp flush(busy) # pragma omp flush(__busy)
victim = rand_gen(); __victim = rand_gen();
supposed_first = job[victim * stride].first; __supposed_first = __job[__victim * __stride].__first;
supposed_last = job[victim * stride].last; __supposed_last = __job[__victim * __stride].__last;
supposed_load = job[victim * stride].load; __supposed_load = __job[__victim * __stride].__load;
} }
while (busy > 0 while (__busy > 0
&& ((supposed_load <= 0) && ((__supposed_load <= 0)
|| ((supposed_first + supposed_load - 1) != supposed_last))); || ((__supposed_first + __supposed_load - 1) != __supposed_last)));
if (busy == 0) if (__busy == 0)
break; break;
if (supposed_load > 0) if (__supposed_load > 0)
{ {
// Has work and work to do. // Has work and work to do.
// Number of elements to steal (at least one). // Number of elements to steal (at least one).
steal = (supposed_load < 2) ? 1 : supposed_load / 2; __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2;
// Push victim's start forward. // Push __victim's __start forward.
difference_type stolen_first = _DifferenceType __stolen_first =
fetch_and_add<difference_type>( __fetch_and_add<_DifferenceType>(
&(job[victim * stride].first), steal); &(__job[__victim * __stride].__first), __steal);
difference_type stolen_try = _DifferenceType stolen_try =
stolen_first + steal - difference_type(1); __stolen_first + __steal - _DifferenceType(1);
my_job.first = stolen_first; __my_job.__first = __stolen_first;
my_job.last = __gnu_parallel::min(stolen_try, supposed_last); __my_job.__last = __gnu_parallel::min(stolen_try, __supposed_last);
my_job.load = my_job.last - my_job.first + 1; __my_job.__load = __my_job.__last - __my_job.__first + 1;
// Has potential work again. // Has potential work again.
# pragma omp atomic # pragma omp atomic
++busy; ++__busy;
iam_working = true; __iam_working = true;
# pragma omp flush(busy) # pragma omp flush(__busy)
} }
# pragma omp flush(busy) # pragma omp flush(__busy)
} // end while busy > 0 } // end while __busy > 0
// Add accumulated result to output. // Add accumulated __result to output.
omp_set_lock(&output_lock); omp_set_lock(&__output_lock);
output = r(output, result); __output = __r(__output, __result);
omp_unset_lock(&output_lock); omp_unset_lock(&__output_lock);
} }
delete[] job; delete[] __job;
// Points to last element processed (needed as return value for // Points to last element processed (needed as return value for
// some algorithms like transform) // some algorithms like transform)
f.finish_iterator = begin + length; __f.finish_iterator = __begin + __length;
omp_destroy_lock(&output_lock); omp_destroy_lock(&__output_lock);
return op; return __op;
} }
} // end namespace } // end namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment