From 5817ff8e5f722e2a36ed6982f94d003164c01992 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 10 Jan 2008 02:07:41 +0000 Subject: [PATCH] multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor style fixes. 2008-01-09 Paolo Carlini * include/parallel/multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor style fixes. * include/parallel/losertree.h: Likewise. * include/parallel/list_partition.h: Likewise. * include/parallel/multiseq_selection.h: Likewise. * include/parallel/workstealing.h: Likewise. * include/parallel/base.h: Likewise. * include/parallel/par_loop.h: Likewise. * include/parallel/numeric: Likewise. * include/parallel/quicksort.h: Likewise. * include/parallel/algorithmfwd.h: Likewise. * include/parallel/for_each_selectors.h: Likewise. * include/parallel/omp_loop_static.h: Likewise. * include/parallel/random_shuffle.h: Likewise. * include/parallel/balanced_quicksort.h: Likewise. * include/parallel/set_operations.h: Likewise. * include/parallel/tree.h: Likewise. * include/parallel/merge.h: Likewise. * include/parallel/unique_copy.h: Likewise. * include/parallel/settings.h: Likewise. * include/parallel/multiway_mergesort.h: Likewise. * include/parallel/numericfwd.h: Likewise. * include/parallel/search.h: Likewise. * include/parallel/partition.h: Likewise. * include/parallel/compatibility.h: Likewise. * include/parallel/partial_sum.h: Likewise. * include/parallel/find.h: Likewise. * include/parallel/algo.h: Likewise. * include/parallel/queue.h: Likewise. * include/parallel/omp_loop.h: Likewise. * include/parallel/sort.h: Likewise. * include/parallel/random_number.h: Likewise. From-SVN: r131440 --- libstdc++-v3/ChangeLog | 35 + libstdc++-v3/include/parallel/algo.h | 202 +- libstdc++-v3/include/parallel/algorithmfwd.h | 6 +- .../include/parallel/balanced_quicksort.h | 31 +- libstdc++-v3/include/parallel/base.h | 12 +- libstdc++-v3/include/parallel/compatibility.h | 38 +- libstdc++-v3/include/parallel/find.h | 40 +- .../include/parallel/for_each_selectors.h | 446 +-- .../include/parallel/list_partition.h | 4 +- libstdc++-v3/include/parallel/losertree.h | 50 +- libstdc++-v3/include/parallel/merge.h | 6 +- .../include/parallel/multiseq_selection.h | 26 +- .../include/parallel/multiway_merge.h | 402 +- .../include/parallel/multiway_mergesort.h | 50 +- libstdc++-v3/include/parallel/numeric | 662 ++-- libstdc++-v3/include/parallel/numericfwd.h | 252 +- libstdc++-v3/include/parallel/omp_loop.h | 31 +- .../include/parallel/omp_loop_static.h | 40 +- libstdc++-v3/include/parallel/par_loop.h | 30 +- libstdc++-v3/include/parallel/partial_sum.h | 69 +- libstdc++-v3/include/parallel/partition.h | 88 +- libstdc++-v3/include/parallel/queue.h | 160 +- libstdc++-v3/include/parallel/quicksort.h | 172 +- libstdc++-v3/include/parallel/random_number.h | 537 +-- .../include/parallel/random_shuffle.h | 22 +- libstdc++-v3/include/parallel/search.h | 9 +- .../include/parallel/set_operations.h | 116 +- libstdc++-v3/include/parallel/settings.h | 28 +- libstdc++-v3/include/parallel/sort.h | 47 +- libstdc++-v3/include/parallel/tree.h | 3528 +++++++++-------- libstdc++-v3/include/parallel/unique_copy.h | 47 +- libstdc++-v3/include/parallel/workstealing.h | 41 +- 32 files changed, 3871 insertions(+), 3356 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 842ce0b138a..30d58857f83 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,38 @@ +2008-01-09 Paolo Carlini + + * include/parallel/multiway_merge.h: Reformat to 80 columns; + adjust some inline specifiers; other minor style fixes. + * include/parallel/losertree.h: Likewise. + * include/parallel/list_partition.h: Likewise. + * include/parallel/multiseq_selection.h: Likewise. + * include/parallel/workstealing.h: Likewise. + * include/parallel/base.h: Likewise. + * include/parallel/par_loop.h: Likewise. + * include/parallel/numeric: Likewise. + * include/parallel/quicksort.h: Likewise. + * include/parallel/algorithmfwd.h: Likewise. + * include/parallel/for_each_selectors.h: Likewise. + * include/parallel/omp_loop_static.h: Likewise. + * include/parallel/random_shuffle.h: Likewise. + * include/parallel/balanced_quicksort.h: Likewise. + * include/parallel/set_operations.h: Likewise. + * include/parallel/tree.h: Likewise. + * include/parallel/merge.h: Likewise. + * include/parallel/unique_copy.h: Likewise. + * include/parallel/settings.h: Likewise. + * include/parallel/multiway_mergesort.h: Likewise. + * include/parallel/numericfwd.h: Likewise. + * include/parallel/search.h: Likewise. + * include/parallel/partition.h: Likewise. + * include/parallel/compatibility.h: Likewise. + * include/parallel/partial_sum.h: Likewise. + * include/parallel/find.h: Likewise. + * include/parallel/algo.h: Likewise. + * include/parallel/queue.h: Likewise. + * include/parallel/omp_loop.h: Likewise. + * include/parallel/sort.h: Likewise. + * include/parallel/random_number.h: Likewise. + 2008-01-09 Benjamin Kosnik * docs/html/17_intro/api.html: Fix markup for rope.h. diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h index 280958818df..47f305dca32 100644 --- a/libstdc++-v3/include/parallel/algo.h +++ b/libstdc++-v3/include/parallel/algo.h @@ -90,12 +90,10 @@ namespace __parallel __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - for_each_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::for_each_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { bool dummy; __gnu_parallel::for_each_selector @@ -333,10 +331,9 @@ namespace __parallel RandomAccessOutputIterator out, Predicate pred, random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(last - begin) - > __gnu_parallel::Settings:: - unique_copy_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(last - begin) + > __gnu_parallel::Settings::unique_copy_minimal_n)) return __gnu_parallel::parallel_unique_copy(begin, last, out, pred); else return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred); @@ -414,14 +411,11 @@ namespace __parallel random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end1 - begin1) - >= __gnu_parallel::Settings:: - set_union_minimal_n - || static_cast<__gnu_parallel:: - sequence_index_t>(end2 - begin2) - >= __gnu_parallel::Settings:: - set_union_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) + >= __gnu_parallel::Settings::set_union_minimal_n + || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) + >= __gnu_parallel::Settings::set_union_minimal_n)) return __gnu_parallel::parallel_set_union(begin1, end1, begin2, end2, result, pred); else @@ -523,14 +517,11 @@ namespace __parallel random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end1 - begin1) - >= __gnu_parallel::Settings:: - set_union_minimal_n - || static_cast<__gnu_parallel:: - sequence_index_t>(end2 - begin2) - >= __gnu_parallel::Settings:: - set_union_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) + >= __gnu_parallel::Settings::set_union_minimal_n + || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) + >= __gnu_parallel::Settings::set_union_minimal_n)) return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2, end2, result, pred); else @@ -639,14 +630,11 @@ namespace __parallel random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end1 - begin1) - >= __gnu_parallel::Settings:: - set_symmetric_difference_minimal_n - || static_cast<__gnu_parallel:: - sequence_index_t>(end2 - begin2) - >= __gnu_parallel::Settings:: - set_symmetric_difference_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) + >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n + || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) + >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n)) return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1, begin2, end2, result, pred); @@ -751,14 +739,11 @@ namespace __parallel random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end1 - begin1) - >= __gnu_parallel::Settings:: - set_difference_minimal_n - || static_cast<__gnu_parallel:: - sequence_index_t>(end2 - begin2) - >= __gnu_parallel::Settings:: - set_difference_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) + >= __gnu_parallel::Settings::set_difference_minimal_n + || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) + >= __gnu_parallel::Settings::set_difference_minimal_n)) return __gnu_parallel::parallel_set_difference(begin1, end1, begin2, end2, result, pred); @@ -926,12 +911,10 @@ namespace __parallel typedef typename traits_type::difference_type difference_type; typedef __gnu_parallel::sequence_index_t sequence_index_t; - if (_GLIBCXX_PARALLEL_CONDITION(static_cast - (end - begin) - >= __gnu_parallel::Settings:: - count_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast(end - begin) + >= __gnu_parallel::Settings::count_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { __gnu_parallel::count_selector functionality; @@ -996,12 +979,10 @@ namespace __parallel typedef typename traits_type::difference_type difference_type; typedef __gnu_parallel::sequence_index_t sequence_index_t; - if (_GLIBCXX_PARALLEL_CONDITION(static_cast - (end - begin) - >= __gnu_parallel::Settings:: - count_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast(end - begin) + >= __gnu_parallel::Settings::count_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { difference_type res = 0; __gnu_parallel:: @@ -1239,12 +1220,10 @@ namespace __parallel __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - transform_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::transform_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { bool dummy = true; typedef __gnu_parallel::iterator_pair= __gnu_parallel::Settings:: - transform_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + (end1 - begin1) >= __gnu_parallel::Settings::transform_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { bool dummy = true; typedef __gnu_parallel::iterator_triple(end - begin) - >= __gnu_parallel::Settings:: - replace_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::replace_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { bool dummy; __gnu_parallel:: @@ -1556,12 +1531,10 @@ namespace __parallel __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - generate_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::generate_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { bool dummy; __gnu_parallel::generate_selector @@ -1686,10 +1659,9 @@ namespace __parallel { if (begin == end) return; - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - random_shuffle_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::random_shuffle_minimal_n)) __gnu_parallel::parallel_random_shuffle(begin, end, rand); else __gnu_parallel::sequential_random_shuffle(begin, end, rand); @@ -1715,10 +1687,9 @@ namespace __parallel partition_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - partition_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::partition_minimal_n)) { typedef typename std::iterator_traits:: difference_type difference_type; @@ -1775,10 +1746,9 @@ namespace __parallel if (begin != end) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - sort_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::sort_minimal_n)) __gnu_parallel::parallel_sort(begin, end, comp, false); else sort(begin, end, comp, __gnu_parallel::sequential_tag()); @@ -1816,10 +1786,9 @@ namespace __parallel { if (begin != end) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - sort_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::sort_minimal_n)) __gnu_parallel::parallel_sort(begin, end, comp, true); else stable_sort(begin, end, comp, __gnu_parallel::sequential_tag()); @@ -1866,14 +1835,11 @@ namespace __parallel random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { - if (_GLIBCXX_PARALLEL_CONDITION((static_cast<__gnu_parallel:: - sequence_index_t>(end1 - begin1) - >= __gnu_parallel::Settings:: - merge_minimal_n - || static_cast<__gnu_parallel:: - sequence_index_t>(end2 - begin2) - >= __gnu_parallel::Settings:: - merge_minimal_n))) + if (_GLIBCXX_PARALLEL_CONDITION( + (static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) + >= __gnu_parallel::Settings::merge_minimal_n + || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) + >= __gnu_parallel::Settings::merge_minimal_n))) return __gnu_parallel::parallel_merge_advance(begin1, end1, begin2, end2, result, (end1 - begin1) @@ -1945,10 +1911,9 @@ namespace __parallel nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - nth_element_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::nth_element_minimal_n)) __gnu_parallel::parallel_nth_element(begin, nth, end, comp); else nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag()); @@ -1986,10 +1951,9 @@ namespace __parallel partial_sort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, _Compare comp) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - partial_sort_minimal_n)) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::partial_sort_minimal_n)) __gnu_parallel::parallel_partial_sort(begin, middle, end, comp); else partial_sort(begin, middle, end, comp, @@ -2036,12 +2000,10 @@ namespace __parallel __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - max_element_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::max_element_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { RandomAccessIterator res(begin); __gnu_parallel::identity_selector @@ -2129,12 +2091,10 @@ namespace __parallel __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced) { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: - sequence_index_t>(end - begin) - >= __gnu_parallel::Settings:: - min_element_minimal_n - && __gnu_parallel:: - is_parallel(parallelism_tag))) + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::min_element_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) { RandomAccessIterator res(begin); __gnu_parallel::identity_selector diff --git a/libstdc++-v3/include/parallel/algorithmfwd.h b/libstdc++-v3/include/parallel/algorithmfwd.h index f4fc1aca825..f1aa5d71908 100644 --- a/libstdc++-v3/include/parallel/algorithmfwd.h +++ b/libstdc++-v3/include/parallel/algorithmfwd.h @@ -454,8 +454,8 @@ namespace __parallel _RAIter3 transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, random_access_iterator_tag, random_access_iterator_tag, - random_access_iterator_tag, - __gnu_parallel::parallelism parallelism_tag); + random_access_iterator_tag, + __gnu_parallel::parallelism); template _FIter - max_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag); + max_element(_FIter, _FIter, __gnu_parallel::parallelism); template _FIter diff --git a/libstdc++-v3/include/parallel/balanced_quicksort.h b/libstdc++-v3/include/parallel/balanced_quicksort.h index ac05ec70257..70d811526fd 100644 --- a/libstdc++-v3/include/parallel/balanced_quicksort.h +++ b/libstdc++-v3/include/parallel/balanced_quicksort.h @@ -112,8 +112,9 @@ template typedef typename traits_type::value_type value_type; typedef typename traits_type::difference_type difference_type; - RandomAccessIterator pivot_pos = median_of_three_iterators( - begin, begin + (end - begin) / 2, end - 1, comp); + RandomAccessIterator pivot_pos = + median_of_three_iterators(begin, begin + (end - begin) / 2, + end - 1, comp); #if defined(_GLIBCXX_ASSERTIONS) // Must be in between somewhere. @@ -146,9 +147,9 @@ template #if _GLIBCXX_ASSERTIONS RandomAccessIterator r; - for (r = begin; r != pivot_pos; r++) + for (r = begin; r != pivot_pos; ++r) _GLIBCXX_PARALLEL_ASSERT(comp(*r, *pivot_pos)); - for (; r != end; r++) + for (; r != end; ++r) _GLIBCXX_PARALLEL_ASSERT(!comp(*r, *pivot_pos)); #endif @@ -308,12 +309,12 @@ template __gnu_parallel::unary_negate<__gnu_parallel::binder1st , value_type> pred(__gnu_parallel::binder1st - ( - comp, *pivot_pos)); + (comp, + *pivot_pos)); // Find other end of pivot-equal range. - split_pos2 = __gnu_sequential::partition( - split_pos1 + 1, end, pred); + split_pos2 = __gnu_sequential::partition(split_pos1 + 1, + end, pred); } else // Only skip the pivot. @@ -339,8 +340,8 @@ template { // Left side larger. if (begin != split_pos1) - tl.leftover_parts.push_front( - std::make_pair(begin, split_pos1)); + tl.leftover_parts.push_front(std::make_pair(begin, + split_pos1)); current.first = split_pos2; //current.second = end; //already set anyway @@ -394,8 +395,8 @@ template if (omp_get_wtime() >= (search_start + 1.0)) { sleep(1); - _GLIBCXX_PARALLEL_ASSERT( - omp_get_wtime() < (search_start + 1.0)); + _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime() + < (search_start + 1.0)); } #endif if (!successfully_stolen) @@ -452,7 +453,7 @@ template // 2. The largest range has at most length n // 3. Each range is larger than half of the range remaining volatile difference_type 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]->num_threads = num_threads; @@ -468,11 +469,11 @@ template #if _GLIBCXX_ASSERTIONS // All stack must be empty. 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)); #endif - for (int i = 0; i < num_threads; i++) + for (int i = 0; i < num_threads; ++i) delete tls[i]; delete[] tls; } diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h index 5a756cd4be9..8d1c073d4d0 100644 --- a/libstdc++-v3/include/parallel/base.h +++ b/libstdc++-v3/include/parallel/base.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -96,17 +96,13 @@ decode2(lcas_t x, int& a, int& b) template const T& min(const T& a, const T& b) - { - return (a < b) ? a : b; - }; + { return (a < b) ? a : b; } /** @brief Equivalent to std::max. */ template const T& max(const T& a, const T& b) - { - return (a > b) ? a : b; - }; + { return (a > b) ? a : b; } /** @brief Constructs predicate for equality from strict weak * ordering predicate @@ -402,7 +398,7 @@ template * @param comp Comparator. */ template -RandomAccessIterator + RandomAccessIterator median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b, RandomAccessIterator c, Comparator& comp) { diff --git a/libstdc++-v3/include/parallel/compatibility.h b/libstdc++-v3/include/parallel/compatibility.h index cf8e318aa5c..c4e90614109 100644 --- a/libstdc++-v3/include/parallel/compatibility.h +++ b/libstdc++-v3/include/parallel/compatibility.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -105,7 +105,8 @@ namespace __gnu_parallel #elif defined(__ECC) //IA-64 version return _InterlockedExchangeAdd((void*)ptr, addend); #elif defined(__ICL) || defined(_MSC_VER) - return _InterlockedExchangeAdd(reinterpret_cast(ptr), addend); + return _InterlockedExchangeAdd(reinterpret_cast(ptr), + addend); #elif defined(__GNUC__) return __sync_fetch_and_add(ptr, addend); #elif defined(__SUNPRO_CC) && defined(__sparc) @@ -114,7 +115,8 @@ namespace __gnu_parallel { before = *ptr; after = before + addend; - } while (atomic_cas_32((volatile unsigned int*)ptr, before, after) != before); + } while (atomic_cas_32((volatile unsigned int*)ptr, before, + after) != before); return before; #else //fallback, slow #pragma message("slow fetch_and_add_32") @@ -159,7 +161,8 @@ namespace __gnu_parallel { before = *ptr; after = before + addend; - } while (atomic_cas_64((volatile unsigned long long*)ptr, before, after) != before); + } while (atomic_cas_64((volatile unsigned long long*)ptr, before, + after) != before); return before; #else //fallback, slow #if defined(__GNUC__) && defined(__i386) @@ -238,15 +241,19 @@ namespace __gnu_parallel compare_and_swap_32(volatile int32* ptr, int32 comparand, int32 replacement) { #if defined(__ICC) //x86 version - return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand; + return _InterlockedCompareExchange((void*)ptr, replacement, + comparand) == comparand; #elif defined(__ECC) //IA-64 version - return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand; + return _InterlockedCompareExchange((void*)ptr, replacement, + comparand) == comparand; #elif defined(__ICL) || defined(_MSC_VER) - return _InterlockedCompareExchange(reinterpret_cast(ptr), replacement, comparand) == comparand; + return _InterlockedCompareExchange(reinterpret_cast(ptr), + replacement, comparand) == comparand; #elif defined(__GNUC__) return __sync_bool_compare_and_swap(ptr, comparand, replacement); #elif defined(__SUNPRO_CC) && defined(__sparc) - return atomic_cas_32((volatile unsigned int*)ptr, comparand, replacement) == comparand; + return atomic_cas_32((volatile unsigned int*)ptr, comparand, + replacement) == comparand; #else #pragma message("slow compare_and_swap_32") bool res = false; @@ -276,13 +283,15 @@ namespace __gnu_parallel #if defined(__ICC) && defined(__x86_64) //x86 version return cas64(ptr, comparand, replacement) == comparand; #elif defined(__ECC) //IA-64 version - return _InterlockedCompareExchange64((void*)ptr, replacement, comparand) == comparand; + return _InterlockedCompareExchange64((void*)ptr, replacement, + comparand) == comparand; #elif defined(__ICL) || defined(_MSC_VER) #ifndef _WIN64 _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case return 0; #else - return _InterlockedCompareExchange64(ptr, replacement, comparand) == comparand; + return _InterlockedCompareExchange64(ptr, replacement, + comparand) == comparand; #endif #elif defined(__GNUC__) && defined(__x86_64) @@ -291,7 +300,8 @@ namespace __gnu_parallel (defined(__i686) || defined(__pentium4) || defined(__athlon)) return __sync_bool_compare_and_swap(ptr, comparand, replacement); #elif defined(__SUNPRO_CC) && defined(__sparc) - return atomic_cas_64((volatile unsigned long long*)ptr, comparand, replacement) == comparand; + return atomic_cas_64((volatile unsigned long long*)ptr, + comparand, replacement) == comparand; #else #if defined(__GNUC__) && defined(__i386) // XXX -march=native @@ -323,9 +333,11 @@ namespace __gnu_parallel compare_and_swap(volatile T* ptr, T comparand, T replacement) { if (sizeof(T) == 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)) - 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 _GLIBCXX_PARALLEL_ASSERT(false); } diff --git a/libstdc++-v3/include/parallel/find.h b/libstdc++-v3/include/parallel/find.h index 3a0db1ffbe1..051c69ef35b 100644 --- a/libstdc++-v3/include/parallel/find.h +++ b/libstdc++-v3/include/parallel/find.h @@ -62,7 +62,7 @@ template - std::pair + inline std::pair find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, Pred pred, Selector selector) { @@ -70,13 +70,13 @@ template( - begin1 + result, begin2 + result); + return + std::pair(begin1 + result, + begin2 + result); } #endif @@ -205,8 +206,8 @@ template( - length, Settings::find_sequential_search_size); + difference_type sequential_search_size = + std::min(length, Settings::find_sequential_search_size); // Try it sequentially first. std::pair find_seq_result = @@ -267,23 +268,25 @@ template( - block_size * Settings::find_increasing_factor, - Settings::find_maximum_block_size); + block_size = + std::min(block_size + * Settings::find_increasing_factor, + Settings::find_maximum_block_size); // Get new block, update pointer to next block. start = - fetch_and_add(&next_block_start, block_size); - stop = (length < (start + block_size)) ? - length : (start + block_size); + fetch_and_add(&next_block_start, block_size); + stop = ((length < (start + block_size)) + ? length : (start + block_size)); } } //parallel omp_destroy_lock(&result_lock); // Return iterator on found element. - return std::pair( - begin1 + result, begin2 + result); + return + std::pair(begin1 + result, + begin2 + result); } #endif @@ -391,8 +394,9 @@ template( - begin1 + result, begin2 + result); + return + std::pair(begin1 + result, + begin2 + result); } #endif } // end namespace diff --git a/libstdc++-v3/include/parallel/for_each_selectors.h b/libstdc++-v3/include/parallel/for_each_selectors.h index b38aded5cb3..eaa55fc05c6 100644 --- a/libstdc++-v3/include/parallel/for_each_selectors.h +++ b/libstdc++-v3/include/parallel/for_each_selectors.h @@ -57,231 +57,234 @@ namespace __gnu_parallel /** @brief std::for_each() selector. */ template - struct for_each_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. */ - template - bool - operator()(Op& o, It i) - { - o(*i); - return true; - } - }; + struct for_each_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. */ + template + bool + operator()(Op& o, It i) + { + o(*i); + return true; + } + }; /** @brief std::generate() selector. */ template - struct generate_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. */ - template - bool - operator()(Op& o, It i) - { - *i = o(); - return true; - } - }; + struct generate_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. */ + template + bool + operator()(Op& o, It i) + { + *i = o(); + return true; + } + }; /** @brief std::fill() selector. */ template - struct fill_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param v Current value. - * @param i Iterator referencing object. */ - template - bool - operator()(Val& v, It i) - { - *i = v; - return true; - } - }; + struct fill_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param v Current value. + * @param i Iterator referencing object. */ + template + bool + operator()(Val& v, It i) + { + *i = v; + return true; + } + }; /** @brief std::transform() selector, one input sequence variant. */ template - struct transform1_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. */ - template - bool - operator()(Op& o, It i) - { - *i.second = o(*i.first); - return true; - } - }; + struct transform1_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. */ + template + bool + operator()(Op& o, It i) + { + *i.second = o(*i.first); + return true; + } + }; /** @brief std::transform() selector, two input sequences variant. */ template - struct transform2_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. */ - template - bool - operator()(Op& o, It i) - { - *i.third = o(*i.first, *i.second); - return true; - } - }; + struct transform2_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. */ + template + bool + operator()(Op& o, It i) + { + *i.third = o(*i.first, *i.second); + return true; + } + }; /** @brief std::replace() selector. */ template - struct replace_selector : public generic_for_each_selector - { - /** @brief Value to replace with. */ - const T& new_val; - - /** @brief Constructor - * @param new_val Value to replace with. */ - explicit replace_selector(const T &new_val) : new_val(new_val) {} - - /** @brief Functor execution. - * @param v Current value. - * @param i Iterator referencing object. */ - bool - operator()(T& v, It i) + struct replace_selector : public generic_for_each_selector { - if (*i == v) - *i = new_val; - return true; - } - }; + /** @brief Value to replace with. */ + const T& new_val; + + /** @brief Constructor + * @param new_val Value to replace with. */ + explicit + replace_selector(const T &new_val) : new_val(new_val) {} + + /** @brief Functor execution. + * @param v Current value. + * @param i Iterator referencing object. */ + bool + operator()(T& v, It i) + { + if (*i == v) + *i = new_val; + return true; + } + }; /** @brief std::replace() selector. */ template - struct replace_if_selector : public generic_for_each_selector - { - /** @brief Value to replace with. */ - const T& new_val; - - /** @brief Constructor. - * @param new_val Value to replace with. */ - explicit replace_if_selector(const T &new_val) : new_val(new_val) { } - - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. */ - bool - operator()(Op& o, It i) + struct replace_if_selector : public generic_for_each_selector { - if (o(*i)) - *i = new_val; - return true; - } - }; + /** @brief Value to replace with. */ + const T& new_val; + + /** @brief Constructor. + * @param new_val Value to replace with. */ + explicit + replace_if_selector(const T &new_val) : new_val(new_val) { } + + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. */ + bool + operator()(Op& o, It i) + { + if (o(*i)) + *i = new_val; + return true; + } + }; /** @brief std::count() selector. */ template - struct count_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param v Current value. - * @param i Iterator referencing object. - * @return 1 if count, 0 if does not count. */ - template - Diff - operator()(Val& v, It i) - { return (v == *i) ? 1 : 0; } - }; + struct count_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param v Current value. + * @param i Iterator referencing object. + * @return 1 if count, 0 if does not count. */ + template + Diff + operator()(Val& v, It i) + { return (v == *i) ? 1 : 0; } + }; /** @brief std::count_if () selector. */ template - struct count_if_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator. - * @param i Iterator referencing object. - * @return 1 if count, 0 if does not count. */ - template - Diff - operator()(Op& o, It i) - { return (o(*i)) ? 1 : 0; } - }; + struct count_if_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator. + * @param i Iterator referencing object. + * @return 1 if count, 0 if does not count. */ + template + Diff + operator()(Op& o, It i) + { return (o(*i)) ? 1 : 0; } + }; /** @brief std::accumulate() selector. */ template - struct accumulate_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator (unused). - * @param i Iterator referencing object. - * @return The current value. */ - template - typename std::iterator_traits::value_type operator()(Op o, It i) - { return *i; } - }; + struct accumulate_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator (unused). + * @param i Iterator referencing object. + * @return The current value. */ + template + typename std::iterator_traits::value_type operator()(Op o, It i) + { return *i; } + }; /** @brief std::inner_product() selector. */ template - struct inner_product_selector : public generic_for_each_selector - { - /** @brief Begin iterator of first sequence. */ - It begin1_iterator; + struct inner_product_selector : public generic_for_each_selector + { + /** @brief Begin iterator of first sequence. */ + It begin1_iterator; - /** @brief Begin iterator of second sequence. */ - It2 begin2_iterator; + /** @brief Begin iterator of second sequence. */ + It2 begin2_iterator; - /** @brief Constructor. - * @param b1 Begin iterator of first sequence. - * @param b2 Begin iterator of second sequence. */ - explicit inner_product_selector(It b1, It2 b2) - : begin1_iterator(b1), begin2_iterator(b2) { } + /** @brief Constructor. + * @param b1 Begin iterator of first sequence. + * @param b2 Begin iterator of second sequence. */ + explicit + inner_product_selector(It b1, It2 b2) + : begin1_iterator(b1), begin2_iterator(b2) { } - /** @brief Functor execution. - * @param mult Multiplication functor. - * @param current Iterator referencing object. - * @return Inner product elemental result. */ - template - T - operator()(Op mult, It current) - { - typename std::iterator_traits::difference_type position - = current - begin1_iterator; - return mult(*current, *(begin2_iterator + position)); - } - }; + /** @brief Functor execution. + * @param mult Multiplication functor. + * @param current Iterator referencing object. + * @return Inner product elemental result. */ + template + T + operator()(Op mult, It current) + { + typename std::iterator_traits::difference_type position + = current - begin1_iterator; + return mult(*current, *(begin2_iterator + position)); + } + }; /** @brief Selector that just returns the passed iterator. */ template - struct identity_selector : public generic_for_each_selector - { - /** @brief Functor execution. - * @param o Operator (unused). - * @param i Iterator referencing object. - * @return Passed iterator. */ - template - It - operator()(Op o, It i) - { return i; } - }; + struct identity_selector : public generic_for_each_selector + { + /** @brief Functor execution. + * @param o Operator (unused). + * @param i Iterator referencing object. + * @return Passed iterator. */ + template + It + operator()(Op o, It i) + { return i; } + }; /** @brief Selector that returns the difference between two adjacent * elements. */ template - struct adjacent_difference_selector : public generic_for_each_selector - { - template - bool - operator()(Op& o, It i) - { - typename It::first_type go_back_one = i.first; - --go_back_one; - *i.second = o(*i.first, *go_back_one); - return true; - } - }; + struct adjacent_difference_selector : public generic_for_each_selector + { + template + bool + operator()(Op& o, It i) + { + typename It::first_type go_back_one = i.first; + --go_back_one; + *i.second = o(*i.first, *go_back_one); + return true; + } + }; // XXX move into type_traits? /** @brief Functor doing nothing @@ -308,55 +311,56 @@ namespace __gnu_parallel /** @brief Reduction for finding the maximum element, using a comparator. */ template - struct min_element_reduct - { - Comp& comp; - - explicit min_element_reduct(Comp &c) : comp(c) - { } - - It - operator()(It x, It y) + struct min_element_reduct { - if (comp(*x, *y)) - return x; - else - return y; - } - }; + Comp& comp; + + explicit + min_element_reduct(Comp &c) : comp(c) { } + + It + operator()(It x, It y) + { + if (comp(*x, *y)) + return x; + else + return y; + } + }; /** @brief Reduction for finding the maximum element, using a comparator. */ template - struct max_element_reduct - { - Comp& comp; - - explicit max_element_reduct(Comp& c) : comp(c) - { } - - It - operator()(It x, It y) + struct max_element_reduct { - if (comp(*x, *y)) - return y; - else - return x; - } - }; + Comp& comp; + + explicit + max_element_reduct(Comp& c) : comp(c) { } + + It + operator()(It x, It y) + { + if (comp(*x, *y)) + return y; + else + return x; + } + }; /** @brief General reduction, using a binary operator. */ template - struct accumulate_binop_reduct - { - BinOp& binop; + struct accumulate_binop_reduct + { + BinOp& binop; - explicit accumulate_binop_reduct(BinOp& b) : binop(b) {} + explicit + accumulate_binop_reduct(BinOp& b) : binop(b) { } - template - Result - operator()(const Result& x, const Addend& y) - { return binop(x, y); } - }; + template + Result + operator()(const Result& x, const Addend& y) + { return binop(x, y); } + }; } #endif diff --git a/libstdc++-v3/include/parallel/list_partition.h b/libstdc++-v3/include/parallel/list_partition.h index b3461054e4a..0fcc6285c71 100644 --- a/libstdc++-v3/include/parallel/list_partition.h +++ b/libstdc++-v3/include/parallel/list_partition.h @@ -159,7 +159,7 @@ namespace __gnu_parallel // Smallest partitions. 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; starts[i] = os_starts[index]; } @@ -167,7 +167,7 @@ namespace __gnu_parallel // Biggest partitions. 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); starts[i] = os_starts[index]; } diff --git a/libstdc++-v3/include/parallel/losertree.h b/libstdc++-v3/include/parallel/losertree.h index 572688062fc..ddeb0d36d6c 100644 --- a/libstdc++-v3/include/parallel/losertree.h +++ b/libstdc++-v3/include/parallel/losertree.h @@ -82,7 +82,7 @@ template > size = _size; offset = size; losers = new Loser[size]; - for (unsigned int l = 0; l < size; l++) + for (unsigned int l = 0; l < size; ++l) { //losers[l].key = ... stays unset losers[l].inf = true; @@ -156,9 +156,10 @@ template > bool inf = false; for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2) { - if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup && - ((comp(losers[pos].key, key)) || - (!comp(key, losers[pos].key) && losers[pos].source < source))) + if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup + && ((comp(losers[pos].key, key)) + || (!comp(key, losers[pos].key) + && losers[pos].source < source))) || losers[pos].inf || sup) { // Take next key. @@ -186,8 +187,9 @@ template > for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2) { if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup - && ((comp(losers[pos].key, key)) || - (!comp(key, losers[pos].key) && losers[pos].source < source))) + && ((comp(losers[pos].key, key)) + || (!comp(key, losers[pos].key) + && losers[pos].source < source))) || losers[pos].inf || sup) { std::swap(losers[pos].key, key); @@ -285,9 +287,9 @@ template > { unsigned int left = init_winner (2 * root); unsigned int right = init_winner (2 * root + 1); - if (losers[right].sup || - (!losers[left].sup - && !comp(losers[right].key, losers[left].key))) + if (losers[right].sup + || (!losers[left].sup + && !comp(losers[right].key, losers[left].key))) { // Left one is less or equal. losers[root] = losers[right]; @@ -345,7 +347,7 @@ template > unsigned int right = init_winner (2 * root + 1); if (losers[right].sup || (!losers[left].sup - && !comp(losers[right].key, losers[left].key))) + && !comp(losers[right].key, losers[left].key))) { // Left one is less or equal. losers[root] = losers[right]; @@ -443,7 +445,7 @@ template > #ifndef COPY keys = new T[ik]; #endif - for (unsigned int i = ik - 1; i < k; i++) + for (unsigned int i = ik - 1; i < k; ++i) losers[i + k].sup = true; } @@ -569,11 +571,11 @@ template > for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) { // The smaller one gets promoted, ties are broken by source. - if ( (sup && (!losers[pos].sup || losers[pos].source < source)) || - (!sup && !losers[pos].sup && - ((comp(KEY(pos), KEY_SOURCE(source))) || - (!comp(KEY_SOURCE(source), KEY(pos)) - && losers[pos].source < source)))) + if ((sup && (!losers[pos].sup || losers[pos].source < source)) + || (!sup && !losers[pos].sup + && ((comp(KEY(pos), KEY_SOURCE(source))) + || (!comp(KEY_SOURCE(source), KEY(pos)) + && losers[pos].source < source)))) { // The other one is smaller. std::swap(losers[pos].sup, sup); @@ -629,7 +631,7 @@ template > k = 1 << (log2(ik - 1) + 1); offset = k; 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; } @@ -746,11 +748,11 @@ template > for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2) { // The smaller one gets promoted, ties are broken by source. - if ( (sup && (!losers[pos].sup || losers[pos].source < source)) || - (!sup && !losers[pos].sup && - ((comp(*losers[pos].keyp, *keyp)) || - (!comp(*keyp, *losers[pos].keyp) - && losers[pos].source < source)))) + if ( (sup && (!losers[pos].sup || losers[pos].source < source)) + || (!sup && !losers[pos].sup && + ((comp(*losers[pos].keyp, *keyp)) + || (!comp(*keyp, *losers[pos].keyp) + && losers[pos].source < source)))) { // The other one is smaller. std::swap(losers[pos].sup, sup); @@ -995,8 +997,8 @@ template > // Next greater or equal power of 2. unsigned int division = 1 << (log2(end - begin - 1)); unsigned int left = init_winner(2 * root, begin, begin + division); - unsigned int right - = init_winner(2 * root + 1, begin + division, end); + unsigned int right = init_winner(2 * root + 1, + begin + division, end); if (!comp(*losers[right].keyp, *losers[left].keyp)) { // Left one is less or equal. diff --git a/libstdc++-v3/include/parallel/merge.h b/libstdc++-v3/include/parallel/merge.h index 667213045b5..f12f3110871 100644 --- a/libstdc++-v3/include/parallel/merge.h +++ b/libstdc++-v3/include/parallel/merge.h @@ -74,7 +74,7 @@ namespace __gnu_parallel *target++ = *begin2++; else *target++ = *begin1++; - max_length--; + --max_length; } if (begin1 != end1) @@ -143,8 +143,8 @@ namespace __gnu_parallel *target = element1; - target++; - max_length--; + ++target; + --max_length; } if (begin1 != end1) { diff --git a/libstdc++-v3/include/parallel/multiseq_selection.h b/libstdc++-v3/include/parallel/multiseq_selection.h index df5bb870a5c..855d90acdae 100644 --- a/libstdc++-v3/include/parallel/multiseq_selection.h +++ b/libstdc++-v3/include/parallel/multiseq_selection.h @@ -212,7 +212,7 @@ namespace __gnu_parallel difference_type localrank = rank * m / N ; 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; for (; j < m; j++) b[sample[j].second] -= n + 1; @@ -279,7 +279,7 @@ namespace __gnu_parallel if (b[i] < ns[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; pq.pop(); @@ -302,7 +302,7 @@ namespace __gnu_parallel if (a[i] > 0) pq.push(std::make_pair(S(i)[a[i] - 1], i)); - for (; skew != 0; skew++) + for (; skew != 0; ++skew) { int source = pq.top().second; pq.pop(); @@ -416,7 +416,7 @@ namespace __gnu_parallel ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second); 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); nmax = std::max(nmax, ns[i]); @@ -431,7 +431,7 @@ namespace __gnu_parallel // From now on, including padding. N = l * m; - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) { a[i] = 0; b[i] = l; @@ -460,9 +460,9 @@ namespace __gnu_parallel difference_type localrank = rank * m / N ; 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; - for (; j < m; j++) + for (; j < m; ++j) b[sample[j].second] -= n + 1; // Further refinement. @@ -471,7 +471,7 @@ namespace __gnu_parallel n /= 2; const T* lmax = NULL; - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) { if (a[i] > 0) { @@ -496,7 +496,7 @@ namespace __gnu_parallel } difference_type leftsize = 0, total = 0; - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) { leftsize += a[i] / (n + 1); total += l / (n + 1); @@ -512,7 +512,7 @@ namespace __gnu_parallel std::vector >, lexicographic_reverse > pq(lrcomp); - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) if (b[i] < ns[i]) pq.push(std::make_pair(S(i)[b[i]], i)); @@ -535,7 +535,7 @@ namespace __gnu_parallel std::vector >, lexicographic > pq(lcomp); - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) if (a[i] > 0) pq.push(std::make_pair(S(i)[a[i] - 1], i)); @@ -566,7 +566,7 @@ namespace __gnu_parallel // Impossible to avoid the warning? T maxleft, minright; - for (int i = 0; i < m; i++) + for (int i = 0; i < m; ++i) { if (a[i] > 0) { @@ -610,7 +610,7 @@ namespace __gnu_parallel // We have to calculate an offset. 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], minright, diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h index 98f19c2478f..419e96a3b5e 100644 --- a/libstdc++-v3/include/parallel/multiway_merge.h +++ b/libstdc++-v3/include/parallel/multiway_merge.h @@ -73,7 +73,7 @@ template template inline bool operator<=(guarded_iterator& bi1, - guarded_iterator& bi2); + guarded_iterator& bi2); /** @brief Iterator wrapper supporting an implicit supremum at the end of the sequence, dominating all comparisons. @@ -99,14 +99,14 @@ template * @param end End iterator of sequence. * @param comp Comparator provided for associated overloaded * compare operators. */ - inline guarded_iterator(RandomAccessIterator begin, - RandomAccessIterator end, Comparator& comp) + guarded_iterator(RandomAccessIterator begin, + RandomAccessIterator end, Comparator& comp) : current(begin), end(end), comp(comp) { } /** @brief Pre-increment operator. * @return This. */ - inline guarded_iterator& + guarded_iterator& operator++() { ++current; @@ -115,24 +115,24 @@ template /** @brief Dereference operator. * @return Referenced element. */ - inline typename std::iterator_traits::value_type + typename std::iterator_traits::value_type operator*() { return *current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ - inline operator RandomAccessIterator() + operator RandomAccessIterator() { return current; } friend bool operator< ( - guarded_iterator& bi1, - guarded_iterator& bi2); + guarded_iterator& bi1, + guarded_iterator& bi2); friend bool operator<= ( - guarded_iterator& bi1, - guarded_iterator& bi2); + guarded_iterator& bi1, + guarded_iterator& bi2); }; /** @brief Compare two elements referenced by guarded iterators. @@ -158,7 +158,7 @@ template template inline bool operator<=(guarded_iterator& bi1, - guarded_iterator& bi2) + guarded_iterator& bi2) { if (bi2.current == bi2.end) //bi1 is sup return bi1.current != bi1.end; //bi2 is not sup @@ -194,14 +194,14 @@ template * @param begin Begin iterator of sequence. * @param end Unused, only for compatibility. * @param comp Unused, only for compatibility. */ - inline unguarded_iterator(RandomAccessIterator begin, - RandomAccessIterator end, Comparator& comp) + unguarded_iterator(RandomAccessIterator begin, + RandomAccessIterator end, Comparator& comp) : current(begin), comp(comp) { } /** @brief Pre-increment operator. * @return This. */ - inline unguarded_iterator& + unguarded_iterator& operator++() { ++current; @@ -210,25 +210,24 @@ template /** @brief Dereference operator. * @return Referenced element. */ - inline typename std::iterator_traits::value_type + typename std::iterator_traits::value_type operator*() { return *current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ - inline operator RandomAccessIterator() { return current; } friend bool operator< ( - unguarded_iterator& bi1, - unguarded_iterator& bi2); + unguarded_iterator& bi1, + unguarded_iterator& bi2); friend bool operator<= ( - unguarded_iterator& bi1, - unguarded_iterator& bi2); + unguarded_iterator& bi1, + unguarded_iterator& bi2); }; /** @brief Compare two elements referenced by unguarded iterators. @@ -399,18 +398,17 @@ template * @param length Maximum length to merge. * @param stable Unused, stable anyway. * @return End iterator of output sequence. */ -template< - template class iterator, - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template class iterator, + typename RandomAccessIteratorIterator, + typename RandomAccessIterator3, + typename _DifferenceTp, + typename Comparator> RandomAccessIterator3 - multiway_merge_3_variant( - RandomAccessIteratorIterator seqs_begin, - RandomAccessIteratorIterator seqs_end, - RandomAccessIterator3 target, - Comparator comp, _DifferenceTp length, bool stable) + multiway_merge_3_variant(RandomAccessIteratorIterator seqs_begin, + RandomAccessIteratorIterator seqs_end, + RandomAccessIterator3 target, + Comparator comp, _DifferenceTp length, + bool stable) { _GLIBCXX_CALL(length); @@ -483,11 +481,10 @@ template< return target; } -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_3_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -573,12 +570,11 @@ template< * @param length Maximum length to merge. * @param stable Unused, stable anyway. * @return End iterator of output sequence. */ -template< - template class iterator, - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template class iterator, + typename RandomAccessIteratorIterator, + typename RandomAccessIterator3, + typename _DifferenceTp, + typename Comparator> RandomAccessIterator3 multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -680,11 +676,10 @@ template< return target; } -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_4_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -765,11 +760,10 @@ template< * @param stable Stable merging incurs a performance penalty. * @return End iterator of output sequence. */ -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_bubble(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -845,7 +839,8 @@ template< ++target; ++(seqs_begin[source[0]].first); --length; - if (seqs_begin[source[0]].first == seqs_begin[source[0]].second) + if (seqs_begin[source[0]].first + == seqs_begin[source[0]].second) { // Move everything to the left. for (int s = 0; s < nrs - 1; ++s) @@ -870,7 +865,8 @@ template< ++target; ++(seqs_begin[source[0]].first); --length; - if (seqs_begin[source[0]].first == seqs_begin[source[0]].second) + if (seqs_begin[source[0]].first + == seqs_begin[source[0]].second) { for (int s = 0; s < nrs - 1; ++s) { @@ -888,9 +884,9 @@ template< // Sink down. j = 1; - while ((j < nrs) && (comp(fe[j], fe[j - 1]) || - (!comp(fe[j - 1], fe[j]) - && (source[j] < source[j - 1])))) + while ((j < nrs) && (comp(fe[j], fe[j - 1]) + || (!comp(fe[j - 1], fe[j]) + && (source[j] < source[j - 1])))) { std::swap(fe[j - 1], fe[j]); std::swap(source[j - 1], source[j]); @@ -910,7 +906,8 @@ template< ++target; ++seqs_begin[source[0]].first; --length; - if (seqs_begin[source[0]].first == seqs_begin[source[0]].second) + if (seqs_begin[source[0]].first + == seqs_begin[source[0]].second) { for (int s = 0; s < (nrs - 1); ++s) { @@ -954,12 +951,11 @@ template< * @param stable Stable merging incurs a performance penalty. * @return End iterator of output sequence. */ -template< - typename LT, - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -987,7 +983,8 @@ template< for (int t = 0; t < k; ++t) { - if(arbitrary_element == NULL && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0) + if(arbitrary_element == NULL + && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0) arbitrary_element = &(*seqs_begin[t].first); total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]); } @@ -1074,11 +1071,10 @@ template< * @return End iterator of output sequence. * @pre No input will run out of elements during the merge. */ -template< - typename LT, - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, typename Comparator> +template RandomAccessIterator3 multiway_merge_loser_tree_unguarded(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -1190,11 +1186,10 @@ template< return target; } -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_loser_tree_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -1254,17 +1249,16 @@ template< return target_end; } -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_loser_tree_sentinel(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, - RandomAccessIterator3 target, - Comparator comp, - _DifferenceTp length, bool stable) + RandomAccessIterator3 target, + Comparator comp, + _DifferenceTp length, bool stable) { _GLIBCXX_CALL(length) @@ -1326,7 +1320,8 @@ template< /** @brief Sequential multi-way merging switch. * - * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings. + * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and + * runtime settings. * @param seqs_begin Begin iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence. * @param target Begin iterator out output sequence. @@ -1335,11 +1330,10 @@ template< * @param stable Stable merging incurs a performance penalty. * @param sentinel The sequences have a sentinel element. * @return End iterator of output sequence. */ -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -1393,23 +1387,26 @@ template< { case Settings::LOSER_TREE_COMBINED: return_target = multiway_merge_3_combined(seqs_begin, - seqs_end, - target, - comp, length, stable); + seqs_end, + target, + comp, length, + stable); break; case Settings::LOSER_TREE_SENTINEL: - return_target = multiway_merge_3_variant( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = + multiway_merge_3_variant(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; default: - return_target = multiway_merge_3_variant( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = + multiway_merge_3_variant(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; } break; @@ -1417,25 +1414,25 @@ template< switch (mwma) { case Settings::LOSER_TREE_COMBINED: - return_target = multiway_merge_4_combined( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = multiway_merge_4_combined(seqs_begin, + seqs_end, + target, + comp, length, stable); break; case Settings::LOSER_TREE_SENTINEL: - return_target = multiway_merge_4_variant( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = + multiway_merge_4_variant(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; default: return_target = multiway_merge_4_variant( - seqs_begin, - seqs_end, - target, - comp, length, stable); + seqs_begin, + seqs_end, + target, + comp, length, stable); break; } break; @@ -1444,48 +1441,47 @@ template< switch (mwma) { case Settings::BUBBLE: - return_target = multiway_merge_bubble( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = multiway_merge_bubble(seqs_begin, + seqs_end, + target, + comp, length, stable); break; #if _GLIBCXX_LOSER_TREE_EXPLICIT case Settings::LOSER_TREE_EXPLICIT: return_target = multiway_merge_loser_tree< - LoserTreeExplicit >( - seqs_begin, - seqs_end, - target, - comp, length, stable); + LoserTreeExplicit >(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; #endif #if _GLIBCXX_LOSER_TREE case Settings::LOSER_TREE: return_target = multiway_merge_loser_tree< - LoserTree >( - seqs_begin, - seqs_end, - target, - comp, length, stable); + LoserTree >(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; #endif #if _GLIBCXX_LOSER_TREE_COMBINED case Settings::LOSER_TREE_COMBINED: - return_target = multiway_merge_loser_tree_combined( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = multiway_merge_loser_tree_combined(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; #endif #if _GLIBCXX_LOSER_TREE_SENTINEL case Settings::LOSER_TREE_SENTINEL: - return_target = multiway_merge_loser_tree_sentinel( - seqs_begin, - seqs_end, - target, - comp, length, stable); + return_target = multiway_merge_loser_tree_sentinel(seqs_begin, + seqs_end, + target, + comp, length, + stable); break; #endif default: @@ -1504,7 +1500,8 @@ template< /** @brief Parallel multi-way merge routine. * - * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings. + * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor + * and runtime settings. * @param seqs_begin Begin iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence. * @param target Begin iterator out output sequence. @@ -1514,11 +1511,10 @@ template< * @param sentinel Ignored. * @return End iterator of output sequence. */ -template< - typename RandomAccessIteratorIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, @@ -1553,7 +1549,7 @@ template< std::vector >* pieces; thread_index_t num_threads = static_cast( - std::min(get_max_threads(), total_length)); + std::min(get_max_threads(), total_length)); # pragma omp parallel num_threads (num_threads) { @@ -1578,20 +1574,20 @@ template< for (difference_type i = 0; i < num_samples; ++i) { difference_type sample_index = - static_cast( - _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) * (double(i + 1) / - (num_samples + 1)) * (double(length) - / total_length)); - ::new(&(samples[s * num_samples + i])) value_type( - seqs_begin[s].first[sample_index]); + static_cast( + _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) + * (double(i + 1) / (num_samples + 1)) + * (double(length) / total_length)); + ::new(&(samples[s * num_samples + i])) + value_type(seqs_begin[s].first[sample_index]); } if (stable) - __gnu_sequential::stable_sort( - samples, samples + (num_samples * k), comp); + __gnu_sequential::stable_sort(samples, samples + + (num_samples * k), comp); else - __gnu_sequential::sort( - samples, samples + (num_samples * k), comp); + __gnu_sequential::sort(samples, samples + + (num_samples * k), comp); for (int slab = 0; slab < num_threads; ++slab) // For each slab / processor. @@ -1600,12 +1596,12 @@ template< // For each sequence. if (slab > 0) pieces[slab][seq].first = - std::upper_bound( - seqs_begin[seq].first, - seqs_begin[seq].second, - samples[num_samples * k * slab / num_threads], - comp) - - seqs_begin[seq].first; + std::upper_bound(seqs_begin[seq].first, + seqs_begin[seq].second, + samples[num_samples * k + * slab / num_threads], + comp) + - seqs_begin[seq].first; else { // Absolute beginning. @@ -1613,14 +1609,15 @@ template< } if ((slab + 1) < num_threads) pieces[slab][seq].second = - std::upper_bound( - seqs_begin[seq].first, - seqs_begin[seq].second, - samples[num_samples * k * (slab + 1) / - num_threads], comp) - - seqs_begin[seq].first; + std::upper_bound(seqs_begin[seq].first, + seqs_begin[seq].second, + samples[num_samples * k + * (slab + 1) + / num_threads], comp) + - seqs_begin[seq].first; else - pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]); + pieces[slab][seq].second + = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]); } ::operator delete(samples); } @@ -1651,8 +1648,9 @@ template< { offsets[num_threads - 1].resize(k); multiseq_partition(se.begin(), se.end(), - difference_type(length), - offsets[num_threads - 1].begin(), comp); + difference_type(length), + offsets[num_threads - 1].begin(), + comp); } } @@ -1673,12 +1671,12 @@ template< pieces[slab - 1][seq].second; if (!tight || slab < (num_threads - 1)) pieces[slab][seq].second = - offsets[slab][seq] - seqs_begin[seq].first; + offsets[slab][seq] - seqs_begin[seq].first; else { // slab == num_threads - 1 pieces[slab][seq].second = - _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]); + _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]); } } } @@ -1703,8 +1701,8 @@ template< for (int s = 0; s < k; ++s) { chunks[s] = std::make_pair( - seqs_begin[s].first + pieces[iam][s].first, - seqs_begin[s].first + pieces[iam][s].second); + seqs_begin[s].first + pieces[iam][s].first, + seqs_begin[s].first + pieces[iam][s].second); local_length += _GLIBCXX_PARALLEL_LENGTH(chunks[s]); } @@ -1721,13 +1719,13 @@ template< begin0 = seqs_begin[0].first + pieces[iam][0].first, begin1 = seqs_begin[1].first + pieces[iam][1].first; merge_advance(begin0, - seqs_begin[0].first + pieces[iam][0].second, - begin1, - seqs_begin[1].first + pieces[iam][1].second, - target + target_position, - (pieces[iam][0].second - pieces[iam][0].first) + - (pieces[iam][1].second - pieces[iam][1].first), - comp); + seqs_begin[0].first + pieces[iam][0].second, + begin1, + seqs_begin[1].first + pieces[iam][1].second, + target + target_position, + (pieces[iam][0].second - pieces[iam][0].first) + + (pieces[iam][1].second - pieces[iam][1].first), + comp); } } //parallel @@ -1754,11 +1752,10 @@ template< * @param stable Stable merging incurs a performance penalty. * @return End iterator of output sequence. */ -template< - typename RandomAccessIteratorPairIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, @@ -1775,13 +1772,13 @@ template< if (_GLIBCXX_PARALLEL_CONDITION( ((seqs_end - seqs_begin) >= Settings::multiway_merge_minimal_k) && ((sequence_index_t)length >= Settings::multiway_merge_minimal_n))) - target_end = parallel_multiway_merge( - seqs_begin, seqs_end, - target, comp, static_cast(length), stable, false); + target_end = parallel_multiway_merge(seqs_begin, seqs_end, + target, comp, + static_cast(length), + stable, false); else - target_end = multiway_merge( - seqs_begin, seqs_end, - target, comp, length, stable, false, sequential_tag()); + target_end = multiway_merge(seqs_begin, seqs_end, target, comp, length, + stable, false, sequential_tag()); return target_end; } @@ -1797,11 +1794,10 @@ template< * @pre For each @c i, @c seqs_begin[i].second must be the end * marker of the sequence, but also reference the one more sentinel * element. */ -template< - typename RandomAccessIteratorPairIterator, - typename RandomAccessIterator3, - typename _DifferenceTp, - typename Comparator> +template RandomAccessIterator3 multiway_merge_sentinel(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, @@ -1824,9 +1820,9 @@ template< seqs_begin, seqs_end, target, comp, static_cast(length), stable, true); else - return multiway_merge( - seqs_begin, seqs_end, - target, comp, length, stable, true, sequential_tag()); + return multiway_merge(seqs_begin, seqs_end, + target, comp, length, stable, + true, sequential_tag()); } } diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h index 502cfab4557..923a2a89944 100644 --- a/libstdc++-v3/include/parallel/multiway_mergesort.h +++ b/libstdc++-v3/include/parallel/multiway_mergesort.h @@ -120,7 +120,7 @@ template * @param num_samples Number of samples to select. */ template - inline void + void determine_samples(PMWMSSortingData* sd, _DifferenceTp& num_samples) { @@ -138,9 +138,9 @@ template equally_split(sd->starts[iam + 1] - sd->starts[iam], num_samples + 1, es); - for (difference_type i = 0; i < num_samples; i++) - ::new(&(sd->samples[iam * num_samples + i])) value_type( - sd->source[sd->starts[iam] + es[i + 1]]); + for (difference_type i = 0; i < num_samples; ++i) + ::new(&(sd->samples[iam * num_samples + i])) + value_type(sd->source[sd->starts[iam] + es[i + 1]]); delete[] es; } @@ -150,7 +150,7 @@ template * @param comp Comparator. */ template - inline void + void parallel_sort_mwms_pu(PMWMSSortingData* sd, Comparator& comp) { @@ -209,7 +209,7 @@ template # pragma omp barrier - for (int s = 0; s < sd->num_threads; s++) + for (int s = 0; s < sd->num_threads; ++s) { // For each sequence. if (num_samples * iam > 0) @@ -243,7 +243,7 @@ template std::vector > seqs(sd->num_threads); - for (int s = 0; s < sd->num_threads; s++) + for (int s = 0; s < sd->num_threads; ++s) seqs[s] = std::make_pair(sd->sorting_places[s], sd->sorting_places[s] + (sd->starts[s + 1] - sd->starts[s])); @@ -255,20 +255,20 @@ template multiseq_partition(seqs.begin(), seqs.end(), sd->starts[iam + 1], offsets.begin(), comp); - for (int seq = 0; seq < sd->num_threads; seq++) + for (int seq = 0; seq < sd->num_threads; ++seq) { // for each sequence if (iam < (sd->num_threads - 1)) sd->pieces[iam][seq].end = offsets[seq] - seqs[seq].first; else // very end of this sequence - sd->pieces[iam][seq].end = - sd->starts[seq + 1] - sd->starts[seq]; + sd->pieces[iam][seq].end = (sd->starts[seq + 1] + - sd->starts[seq]); } # pragma omp barrier - for (int seq = 0; seq < sd->num_threads; seq++) + for (int seq = 0; seq < sd->num_threads; ++seq) { // For each sequence. if (iam > 0) @@ -281,7 +281,7 @@ template // Offset from target begin, length after merging. difference_type offset = 0, length_am = 0; - for (int s = 0; s < sd->num_threads; s++) + for (int s = 0; s < sd->num_threads; ++s) { length_am += sd->pieces[iam][s].end - sd->pieces[iam][s].begin; offset += sd->pieces[iam][s].begin; @@ -293,8 +293,8 @@ template // instead of the assignment operator. // XXX incorrect (de)construction sd->merging_places[iam] = sd->temporaries[iam] = - static_cast( - ::operator new(sizeof(value_type) * length_am)); + static_cast(::operator new(sizeof(value_type) + * length_am)); #else // Merge directly to target. sd->merging_places[iam] = sd->source + offset; @@ -302,11 +302,11 @@ template std::vector > seqs(sd->num_threads); - for (int s = 0; s < sd->num_threads; s++) + for (int s = 0; s < sd->num_threads; ++s) { seqs[s] = - std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin, - sd->sorting_places[s] + sd->pieces[iam][s].end); + std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin, + sd->sorting_places[s] + sd->pieces[iam][s].end); } multiway_merge(seqs.begin(), seqs.end(), sd->merging_places[iam], comp, @@ -333,13 +333,11 @@ template * @param stable Stable sorting. */ template - inline void + void parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end, - Comparator comp, - typename std::iterator_traits - ::difference_type n, - int num_threads, - bool stable) + Comparator comp, typename + std::iterator_traits:: + difference_type n, int num_threads, bool stable) { _GLIBCXX_CALL(n) @@ -382,14 +380,14 @@ template (Settings::sort_mwms_oversampling * num_threads - 1) * num_threads; sd.samples = static_cast( - ::operator new(size * sizeof(value_type))); + ::operator new(size * sizeof(value_type))); } else sd.samples = NULL; sd.offsets = new difference_type[num_threads - 1]; sd.pieces = new std::vector >[num_threads]; - for (int s = 0; s < num_threads; s++) + for (int s = 0; s < num_threads; ++s) sd.pieces[s].resize(num_threads); starts = sd.starts = new difference_type[num_threads + 1]; sd.stable = stable; @@ -397,7 +395,7 @@ template difference_type chunk_length = n / num_threads; difference_type split = n % num_threads; difference_type pos = 0; - for (int i = 0; i < num_threads; i++) + for (int i = 0; i < num_threads; ++i) { starts[i] = pos; pos += (i < split) ? (chunk_length + 1) : chunk_length; diff --git a/libstdc++-v3/include/parallel/numeric b/libstdc++-v3/include/parallel/numeric index 21b8eea3fdd..ccbdeee12c4 100644 --- a/libstdc++-v3/include/parallel/numeric +++ b/libstdc++-v3/include/parallel/numeric @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -58,387 +58,449 @@ namespace __parallel { // Sequential fallback. template - inline T - accumulate(InputIterator begin, InputIterator end, T init, - __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::accumulate(begin, end, init); } + inline T + accumulate(InputIterator begin, InputIterator end, T init, + __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::accumulate(begin, end, init); } template - inline T - accumulate(InputIterator begin, InputIterator end, T init, - BinaryOperation binary_op, __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); } + inline T + accumulate(InputIterator begin, InputIterator end, T init, + BinaryOperation binary_op, __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); } // Sequential fallback for input iterator case. template - inline T - accumulate_switch(InputIterator begin, InputIterator end, T init, IteratorTag) { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); } + inline T + accumulate_switch(InputIterator begin, InputIterator end, + T init, IteratorTag) + { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); } - template - T - accumulate_switch(InputIterator begin, InputIterator end, T init, - BinaryOperation binary_op, IteratorTag) - { - return accumulate(begin, end, init, binary_op, - __gnu_parallel::sequential_tag()); - } + template + T + accumulate_switch(InputIterator begin, InputIterator end, T init, + BinaryOperation binary_op, IteratorTag) + { return accumulate(begin, end, init, binary_op, + __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. - template - T - accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end, - T init, BinaryOperation binary_op, - random_access_iterator_tag, - __gnu_parallel::parallelism parallelism_tag - = __gnu_parallel::parallel_unbalanced) - { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag))) - { - T res = init; - __gnu_parallel::accumulate_selector<_RandomAccessIterator> my_selector; - __gnu_parallel::for_each_template_random_access(begin, end, __gnu_parallel::nothing(), my_selector, __gnu_parallel::accumulate_binop_reduct(binary_op), res, res, -1, parallelism_tag); - return res; - } - else - return accumulate(begin, end, init, binary_op, - __gnu_parallel::sequential_tag()); - } + template + T + accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end, + T init, BinaryOperation binary_op, + random_access_iterator_tag, + __gnu_parallel::parallelism parallelism_tag + = __gnu_parallel::parallel_unbalanced) + { + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::accumulate_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) + { + T res = init; + __gnu_parallel::accumulate_selector<_RandomAccessIterator> + my_selector; + __gnu_parallel:: + for_each_template_random_access(begin, end, + __gnu_parallel::nothing(), + my_selector, + __gnu_parallel:: + accumulate_binop_reduct + (binary_op), + res, res, -1, parallelism_tag); + return res; + } + else + return accumulate(begin, end, init, binary_op, + __gnu_parallel::sequential_tag()); + } // Public interface. template - inline T - accumulate(InputIterator begin, InputIterator end, T init, - __gnu_parallel::parallelism parallelism_tag) - { - typedef std::iterator_traits iterator_traits; - typedef typename iterator_traits::value_type value_type; - typedef typename iterator_traits::iterator_category iterator_category; + inline T + accumulate(InputIterator begin, InputIterator end, T init, + __gnu_parallel::parallelism parallelism_tag) + { + typedef std::iterator_traits iterator_traits; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, __gnu_parallel::plus(), - iterator_category(), parallelism_tag); - } + return accumulate_switch(begin, end, init, + __gnu_parallel::plus(), + iterator_category(), parallelism_tag); + } template - inline T - accumulate(InputIterator begin, InputIterator end, T init) - { - typedef std::iterator_traits iterator_traits; - typedef typename iterator_traits::value_type value_type; - typedef typename iterator_traits::iterator_category iterator_category; + inline T + accumulate(InputIterator begin, InputIterator end, T init) + { + typedef std::iterator_traits iterator_traits; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, __gnu_parallel::plus(), - iterator_category()); - } + return accumulate_switch(begin, end, init, + __gnu_parallel::plus(), + iterator_category()); + } template - inline T - accumulate(InputIterator begin, InputIterator end, T init, - BinaryOperation binary_op, - __gnu_parallel::parallelism parallelism_tag) - { - typedef iterator_traits iterator_traits; - typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, binary_op, - iterator_category(), parallelism_tag); - } + inline T + accumulate(InputIterator begin, InputIterator end, T init, + BinaryOperation binary_op, + __gnu_parallel::parallelism parallelism_tag) + { + typedef iterator_traits iterator_traits; + typedef typename iterator_traits::iterator_category iterator_category; + return accumulate_switch(begin, end, init, binary_op, + iterator_category(), parallelism_tag); + } template - inline T - accumulate(InputIterator begin, InputIterator end, T init, - BinaryOperation binary_op) - { - typedef iterator_traits iterator_traits; - typedef typename iterator_traits::iterator_category iterator_category; - return accumulate_switch(begin, end, init, binary_op, - iterator_category()); - } + inline T + accumulate(InputIterator begin, InputIterator end, T init, + BinaryOperation binary_op) + { + typedef iterator_traits iterator_traits; + typedef typename iterator_traits::iterator_category iterator_category; + return accumulate_switch(begin, end, init, binary_op, + iterator_category()); + } // Sequential fallback. template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); } + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); } - template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, BinaryFunction1 binary_op1, - BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag) - { - return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init, - binary_op1, binary_op2); - } + template + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, BinaryFunction1 binary_op1, + BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init, + binary_op1, binary_op2); } // Parallel algorithm for random access iterators. - template - T - inner_product_switch(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, T init, BinaryFunction1 binary_op1, BinaryFunction2 binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced) - { - if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag))) - { - T res = init; - __gnu_parallel::inner_product_selector my_selector(first1, first2); - __gnu_parallel::for_each_template_random_access(first1, last1, binary_op2, my_selector, binary_op1, res, res, -1, parallelism_tag); - return res; - } - else - return inner_product(first1, last1, first2, init, - __gnu_parallel::sequential_tag()); - } + template + T + inner_product_switch(RandomAccessIterator1 first1, + RandomAccessIterator1 last1, + RandomAccessIterator2 first2, T init, + BinaryFunction1 binary_op1, + BinaryFunction2 binary_op2, + random_access_iterator_tag, + random_access_iterator_tag, + __gnu_parallel::parallelism parallelism_tag + = __gnu_parallel::parallel_unbalanced) + { + if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) + >= __gnu_parallel::Settings:: + accumulate_minimal_n + && __gnu_parallel:: + is_parallel(parallelism_tag))) + { + T res = init; + __gnu_parallel:: + inner_product_selector my_selector(first1, first2); + __gnu_parallel:: + for_each_template_random_access(first1, last1, binary_op2, + my_selector, binary_op1, + res, res, -1, parallelism_tag); + return res; + } + else + return inner_product(first1, last1, first2, init, + __gnu_parallel::sequential_tag()); + } // No parallelism for input iterators. - template - inline T - inner_product_switch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, - BinaryFunction1 binary_op1, BinaryFunction2 binary_op2, - IteratorTag1, IteratorTag2) - { - return inner_product(first1, last1, first2, init, binary_op1, binary_op2, - __gnu_parallel::sequential_tag()); - } + template + inline T + inner_product_switch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryFunction1 binary_op1, + BinaryFunction2 binary_op2, + IteratorTag1, IteratorTag2) + { return inner_product(first1, last1, first2, init, + binary_op1, binary_op2, + __gnu_parallel::sequential_tag()); } - template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, BinaryFunction1 binary_op1, - BinaryFunction2 binary_op2, - __gnu_parallel::parallelism parallelism_tag) - { - typedef iterator_traits traits1_type; - typedef typename traits1_type::iterator_category iterator1_category; + template + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, BinaryFunction1 binary_op1, + BinaryFunction2 binary_op2, + __gnu_parallel::parallelism parallelism_tag) + { + typedef iterator_traits traits1_type; + typedef typename traits1_type::iterator_category iterator1_category; - typedef iterator_traits traits2_type; - typedef typename traits2_type::iterator_category iterator2_category; + typedef iterator_traits traits2_type; + typedef typename traits2_type::iterator_category iterator2_category; - return inner_product_switch(first1, last1, first2, init, binary_op1, - binary_op2, iterator1_category(), - iterator2_category(), parallelism_tag); - } + return inner_product_switch(first1, last1, first2, init, binary_op1, + binary_op2, iterator1_category(), + iterator2_category(), parallelism_tag); + } - template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, BinaryFunction1 binary_op1, - BinaryFunction2 binary_op2) - { - typedef iterator_traits traits1_type; - typedef typename traits1_type::iterator_category iterator1_category; + template + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, BinaryFunction1 binary_op1, + BinaryFunction2 binary_op2) + { + typedef iterator_traits traits1_type; + typedef typename traits1_type::iterator_category iterator1_category; - typedef iterator_traits traits2_type; - typedef typename traits2_type::iterator_category iterator2_category; + typedef iterator_traits traits2_type; + typedef typename traits2_type::iterator_category iterator2_category; - return inner_product_switch(first1, last1, first2, init, binary_op1, - binary_op2, iterator1_category(), - iterator2_category()); - } + return inner_product_switch(first1, last1, first2, init, binary_op1, + binary_op2, iterator1_category(), + iterator2_category()); + } template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, - __gnu_parallel::parallelism parallelism_tag) - { - typedef iterator_traits traits_type1; - typedef typename traits_type1::value_type value_type1; - typedef iterator_traits traits_type2; - typedef typename traits_type2::value_type value_type2; + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + __gnu_parallel::parallelism parallelism_tag) + { + typedef iterator_traits traits_type1; + typedef typename traits_type1::value_type value_type1; + typedef iterator_traits traits_type2; + typedef typename traits_type2::value_type value_type2; - typedef typename __gnu_parallel::multiplies::result + typedef typename + __gnu_parallel::multiplies::result multiplies_result_type; - return inner_product(first1, last1, first2, init, + return inner_product(first1, last1, first2, init, __gnu_parallel::plus(), - __gnu_parallel::multiplies(), + __gnu_parallel:: + multiplies(), parallelism_tag); - } + } template - inline T - inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init) - { - typedef iterator_traits traits_type1; - typedef typename traits_type1::value_type value_type1; - typedef iterator_traits traits_type2; - typedef typename traits_type2::value_type value_type2; + inline T + inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init) + { + typedef iterator_traits traits_type1; + typedef typename traits_type1::value_type value_type1; + typedef iterator_traits traits_type2; + typedef typename traits_type2::value_type value_type2; - typedef typename __gnu_parallel::multiplies::result + typedef typename + __gnu_parallel::multiplies::result multiplies_result_type; - return inner_product(first1, last1, first2, init, + return inner_product(first1, last1, first2, init, __gnu_parallel::plus(), - __gnu_parallel::multiplies()); - } + __gnu_parallel:: + multiplies()); + } // Sequential fallback. template - inline OutputIterator - partial_sum(InputIterator begin, InputIterator end, OutputIterator result, - __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::partial_sum(begin, end, result); } + inline OutputIterator + partial_sum(InputIterator begin, InputIterator end, OutputIterator result, + __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::partial_sum(begin, end, result); } // Sequential fallback. - template - inline OutputIterator - partial_sum(InputIterator begin, InputIterator end, OutputIterator result, - BinaryOperation bin_op, __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); } + template + inline OutputIterator + partial_sum(InputIterator begin, InputIterator end, OutputIterator result, + BinaryOperation bin_op, __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); } // Sequential fallback for input iterator case. - template - inline OutputIterator - partial_sum_switch(InputIterator begin, InputIterator end, OutputIterator result, BinaryOperation bin_op, IteratorTag1, IteratorTag2) - { - return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); - } + template + inline OutputIterator + partial_sum_switch(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + IteratorTag1, IteratorTag2) + { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); } // Parallel algorithm for random access iterators. - template - OutputIterator - partial_sum_switch(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, - random_access_iterator_tag, random_access_iterator_tag) - { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partial_sum_minimal_n)) - return __gnu_parallel::parallel_partial_sum(begin, end, result, bin_op); - else - return partial_sum(begin, end, result, bin_op, __gnu_parallel::sequential_tag()); - } + template + OutputIterator + partial_sum_switch(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + random_access_iterator_tag, random_access_iterator_tag) + { + if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel:: + sequence_index_t>(end - begin) + >= __gnu_parallel::Settings:: + partial_sum_minimal_n)) + return __gnu_parallel::parallel_partial_sum(begin, end, + result, bin_op); + else + return partial_sum(begin, end, result, bin_op, + __gnu_parallel::sequential_tag()); + } // Public interface. template - inline OutputIterator - partial_sum(InputIterator begin, InputIterator end, OutputIterator result) - { - typedef typename iterator_traits::value_type value_type; - return partial_sum(begin, end, result, std::plus()); - } + inline OutputIterator + partial_sum(InputIterator begin, InputIterator end, OutputIterator result) + { + typedef typename iterator_traits::value_type value_type; + return partial_sum(begin, end, result, std::plus()); + } // Public interface - template - inline OutputIterator - partial_sum(InputIterator begin, InputIterator end, OutputIterator result, - BinaryOperation binary_op) - { - typedef iterator_traits traitsi_type; - typedef typename traitsi_type::iterator_category iteratori_category; + template + inline OutputIterator + partial_sum(InputIterator begin, InputIterator end, OutputIterator result, + BinaryOperation binary_op) + { + typedef iterator_traits traitsi_type; + typedef typename traitsi_type::iterator_category iteratori_category; - typedef iterator_traits traitso_type; - typedef typename traitso_type::iterator_category iteratoro_category; + typedef iterator_traits traitso_type; + typedef typename traitso_type::iterator_category iteratoro_category; - return partial_sum_switch(begin, end, result, binary_op, - iteratori_category(), iteratoro_category()); - } + return partial_sum_switch(begin, end, result, binary_op, + iteratori_category(), iteratoro_category()); + } // Sequential fallback. template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result, __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); } + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result, __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); } // Sequential fallback. - template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, - __gnu_parallel::sequential_tag) - { - return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); - } + template + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); } // Sequential fallback for input iterator case. - template - inline OutputIterator - adjacent_difference_switch(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, + template + inline OutputIterator + adjacent_difference_switch(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, IteratorTag1, IteratorTag2) - { - return adjacent_difference(begin, end, result, bin_op, - __gnu_parallel::sequential_tag()); - } + { return adjacent_difference(begin, end, result, bin_op, + __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. - template - OutputIterator - adjacent_difference_switch(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, - random_access_iterator_tag, - random_access_iterator_tag, - __gnu_parallel::parallelism parallelism_tag - = __gnu_parallel::parallel_balanced) - { - if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::adjacent_difference_minimal_n && __gnu_parallel::is_parallel(parallelism_tag))) - { - bool dummy = true; - typedef __gnu_parallel::iterator_pair ip; - *result = *begin; - ip begin_pair(begin + 1, result + 1), end_pair(end, result + (end - begin)); - __gnu_parallel::adjacent_difference_selector functionality; - __gnu_parallel::for_each_template_random_access(begin_pair, end_pair, bin_op, functionality, __gnu_parallel::dummy_reduct(), dummy, dummy, -1, parallelism_tag); - return functionality.finish_iterator; - } - else - return adjacent_difference(begin, end, result, bin_op, - __gnu_parallel::sequential_tag()); - } + template + OutputIterator + adjacent_difference_switch(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + random_access_iterator_tag, + random_access_iterator_tag, + __gnu_parallel::parallelism parallelism_tag + = __gnu_parallel::parallel_balanced) + { + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::sequence_index_t>(end - begin) + >= __gnu_parallel::Settings::adjacent_difference_minimal_n + && __gnu_parallel::is_parallel(parallelism_tag))) + { + bool dummy = true; + typedef __gnu_parallel::iterator_pair ip; + *result = *begin; + ip begin_pair(begin + 1, result + 1), + end_pair(end, result + (end - begin)); + __gnu_parallel::adjacent_difference_selector functionality; + __gnu_parallel:: + for_each_template_random_access(begin_pair, end_pair, bin_op, + functionality, + __gnu_parallel::dummy_reduct(), + dummy, dummy, -1, parallelism_tag); + return functionality.finish_iterator; + } + else + return adjacent_difference(begin, end, result, bin_op, + __gnu_parallel::sequential_tag()); + } // Public interface. template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result, - __gnu_parallel::parallelism parallelism_tag) - { - typedef iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - return adjacent_difference(begin, end, result, std::minus(), - parallelism_tag); - } + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result, + __gnu_parallel::parallelism parallelism_tag) + { + typedef iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + return adjacent_difference(begin, end, result, std::minus(), + parallelism_tag); + } template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result) - { - typedef iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - return adjacent_difference(begin, end, result, std::minus()); - } + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result) + { + typedef iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + return adjacent_difference(begin, end, result, std::minus()); + } - template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation binary_op, - __gnu_parallel::parallelism parallelism_tag) - { - typedef iterator_traits traitsi_type; - typedef typename traitsi_type::iterator_category iteratori_category; + template + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation binary_op, + __gnu_parallel::parallelism parallelism_tag) + { + typedef iterator_traits traitsi_type; + typedef typename traitsi_type::iterator_category iteratori_category; - typedef iterator_traits traitso_type; - typedef typename traitso_type::iterator_category iteratoro_category; + typedef iterator_traits traitso_type; + typedef typename traitso_type::iterator_category iteratoro_category; - return adjacent_difference_switch(begin, end, result, binary_op, - iteratori_category(), - iteratoro_category(), parallelism_tag); - } + return adjacent_difference_switch(begin, end, result, binary_op, + iteratori_category(), + iteratoro_category(), parallelism_tag); + } - template - inline OutputIterator - adjacent_difference(InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation binary_op) - { - typedef iterator_traits traitsi_type; - typedef typename traitsi_type::iterator_category iteratori_category; + template + inline OutputIterator + adjacent_difference(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation binary_op) + { + typedef iterator_traits traitsi_type; + typedef typename traitsi_type::iterator_category iteratori_category; - typedef iterator_traits traitso_type; - typedef typename traitso_type::iterator_category iteratoro_category; + typedef iterator_traits traitso_type; + typedef typename traitso_type::iterator_category iteratoro_category; - return adjacent_difference_switch(begin, end, result, binary_op, - iteratori_category(), - iteratoro_category()); - } + return adjacent_difference_switch(begin, end, result, binary_op, + iteratori_category(), + iteratoro_category()); + } } // end namespace } // end namespace diff --git a/libstdc++-v3/include/parallel/numericfwd.h b/libstdc++-v3/include/parallel/numericfwd.h index 4181132c13a..f693a60a3bd 100644 --- a/libstdc++-v3/include/parallel/numericfwd.h +++ b/libstdc++-v3/include/parallel/numericfwd.h @@ -1,6 +1,6 @@ // parallel extensions -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -44,146 +44,162 @@ namespace std { namespace __parallel { - template - inline T - accumulate(_IIter, _IIter, T); + template + _Tp + accumulate(_IIter, _IIter, _Tp); - template - inline T - accumulate(_IIter, _IIter, T, __gnu_parallel::sequential_tag); + template + _Tp + accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag); - template - inline T - accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism parallelism_tag); + template + _Tp + accumulate(_IIter, _IIter, _Tp, __gnu_parallel::parallelism); - template - inline T - accumulate_switch(_IIter, _IIter, T, _Tag); + template + _Tp + accumulate_switch(_IIter, _IIter, _Tp, _Tag); - template - inline T - accumulate(_IIter, _IIter, T, _BinaryOper); + template + _Tp + accumulate(_IIter, _IIter, _Tp, _BinaryOper); - template - inline T - accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::sequential_tag); + template + _Tp + accumulate(_IIter, _IIter, _Tp, _BinaryOper, + __gnu_parallel::sequential_tag); - template - inline T - accumulate(_IIter, _IIter, T, _BinaryOper, - __gnu_parallel::parallelism parallelism_tag); + template + _Tp + accumulate(_IIter, _IIter, _Tp, _BinaryOper, + __gnu_parallel::parallelism); - template - T - accumulate_switch(_IIter, _IIter, T, _BinaryOper, _Tag); + template + _Tp + accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag); - template - T - accumulate_switch(_RAIter, _RAIter, T, _BinaryOper, - random_access_iterator_tag, __gnu_parallel::parallelism); - - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter); - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper); - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, - __gnu_parallel::sequential_tag); - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::parallelism); - - template - inline _OIter - adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, + template + _Tp + accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper, + random_access_iterator_tag, __gnu_parallel::parallelism); - template - inline _OIter - adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); + template + _OIter + adjacent_difference(_IIter, _IIter, _OIter); template - _OIter - adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, - random_access_iterator_tag, - random_access_iterator_tag, - __gnu_parallel::parallelism); + _OIter + adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper); + + template + _OIter + adjacent_difference(_IIter, _IIter, _OIter, + __gnu_parallel::sequential_tag); + + template + _OIter + adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, + __gnu_parallel::sequential_tag); + + template + _OIter + adjacent_difference(_IIter, _IIter, _OIter, + __gnu_parallel::parallelism); + + template + _OIter + adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, + __gnu_parallel::parallelism); + + template + _OIter + adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, + _Tag1, _Tag2); + + template + _OIter + adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, + random_access_iterator_tag, + random_access_iterator_tag, + __gnu_parallel::parallelism); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp, + __gnu_parallel::sequential_tag); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp, + __gnu_parallel::parallelism); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp, + _BinaryFunction1, _BinaryFunction2); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, + _BinaryFunction2, __gnu_parallel::sequential_tag); + + template + _Tp + inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1, + BinaryFunction2, __gnu_parallel::parallelism); + + template + _Tp + inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1, + BinaryFunction2, random_access_iterator_tag, + random_access_iterator_tag, + __gnu_parallel::parallelism); + + template + _Tp + inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, + _BinaryFunction2, _Tag1, _Tag2); - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T); + template + _OIter + partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::sequential_tag); - - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::parallelism); - - - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2); - - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2, + template + _OIter + partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); - template - inline T - inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2, - __gnu_parallel::parallelism); - - template - T - inner_product_switch(_RAIter1, _RAIter1, _RAIter2, T, BinaryFunction1, - BinaryFunction2, random_access_iterator_tag, - random_access_iterator_tag, - __gnu_parallel::parallelism); - - template - inline T - inner_product_switch(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, - BinaryFunction2, _Tag1, _Tag2); - - template - inline _OIter - partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); + _OIter + partial_sum(_IIter, _IIter, _OIter result); template - inline _OIter - partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); + _OIter + partial_sum(_IIter, _IIter, _OIter, _BinaryOper); - template - inline _OIter - partial_sum(_IIter, _IIter, _OIter result); + template + _OIter + partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template - inline _OIter - partial_sum(_IIter, _IIter, _OIter, _BinaryOper); - - template - inline _OIter - partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); - - template - _OIter - partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag); + _OIter + partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, + random_access_iterator_tag, random_access_iterator_tag); } // end namespace } // end namespace diff --git a/libstdc++-v3/include/parallel/omp_loop.h b/libstdc++-v3/include/parallel/omp_loop.h index 0a992b063de..97660c16bbc 100644 --- a/libstdc++-v3/include/parallel/omp_loop.h +++ b/libstdc++-v3/include/parallel/omp_loop.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -65,17 +65,18 @@ namespace __gnu_parallel * @return User-supplied functor (that may contain a part of the result). */ template + typename Op, + typename Fu, + typename Red, + typename Result> Op - for_each_template_random_access_omp_loop( - RandomAccessIterator begin, - RandomAccessIterator end, - Op o, Fu& f, Red r, Result base, Result& output, - typename std::iterator_traits:: - difference_type bound) + for_each_template_random_access_omp_loop(RandomAccessIterator begin, + RandomAccessIterator end, + Op o, Fu& f, Red r, Result base, + Result& output, + typename std::iterator_traits + :: + difference_type bound) { typedef typename std::iterator_traits::difference_type @@ -83,7 +84,7 @@ template(get_max_threads(), length); + __gnu_parallel::min(get_max_threads(), length); Result *thread_results; @@ -94,19 +95,19 @@ template + typename Op, + typename Fu, + typename Red, + typename Result> Op - for_each_template_random_access_omp_loop_static( - RandomAccessIterator begin, - RandomAccessIterator end, - Op o, Fu& f, Red r, Result base, Result& output, - typename std::iterator_traits:: - difference_type bound) + for_each_template_random_access_omp_loop_static(RandomAccessIterator begin, + RandomAccessIterator end, + Op o, Fu& f, Red r, + Result base, Result& output, + typename std::iterator_traits + :: + difference_type bound) { typedef typename - std::iterator_traits::difference_type - difference_type; + std::iterator_traits::difference_type + difference_type; difference_type length = end - begin; thread_index_t num_threads = - std::min(get_max_threads(), length); + std::min(get_max_threads(), length); Result *thread_results; @@ -94,20 +95,19 @@ template +template Op - for_each_template_random_access_ed( - RandomAccessIterator begin, - RandomAccessIterator end, - Op o, Fu& f, Red r, Result base, Result& output, - typename std::iterator_traits:: - difference_type bound) + for_each_template_random_access_ed(RandomAccessIterator begin, + RandomAccessIterator end, + Op o, Fu& f, Red r, Result base, + Result& output, + typename std::iterator_traits + :: + difference_type bound) { typedef std::iterator_traits traits_type; typedef typename traits_type::difference_type difference_type; @@ -85,7 +85,7 @@ template< Result *thread_results; thread_index_t num_threads = - __gnu_parallel::min(get_max_threads(), length); + __gnu_parallel::min(get_max_threads(), length); # pragma omp parallel num_threads(num_threads) { @@ -116,7 +116,7 @@ template< thread_results[iam] = reduct; } //parallel - for (thread_index_t i = 0; i < num_threads; i++) + for (thread_index_t i = 0; i < num_threads; ++i) output = r(output, thread_results[i]); // Points to last element processed (needed as return value for diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h index c165729d86a..f7ca754720d 100644 --- a/libstdc++-v3/include/parallel/partial_sum.h +++ b/libstdc++-v3/include/parallel/partial_sum.h @@ -57,15 +57,14 @@ namespace __gnu_parallel * @param value Start value. Must be passed since the neutral * element is unknown in general. * @return End iterator of output sequence. */ -template< - typename InputIterator, - typename OutputIterator, - typename BinaryOperation> - inline OutputIterator - parallel_partial_sum_basecase( - InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, - typename std::iterator_traits::value_type value) +template + OutputIterator + parallel_partial_sum_basecase(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + typename std::iterator_traits + ::value_type value) { if (begin == end) return result; @@ -90,15 +89,14 @@ template< * @param num_threads Number of threads to use. * @return End iterator of output sequence. */ -template< - typename InputIterator, - typename OutputIterator, - typename BinaryOperation> +template OutputIterator - parallel_partial_sum_linear( - InputIterator begin, InputIterator end, - OutputIterator result, BinaryOperation bin_op, - typename std::iterator_traits::difference_type n) + parallel_partial_sum_linear(InputIterator begin, InputIterator end, + OutputIterator result, BinaryOperation bin_op, + typename std::iterator_traits + ::difference_type n) { typedef std::iterator_traits traits_type; typedef typename traits_type::value_type value_type; @@ -133,9 +131,10 @@ template< else { difference_type chunk_length = - ((double)n / - ((double)num_threads + Settings::partial_sum_dilatation)), - borderstart = n - num_threads * chunk_length; + ((double)n + / ((double)num_threads + + Settings::partial_sum_dilatation)), + borderstart = n - num_threads * chunk_length; borders[0] = 0; for (int i = 1; i < (num_threads + 1); ++i) { @@ -145,8 +144,8 @@ template< borders[num_threads + 1] = n; } - sums = static_cast( - ::operator new(sizeof(value_type) * num_threads)); + sums = static_cast(::operator new(sizeof(value_type) + * num_threads)); OutputIterator target_end; } //single @@ -155,16 +154,17 @@ template< { *result = *begin; 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)); } else { - ::new(&(sums[iam])) value_type( - std::accumulate(begin + borders[iam] + 1, - begin + borders[iam + 1], - *(begin + borders[iam]), - bin_op, __gnu_parallel::sequential_tag())); + ::new(&(sums[iam])) + value_type(std::accumulate(begin + borders[iam] + 1, + begin + borders[iam + 1], + *(begin + borders[iam]), + bin_op, + __gnu_parallel::sequential_tag())); } # pragma omp barrier @@ -177,9 +177,9 @@ template< // Still same team. parallel_partial_sum_basecase(begin + borders[iam + 1], - begin + borders[iam + 2], - result + borders[iam + 1], bin_op, - sums[iam]); + begin + borders[iam + 2], + result + borders[iam + 1], bin_op, + sums[iam]); } //parallel ::operator delete(sums); @@ -194,10 +194,9 @@ template< * @param result Begin iterator of output sequence. * @param bin_op Associative binary function. * @return End iterator of output sequence. */ -template< - typename InputIterator, - typename OutputIterator, - typename BinaryOperation> +template OutputIterator parallel_partial_sum(InputIterator begin, InputIterator end, OutputIterator result, BinaryOperation bin_op) diff --git a/libstdc++-v3/include/parallel/partition.h b/libstdc++-v3/include/parallel/partition.h index d6dac37d7c8..9dfcaadd84d 100644 --- a/libstdc++-v3/include/parallel/partition.h +++ b/libstdc++-v3/include/parallel/partition.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -92,10 +92,11 @@ template reserved_right = new bool[num_threads]; if (Settings::partition_chunk_share > 0.0) - chunk_size = std::max( - Settings::partition_chunk_size, - (double)n * Settings::partition_chunk_share / - (double)num_threads); + chunk_size = std::max(Settings:: + partition_chunk_size, + (double)n * Settings:: + partition_chunk_share + / (double)num_threads); else chunk_size = Settings::partition_chunk_size; } @@ -106,7 +107,7 @@ template { difference_type 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_right[r] = false; @@ -164,10 +165,10 @@ template { while (pred(begin[thread_left]) && thread_left <= thread_left_border) - thread_left++; + ++thread_left; while (!pred(begin[thread_right]) && thread_right >= thread_right_border) - thread_right--; + --thread_right; if (thread_left > thread_left_border || thread_right < thread_right_border) @@ -175,18 +176,18 @@ template break; std::swap(begin[thread_left], begin[thread_right]); - thread_left++; - thread_right--; + ++thread_left; + --thread_right; } } // Now swap the leftover chunks to the right places. if (thread_left <= thread_left_border) # pragma omp atomic - leftover_left++; + ++leftover_left; if (thread_right >= thread_right_border) # pragma omp atomic - leftover_right++; + ++leftover_right; # pragma omp barrier @@ -212,9 +213,8 @@ template && thread_right_border <= rightnew) { // Chunk already in place, reserve spot. - reserved_right - [((thread_right_border - 1) - right) / chunk_size] - = true; + reserved_right[((thread_right_border - 1) - right) + / chunk_size] = true; } # pragma omp barrier @@ -225,7 +225,7 @@ template // Find spot and swap. difference_type swapstart = -1; 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]) { reserved_left[r] = true; @@ -238,10 +238,10 @@ template _GLIBCXX_PARALLEL_ASSERT(swapstart != -1); #endif - std::swap_ranges( - begin + thread_left_border - (chunk_size - 1), - begin + thread_left_border + 1, - begin + swapstart); + std::swap_ranges(begin + thread_left_border + - (chunk_size - 1), + begin + thread_left_border + 1, + begin + swapstart); } if (thread_right >= thread_right_border @@ -250,7 +250,7 @@ template // Find spot and swap difference_type swapstart = -1; 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]) { reserved_right[r] = true; @@ -264,17 +264,17 @@ template #endif std::swap_ranges(begin + thread_right_border, - begin + thread_right_border + chunk_size, - begin + swapstart); + begin + thread_right_border + chunk_size, + begin + swapstart); } #if _GLIBCXX_ASSERTIONS # pragma omp barrier # 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]); - for (int r = 0; r < leftover_right; r++) + for (int r = 0; r < leftover_right; ++r) _GLIBCXX_PARALLEL_ASSERT(reserved_right[r]); } @@ -295,17 +295,17 @@ template { // Go right until key is geq than pivot. while (pred(begin[final_left]) && final_left < final_right) - final_left++; + ++final_left; // Go left until key is less than pivot. while (!pred(begin[final_right]) && final_left < final_right) - final_right--; + --final_right; if (final_left == final_right) break; std::swap(begin[final_left], begin[final_right]); - final_left++; - final_right--; + ++final_left; + --final_right; } // All elements on the left side are < piv, all elements on the @@ -345,7 +345,8 @@ template RandomAccessIterator split; random_number rng; - difference_type minimum_length = std::max(2, Settings::partition_minimal_n); + difference_type minimum_length = + std::max(2, Settings::partition_minimal_n); // Break if input range to small. while (static_cast(end - begin) >= minimum_length) @@ -359,15 +360,19 @@ template std::swap(*pivot_pos, *(end - 1)); pivot_pos = end - 1; - // XXX Comparator must have first_value_type, second_value_type, result_type - // Comparator == __gnu_parallel::lexicographic > + // XXX Comparator must have first_value_type, second_value_type, + // result_type + // Comparator == __gnu_parallel::lexicographic > // pivot_pos == std::pair* // XXX binder2nd only for RandomAccessIterators?? - __gnu_parallel::binder2nd pred(comp, *pivot_pos); + __gnu_parallel::binder2nd + pred(comp, *pivot_pos); // Divide, leave pivot unchanged in last place. RandomAccessIterator split_pos1, split_pos2; - split_pos1 = begin + parallel_partition(begin, end - 1, pred, get_max_threads()); + split_pos1 = begin + parallel_partition(begin, end - 1, pred, + get_max_threads()); // Left side: < pivot_pos; right side: >= pivot_pos @@ -377,14 +382,19 @@ template pivot_pos = split_pos1; // In case all elements are equal, split_pos1 == 0 - if ((split_pos1 + 1 - begin) < (n >> 7) || (end - split_pos1) < (n >> 7)) + if ((split_pos1 + 1 - begin) < (n >> 7) + || (end - split_pos1) < (n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not stricly larger than the pivot. - __gnu_parallel::unary_negate<__gnu_parallel::binder1st, value_type> pred(__gnu_parallel::binder1st(comp, *pivot_pos)); + __gnu_parallel::unary_negate<__gnu_parallel:: + binder1st, value_type> + pred(__gnu_parallel::binder1st(comp, *pivot_pos)); // Find other end of pivot-equal range. - split_pos2 = __gnu_sequential::partition(split_pos1 + 1, end, pred); + split_pos2 = __gnu_sequential::partition(split_pos1 + 1, + end, pred); } else // Only skip the pivot. @@ -410,7 +420,9 @@ template * @param comp Comparator. */ template void - parallel_partial_sort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, Comparator comp) + parallel_partial_sort(RandomAccessIterator begin, + RandomAccessIterator middle, + RandomAccessIterator end, Comparator comp) { parallel_nth_element(begin, middle, end, comp); std::sort(begin, middle, comp); diff --git a/libstdc++-v3/include/parallel/queue.h b/libstdc++-v3/include/parallel/queue.h index 9d2143b5787..27a26f3ecaa 100644 --- a/libstdc++-v3/include/parallel/queue.h +++ b/libstdc++-v3/include/parallel/queue.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -55,96 +55,98 @@ namespace __gnu_parallel * Calling them would not make sense in a concurrent setting. * @param T Contained element type. */ template - class RestrictedBoundedConcurrentQueue - { - private: - /** @brief Array of elements, seen as cyclic buffer. */ - T* base; - - /** @brief Maximal number of elements contained at the same time. */ - sequence_index_t max_size; - - /** @brief Cyclic begin and end pointers contained in one - atomically changeable value. */ - _GLIBCXX_VOLATILE lcas_t borders; - - public: - /** @brief Constructor. Not to be called concurrent, of course. - * @param max_size Maximal number of elements to be contained. */ - RestrictedBoundedConcurrentQueue(sequence_index_t max_size) + class RestrictedBoundedConcurrentQueue { - this->max_size = max_size; - base = new T[max_size]; - borders = encode2(0, 0); + private: + /** @brief Array of elements, seen as cyclic buffer. */ + T* base; + + /** @brief Maximal number of elements contained at the same time. */ + sequence_index_t max_size; + + /** @brief Cyclic begin and end pointers contained in one + atomically changeable value. */ + _GLIBCXX_VOLATILE lcas_t borders; + + public: + /** @brief Constructor. Not to be called concurrent, of course. + * @param max_size Maximal number of elements to be contained. */ + RestrictedBoundedConcurrentQueue(sequence_index_t max_size) + { + this->max_size = max_size; + base = new T[max_size]; + borders = encode2(0, 0); #pragma omp flush - } + } - /** @brief Destructor. Not to be called concurrent, of course. */ - ~RestrictedBoundedConcurrentQueue() - { - delete[] base; - } + /** @brief Destructor. Not to be called concurrent, of course. */ + ~RestrictedBoundedConcurrentQueue() + { delete[] base; } - /** @brief Pushes one element into the queue at the front end. - * Must not be called concurrently with pop_front(). */ - void push_front(const T& t) - { - lcas_t former_borders = borders; - int former_front, former_back; - decode2(former_borders, former_front, former_back); - *(base + former_front % max_size) = t; + /** @brief Pushes one element into the queue at the front end. + * Must not be called concurrently with pop_front(). */ + void + push_front(const T& t) + { + lcas_t former_borders = borders; + int former_front, former_back; + decode2(former_borders, former_front, former_back); + *(base + former_front % max_size) = t; #if _GLIBCXX_ASSERTIONS - // Otherwise: front - back > max_size eventually. - _GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back) <= max_size); + // Otherwise: front - back > max_size eventually. + _GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back) + <= max_size); #endif - fetch_and_add(&borders, encode2(1, 0)); - } + fetch_and_add(&borders, encode2(1, 0)); + } - /** @brief Pops one element from the queue at the front end. - * Must not be called concurrently with pop_front(). */ - bool pop_front(T& t) - { - int former_front, former_back; + /** @brief Pops one element from the queue at the front end. + * Must not be called concurrently with pop_front(). */ + bool + pop_front(T& t) + { + int former_front, former_back; #pragma omp flush - decode2(borders, former_front, former_back); - while (former_front > former_back) - { - // Chance. - lcas_t former_borders = encode2(former_front, former_back); - lcas_t new_borders = encode2(former_front - 1, former_back); - if (compare_and_swap(&borders, former_borders, new_borders)) - { - t = *(base + (former_front - 1) % max_size); - return true; - } + decode2(borders, former_front, former_back); + while (former_front > former_back) + { + // Chance. + lcas_t former_borders = encode2(former_front, former_back); + lcas_t new_borders = encode2(former_front - 1, former_back); + if (compare_and_swap(&borders, former_borders, new_borders)) + { + t = *(base + (former_front - 1) % max_size); + return true; + } #pragma omp flush - decode2(borders, former_front, former_back); - } - return false; - } + decode2(borders, former_front, former_back); + } + return false; + } - /** @brief Pops one element from the queue at the front end. - * Must not be called concurrently with pop_front(). */ - bool pop_back(T& t) //queue behavior - { - int former_front, former_back; + /** @brief Pops one element from the queue at the front end. + * Must not be called concurrently with pop_front(). */ + bool + pop_back(T& t) //queue behavior + { + int former_front, former_back; #pragma omp flush - decode2(borders, former_front, former_back); - while (former_front > former_back) - { - // Chance. - lcas_t former_borders = encode2(former_front, former_back); - lcas_t new_borders = encode2(former_front, former_back + 1); - if (compare_and_swap(&borders, former_borders, new_borders)) - { - t = *(base + former_back % max_size); - return true; - } + decode2(borders, former_front, former_back); + while (former_front > former_back) + { + // Chance. + lcas_t former_borders = encode2(former_front, former_back); + lcas_t new_borders = encode2(former_front, former_back + 1); + if (compare_and_swap(&borders, former_borders, new_borders)) + { + t = *(base + former_back % max_size); + return true; + } #pragma omp flush - decode2(borders, former_front, former_back); - } - return false; - } + decode2(borders, former_front, former_back); + } + return false; + } }; } //namespace __gnu_parallel diff --git a/libstdc++-v3/include/parallel/quicksort.h b/libstdc++-v3/include/parallel/quicksort.h index 9228647d5e0..5b5a62f30c5 100644 --- a/libstdc++-v3/include/parallel/quicksort.h +++ b/libstdc++-v3/include/parallel/quicksort.h @@ -53,48 +53,46 @@ namespace __gnu_parallel * this part. */ template - inline - typename std::iterator_traits::difference_type - parallel_sort_qs_divide( - RandomAccessIterator begin, - RandomAccessIterator end, - Comparator comp, - typename std::iterator_traits::difference_type - pivot_rank, - typename std::iterator_traits::difference_type - num_samples, - thread_index_t num_threads) - { - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::difference_type difference_type; + typename std::iterator_traits::difference_type + parallel_sort_qs_divide(RandomAccessIterator begin, + RandomAccessIterator end, + Comparator comp, typename std::iterator_traits + ::difference_type pivot_rank, + typename std::iterator_traits + ::difference_type + num_samples, thread_index_t num_threads) + { + typedef std::iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + typedef typename traits_type::difference_type difference_type; - difference_type n = end - begin; - num_samples = std::min(num_samples, n); + difference_type n = end - begin; + num_samples = std::min(num_samples, n); - // Allocate uninitialized, to avoid default constructor. - value_type* samples = static_cast( - ::operator new(num_samples * sizeof(value_type))); + // Allocate uninitialized, to avoid default constructor. + value_type* samples = + static_cast(::operator new(num_samples + * sizeof(value_type))); - for (difference_type s = 0; s < num_samples; ++s) - { - const unsigned long long index = static_cast(s) - * n / num_samples; - ::new(&(samples[s])) value_type(begin[index]); - } + for (difference_type s = 0; s < num_samples; ++s) + { + const unsigned long long index = static_cast(s) + * n / num_samples; + ::new(&(samples[s])) value_type(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]; + value_type& pivot = samples[pivot_rank * num_samples / n]; - __gnu_parallel::binder2nd + __gnu_parallel::binder2nd pred(comp, pivot); - difference_type split = parallel_partition(begin, end, pred, num_threads); + difference_type split = parallel_partition(begin, end, pred, num_threads); - ::operator delete(samples); + ::operator delete(samples); - return split; - } + return split; + } /** @brief Unbalanced quicksort conquer step. * @param begin Begin iterator of subsequence. @@ -104,50 +102,51 @@ namespace __gnu_parallel * this part. */ template - inline void - parallel_sort_qs_conquer(RandomAccessIterator begin, - RandomAccessIterator end, - Comparator comp, - thread_index_t num_threads) - { - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::difference_type difference_type; + void + parallel_sort_qs_conquer(RandomAccessIterator begin, + RandomAccessIterator end, + Comparator comp, + thread_index_t num_threads) + { + typedef std::iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + typedef typename traits_type::difference_type difference_type; - if (num_threads <= 1) - { - __gnu_sequential::sort(begin, end, comp); - return; - } + if (num_threads <= 1) + { + __gnu_sequential::sort(begin, end, comp); + return; + } - difference_type n = end - begin, pivot_rank; + difference_type n = end - begin, pivot_rank; - if (n <= 1) - return; + if (n <= 1) + return; - thread_index_t num_threads_left; + thread_index_t num_threads_left; - if ((num_threads % 2) == 1) - num_threads_left = num_threads / 2 + 1; - else - num_threads_left = num_threads / 2; + if ((num_threads % 2) == 1) + num_threads_left = num_threads / 2 + 1; + else + 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 = parallel_sort_qs_divide( - begin, end, comp, pivot_rank, - Settings::sort_qs_num_samples_preset, num_threads); + difference_type split = + parallel_sort_qs_divide(begin, end, comp, pivot_rank, + Settings::sort_qs_num_samples_preset, + num_threads); #pragma omp parallel sections - { + { #pragma omp section - parallel_sort_qs_conquer(begin, begin + split, - comp, num_threads_left); + parallel_sort_qs_conquer(begin, begin + split, + comp, num_threads_left); #pragma omp section - parallel_sort_qs_conquer(begin + split, end, - comp, num_threads - num_threads_left); + parallel_sort_qs_conquer(begin + split, end, + comp, num_threads - num_threads_left); + } } - } @@ -160,34 +159,33 @@ namespace __gnu_parallel * this part. */ template - inline void - parallel_sort_qs( - RandomAccessIterator begin, - RandomAccessIterator end, - Comparator comp, - typename std::iterator_traits::difference_type n, - int num_threads) - { - _GLIBCXX_CALL(n) + void + parallel_sort_qs(RandomAccessIterator begin, + RandomAccessIterator end, + Comparator comp, typename std::iterator_traits + ::difference_type n, + int num_threads) + { + _GLIBCXX_CALL(n) - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::difference_type difference_type; + typedef std::iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + typedef typename traits_type::difference_type difference_type; - if (n == 0) - return; + if (n == 0) + return; - // At least one element per processor. - if (num_threads > n) - num_threads = static_cast(n); + // At least one element per processor. + if (num_threads > n) + num_threads = static_cast(n); - Settings::sort_qs_num_samples_preset = 100; + Settings::sort_qs_num_samples_preset = 100; - // Hard to avoid. - omp_set_num_threads(num_threads); + // Hard to avoid. + omp_set_num_threads(num_threads); - parallel_sort_qs_conquer(begin, begin + n, comp, num_threads); - } + parallel_sort_qs_conquer(begin, begin + n, comp, num_threads); + } } //namespace __gnu_parallel diff --git a/libstdc++-v3/include/parallel/random_number.h b/libstdc++-v3/include/parallel/random_number.h index 266ed0ab251..ae523723ecb 100644 --- a/libstdc++-v3/include/parallel/random_number.h +++ b/libstdc++-v3/include/parallel/random_number.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -46,229 +46,288 @@ namespace __gnu_parallel // http://www.math.keio.ac.jp/matumoto/emt.html template - class mersenne_twister - { - public: - typedef UIntType result_type; - static const int word_size = w; - static const int state_size = n; - static const int shift_size = m; - static const int mask_bits = r; - static const UIntType parameter_a = a; - static const int output_u = u; - static const int output_s = s; - static const UIntType output_b = b; - static const int output_t = t; - static const UIntType output_c = c; - static const int output_l = l; - - static const bool has_fixed_range = false; - - mersenne_twister() { seed(); } - -#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520) - // Work around overload resolution problem (Gennadiy E. Rozental) - explicit mersenne_twister(const UIntType& value) -#else - explicit mersenne_twister(UIntType value) -#endif - { seed(value); } - template mersenne_twister(It& first, It last) { seed(first,last); } - - template - explicit mersenne_twister(Generator & gen) { seed(gen); } - - // compiler-generated copy ctor and assignment operator are fine - - void seed() { seed(UIntType(5489)); } - -#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520) - // Work around overload resolution problem (Gennadiy E. Rozental) - void seed(const UIntType& value) -#else - void seed(UIntType value) -#endif + class mersenne_twister { - // New seeding algorithm from + public: + typedef UIntType result_type; + static const int word_size = w; + static const int state_size = n; + static const int shift_size = m; + static const int mask_bits = r; + static const UIntType parameter_a = a; + static const int output_u = u; + static const int output_s = s; + static const UIntType output_b = b; + static const int output_t = t; + static const UIntType output_c = c; + static const int output_l = l; + + static const bool has_fixed_range = false; + + mersenne_twister() { seed(); } + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520) + // Work around overload resolution problem (Gennadiy E. Rozental) + explicit + mersenne_twister(const UIntType& value) +#else + explicit + mersenne_twister(UIntType value) +#endif + { seed(value); } + + template + mersenne_twister(It& first, It last) + { seed(first,last); } + + template + explicit + mersenne_twister(Generator & gen) + { seed(gen); } + + // compiler-generated copy ctor and assignment operator are fine + + void + seed() + { seed(UIntType(5489)); } + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520) + // Work around overload resolution problem (Gennadiy E. Rozental) + void + seed(const UIntType& value) +#else + void + seed(UIntType value) +#endif + { + // New seeding algorithm from // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html - // In the previous versions, MSBs of the seed affected only MSBs of the - // state x[]. - const UIntType mask = ~0u; - x[0] = value & mask; - for (i = 1; i < n; i++) { - // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106 - x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; + // In the previous versions, MSBs of the seed affected only MSBs of the + // state x[]. + const UIntType mask = ~0u; + x[0] = value & mask; + for (i = 1; i < n; ++i) + { + // See Knuth "The Art of Computer Programming" Vol. 2, + // 3rd ed., page 106 + x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; + } } - } - // For GCC, moving this function out-of-line prevents inlining, which may - // reduce overall object code size. However, MSVC does not grok - // out-of-line definitions of member function templates. - template - void seed(Generator & gen) - { - // I could have used std::generate_n, but it takes "gen" by value - for (int j = 0; j < n; j++) - x[j] = gen(); - i = n; - } + // For GCC, moving this function out-of-line prevents inlining, which may + // reduce overall object code size. However, MSVC does not grok + // out-of-line definitions of member function templates. + template + void + seed(Generator & gen) + { + // I could have used std::generate_n, but it takes "gen" by value + for (int j = 0; j < n; ++j) + x[j] = gen(); + i = n; + } - template - void seed(It& first, It last) - { - int j; - for (j = 0; j < n && first != last; ++j, ++first) - x[j] = *first; - i = n; - /* if (first == last && j < n) - throw std::invalid_argument("mersenne_twister::seed");*/ - } + template + void + seed(It& first, It last) + { + int j; + for (j = 0; j < n && first != last; ++j, ++first) + x[j] = *first; + i = n; + /* if (first == last && j < n) + throw std::invalid_argument("mersenne_twister::seed");*/ + } - result_type min() const { return 0; } - result_type max() const - { - // avoid "left shift count >= with of type" warning - result_type res = 0; - for (int i = 0; i < w; ++i) - res |= (1u << i); - return res; - } + result_type + min() const + { return 0; } + + result_type + max() const + { + // avoid "left shift count >= with of type" warning + result_type res = 0; + for (int i = 0; i < w; ++i) + res |= (1u << i); + return res; + } - result_type operator()(); - static bool validation(result_type v) { return val == v; } + result_type + operator()(); + + static bool + validation(result_type v) + { return val == v; } #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE - friend bool operator==(const mersenne_twister& x, const mersenne_twister& y) - { - for (int j = 0; j < state_size; ++j) - if (x.compute(j) != y.compute(j)) - return false; - return true; - } + friend bool + operator==(const mersenne_twister& x, const mersenne_twister& y) + { + for (int j = 0; j < state_size; ++j) + if (x.compute(j) != y.compute(j)) + return false; + return true; + } - friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y) - { return !(x == y); } + friend bool + operator!=(const mersenne_twister& x, const mersenne_twister& y) + { return !(x == y); } #else - // Use a member function; Streamable concept not supported. - bool operator==(const mersenne_twister& rhs) const - { - for (int j = 0; j < state_size; ++j) - if (compute(j) != rhs.compute(j)) - return false; - return true; - } + // Use a member function; Streamable concept not supported. + bool + operator==(const mersenne_twister& rhs) const + { + for (int j = 0; j < state_size; ++j) + if (compute(j) != rhs.compute(j)) + return false; + return true; + } - bool operator!=(const mersenne_twister& rhs) const - { return !(*this == rhs); } + bool + operator!=(const mersenne_twister& rhs) const + { return !(*this == rhs); } #endif - private: - // returns x(i-n+index), where index is in 0..n-1 - UIntType compute(unsigned int index) const - { - // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers - return x[ (i + n + index) % (2*n) ]; - } - void twist(int block); + private: + // returns x(i-n+index), where index is in 0..n-1 + UIntType + compute(unsigned int index) const + { + // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers + return x[ (i + n + index) % (2*n) ]; + } - // state representation: next output is o(x(i)) - // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents - // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)] - // The goal is to always have x(i-n) ... x(i-1) available for - // operator== and save/restore. + void + twist(int block); - UIntType x[2*n]; - int i; + // state representation: next output is o(x(i)) + // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents + // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)] + // The goal is to always have x(i-n) ... x(i-1) available for + // operator== and save/restore. + + UIntType x[2*n]; + int i; }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION // A definition is required even for integral static constants template - const bool mersenne_twister::has_fixed_range; + const bool + mersenne_twister::has_fixed_range; + template - const int mersenne_twister::state_size; + const int + mersenne_twister::state_size; + template - const int mersenne_twister::shift_size; + const int + mersenne_twister::shift_size; + template - const int mersenne_twister::mask_bits; + const int + mersenne_twister::mask_bits; + template - const UIntType mersenne_twister::parameter_a; + const UIntType + mersenne_twister::parameter_a; + template - const int mersenne_twister::output_u; + const int + mersenne_twister::output_u; + template - const int mersenne_twister::output_s; + const int + mersenne_twister::output_s; + template - const UIntType mersenne_twister::output_b; + const UIntType + mersenne_twister::output_b; + template - const int mersenne_twister::output_t; + const int + mersenne_twister::output_t; + template - const UIntType mersenne_twister::output_c; + const UIntType + mersenne_twister::output_c; + template - const int mersenne_twister::output_l; + const int + mersenne_twister::output_l; #endif template - void mersenne_twister::twist(int block) + void + mersenne_twister::twist(int block) { const UIntType upper_mask = (~0u) << r; const UIntType lower_mask = ~upper_mask; - if (block == 0) { - for (int j = n; j < 2*n; j++) { - UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask); - x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + if (block == 0) + { + for (int j = n; j < 2*n; ++j) + { + UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } } - } else if (block == 1) { - // split loop to avoid costly modulo operations - { // extra scope for MSVC brokenness w.r.t. for scope - for (int j = 0; j < n-m; j++) { - UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); - x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0); + else if (block == 1) + { + // split loop to avoid costly modulo operations + { // extra scope for MSVC brokenness w.r.t. for scope + for (int j = 0; j < n-m; ++j) + { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0); + } } + + for (int j = n-m; j < n-1; ++j) + { + UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); + x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); + } + // last iteration + UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask); + x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0); + i = 0; } - - for (int j = n-m; j < n-1; j++) { - UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask); - x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0); - } - // last iteration - UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask); - x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0); - i = 0; - } } template - inline typename mersenne_twister::result_type - mersenne_twister::operator()() - { - if (i == n) - twist(0); - else if (i >= 2*n) - twist(1); - // Step 4 - UIntType z = x[i]; - ++i; - z ^= (z >> u); - z ^= ((z << s) & b); - z ^= ((z << t) & c); - z ^= (z >> l); - return z; - } + inline + typename mersenne_twister::result_type + mersenne_twister::operator()() + { + if (i == n) + twist(0); + else if (i >= 2*n) + twist(1); + // Step 4 + UIntType z = x[i]; + ++i; + z ^= (z >> u); + z ^= ((z << s) & b); + z ^= ((z << t) & c); + z ^= (z >> l); + return z; + } typedef mersenne_twister - inline unsigned long genrand_bits() - { - unsigned long res = cache & ((1 << bits) - 1); - cache = cache >> bits; - bits_left -= bits; - if (bits_left < 32) + /** @brief Generate a number of random bits, compile-time parameter. */ + template + unsigned long + genrand_bits() { - cache |= (((uint64)mt()) << bits_left); - bits_left += 32; + unsigned long res = cache & ((1 << bits) - 1); + cache = cache >> bits; + bits_left -= bits; + if (bits_left < 32) + { + cache |= (((uint64)mt()) << bits_left); + bits_left += 32; + } + return res; } - return res; - } - - /** @brief Generate a number of random bits, run-time parameter. - * @param bits Number of bits to generate. */ - inline unsigned long genrand_bits(int bits) - { - unsigned long res = cache & ((1 << bits) - 1); - cache = cache >> bits; - bits_left -= bits; - if (bits_left < 32) - { - cache |= (((uint64)mt()) << bits_left); - bits_left += 32; - } - return res; - } + /** @brief Generate a number of random bits, run-time parameter. + * @param bits Number of bits to generate. */ + unsigned long + genrand_bits(int bits) + { + unsigned long res = cache & ((1 << bits) - 1); + cache = cache >> bits; + bits_left -= bits; + if (bits_left < 32) + { + cache |= (((uint64)mt()) << bits_left); + bits_left += 32; + } + return res; + } }; } // namespace __gnu_parallel diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h index dd086baf3ec..348a3a34b37 100644 --- a/libstdc++-v3/include/parallel/random_shuffle.h +++ b/libstdc++-v3/include/parallel/random_shuffle.h @@ -124,7 +124,7 @@ template /** @brief Random shuffle code executed by each thread. * @param pus Array of thread-local data records. */ template - inline void + void parallel_random_shuffle_drs_pu(DRSSorterPU* pus) { @@ -213,8 +213,8 @@ template thread_index_t target_p = bin_proc[target_bin]; // Last column [d->num_threads] stays unchanged. - ::new(&(temporaries[target_p][dist[target_bin + 1]++])) value_type( - *(source + i + start)); + ::new(&(temporaries[target_p][dist[target_bin + 1]++])) + value_type(*(source + i + start)); } delete[] oracles; @@ -260,13 +260,13 @@ template * @param rng Random number generator to use. */ template - inline void - parallel_random_shuffle_drs( - RandomAccessIterator begin, - RandomAccessIterator end, - typename std::iterator_traits::difference_type n, - thread_index_t num_threads, - RandomNumberGenerator& rng) + void + parallel_random_shuffle_drs(RandomAccessIterator begin, + RandomAccessIterator end, + typename std::iterator_traits + ::difference_type n, + thread_index_t num_threads, + RandomNumberGenerator& rng) { typedef std::iterator_traits traits_type; typedef typename traits_type::value_type value_type; @@ -393,7 +393,7 @@ template * @param rng Random number generator to use. */ template - inline void + void sequential_random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rng) diff --git a/libstdc++-v3/include/parallel/search.h b/libstdc++-v3/include/parallel/search.h index d917b12693a..86bd2b827b9 100644 --- a/libstdc++-v3/include/parallel/search.h +++ b/libstdc++-v3/include/parallel/search.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -81,10 +81,9 @@ template * @param end2 End iterator of second sequence. * @param pred Find predicate. * @return Place of finding in first sequences. */ -template< - typename _RandomAccessIterator1, - typename _RandomAccessIterator2, - typename Pred> +template _RandomAccessIterator1 search_template(_RandomAccessIterator1 begin1, _RandomAccessIterator1 end1, _RandomAccessIterator2 begin2, _RandomAccessIterator2 end2, diff --git a/libstdc++-v3/include/parallel/set_operations.h b/libstdc++-v3/include/parallel/set_operations.h index 7be31277077..50c28d48d66 100644 --- a/libstdc++-v3/include/parallel/set_operations.h +++ b/libstdc++-v3/include/parallel/set_operations.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -48,7 +48,7 @@ namespace __gnu_parallel { template - inline OutputIterator + OutputIterator copy_tail(std::pair b, std::pair e, OutputIterator r) { @@ -68,10 +68,9 @@ template return r; } -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> +template struct symmetric_difference_func { typedef std::iterator_traits traits_type; @@ -82,9 +81,10 @@ template< Comparator comp; - inline OutputIterator invoke(InputIterator a, InputIterator b, - InputIterator c, InputIterator d, - OutputIterator r) const + OutputIterator + invoke(InputIterator a, InputIterator b, + InputIterator c, InputIterator d, + OutputIterator r) const { while (a != b && c != d) { @@ -109,9 +109,9 @@ template< return std::copy(c, d, std::copy(a, b, r)); } - inline difference_type - count(InputIterator a, InputIterator b, InputIterator c, InputIterator d) - const + difference_type + count(InputIterator a, InputIterator b, + InputIterator c, InputIterator d) const { difference_type counter = 0; @@ -137,21 +137,19 @@ template< return counter + (b - a) + (d - c); } - inline OutputIterator + OutputIterator first_empty(InputIterator c, InputIterator d, OutputIterator out) const { return std::copy(c, d, out); } - inline OutputIterator + OutputIterator second_empty(InputIterator a, InputIterator b, OutputIterator out) const { return std::copy(a, b, out); } - }; -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> +template struct difference_func { typedef std::iterator_traits traits_type; @@ -162,7 +160,7 @@ template< Comparator comp; - inline OutputIterator + OutputIterator invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d, OutputIterator r) const { @@ -185,9 +183,9 @@ template< return std::copy(a, b, r); } - inline difference_type - count(InputIterator a, InputIterator b, InputIterator c, InputIterator d) - const + difference_type + count(InputIterator a, InputIterator b, + InputIterator c, InputIterator d) const { difference_type counter = 0; @@ -217,10 +215,9 @@ template< }; -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> +template struct intersection_func { typedef std::iterator_traits traits_type; @@ -231,7 +228,7 @@ template< Comparator comp; - inline OutputIterator + OutputIterator invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d, OutputIterator r) const { @@ -253,9 +250,9 @@ template< return r; } - inline difference_type - count(InputIterator a, InputIterator b, InputIterator c, InputIterator d) - const + difference_type + count(InputIterator a, InputIterator b, + InputIterator c, InputIterator d) const { difference_type counter = 0; @@ -289,13 +286,13 @@ template struct union_func { typedef typename std::iterator_traits::difference_type - difference_type; + difference_type; union_func(Comparator c) : comp(c) {} Comparator comp; - inline OutputIterator + OutputIterator invoke(InputIterator a, const InputIterator b, InputIterator c, const InputIterator d, OutputIterator r) const { @@ -322,9 +319,9 @@ template return std::copy(c, d, std::copy(a, b, r)); } - inline difference_type - count(InputIterator a, InputIterator b, InputIterator c, InputIterator d) - const + difference_type + count(InputIterator a, InputIterator b, + InputIterator c, InputIterator d) const { difference_type counter = 0; @@ -356,10 +353,9 @@ template { return std::copy(a, b, out); } }; -template< - typename InputIterator, - typename OutputIterator, - typename Operation> +template OutputIterator parallel_set_operation(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, @@ -480,11 +476,10 @@ template< } -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> - OutputIterator +template + inline OutputIterator parallel_set_union(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, OutputIterator result, Comparator comp) @@ -493,11 +488,10 @@ template< union_func< InputIterator, OutputIterator, Comparator>(comp)); } -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> - OutputIterator +template + inline OutputIterator parallel_set_intersection(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, OutputIterator result, Comparator comp) @@ -508,7 +502,7 @@ template< template - OutputIterator + inline OutputIterator set_intersection(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, OutputIterator result) @@ -517,14 +511,13 @@ template typedef typename traits_type::value_type value_type; return set_intersection(begin1, end1, begin2, end2, result, - std::less()); + std::less()); } -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> - OutputIterator +template + inline OutputIterator parallel_set_difference(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, OutputIterator result, Comparator comp) @@ -533,11 +526,10 @@ template< difference_func(comp)); } -template< - typename InputIterator, - typename OutputIterator, - typename Comparator> - OutputIterator +template + inline OutputIterator parallel_set_symmetric_difference(InputIterator begin1, InputIterator end1, InputIterator begin2, InputIterator end2, OutputIterator result, Comparator comp) diff --git a/libstdc++-v3/include/parallel/settings.h b/libstdc++-v3/include/parallel/settings.h index 5cfc6a05c47..a06227b5008 100644 --- a/libstdc++-v3/include/parallel/settings.h +++ b/libstdc++-v3/include/parallel/settings.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -33,7 +33,8 @@ * whether to use parallelized algorithms. * This file is a GNU parallel extension to the Standard C++ Library. * - * @section parallelization_decision The decision whether to run an algorithm in parallel. + * @section parallelization_decision The decision whether to run + * an algorithm in parallel. * * There are several ways the user can switch on and off the * parallel execution of an algorithm, both at compile- and @@ -104,7 +105,10 @@ * __gnu_parallel::Settings::force_parallel, i. e. usually a decision based on * the input size. */ -#define _GLIBCXX_PARALLEL_CONDITION(c) (!(__gnu_parallel::Settings::force_sequential) && ((__gnu_parallel::get_max_threads() > 1 && (c)) || __gnu_parallel::Settings::force_parallel)) +#define _GLIBCXX_PARALLEL_CONDITION(c) \ +(!(__gnu_parallel::Settings::force_sequential) \ + && ((__gnu_parallel::get_max_threads() > 1 \ + && (c)) || __gnu_parallel::Settings::force_parallel)) namespace __gnu_parallel { @@ -131,7 +135,8 @@ namespace /** @brief Different merging algorithms: bubblesort-alike, loser-tree variants, enum sentinel */ enum MultiwayMergeAlgorithm - { BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED, LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST }; + { BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED, + LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST }; /** @brief Different splitting strategies for sorting/merging: by sampling, exact */ @@ -340,7 +345,8 @@ namespace volatile sequence_index_t Settings::partition_chunk_size = 1000; volatile double Settings::partition_chunk_share = 0.0; volatile unsigned int Settings::adjacent_difference_minimal_n = 1000; - volatile Settings::PartialSumAlgorithm Settings::partial_sum_algorithm = Settings::LINEAR; + volatile Settings::PartialSumAlgorithm Settings:: + partial_sum_algorithm = Settings::LINEAR; volatile unsigned int Settings::partial_sum_minimal_n = 1000; volatile float Settings::partial_sum_dilatation = 1.0f; volatile unsigned int Settings::random_shuffle_minimal_n = 1000; @@ -352,10 +358,13 @@ namespace // unique copy volatile sequence_index_t Settings::unique_copy_minimal_n = 10000; - volatile Settings::MultiwayMergeAlgorithm Settings::multiway_merge_algorithm = Settings::LOSER_TREE; - volatile Settings::Splitting Settings::multiway_merge_splitting = Settings::EXACT; + volatile Settings::MultiwayMergeAlgorithm Settings:: + multiway_merge_algorithm = Settings::LOSER_TREE; + volatile Settings::Splitting Settings::multiway_merge_splitting = + Settings::EXACT; volatile unsigned int Settings::multiway_merge_oversampling = 10; - volatile Settings::FindDistribution Settings::find_distribution = Settings::CONSTANT_SIZE_BLOCKS; + volatile Settings::FindDistribution Settings::find_distribution = + Settings::CONSTANT_SIZE_BLOCKS; volatile sequence_index_t Settings::find_sequential_search_size = 256; volatile sequence_index_t Settings::find_initial_block_size = 256; volatile sequence_index_t Settings::find_maximum_block_size = 8192; @@ -375,7 +384,8 @@ namespace volatile sequence_index_t Settings::set_union_minimal_n = 1000; volatile sequence_index_t Settings::set_intersection_minimal_n = 1000; volatile sequence_index_t Settings::set_difference_minimal_n = 1000; - volatile sequence_index_t Settings::set_symmetric_difference_minimal_n = 1000; + volatile sequence_index_t Settings::set_symmetric_difference_minimal_n = + 1000; volatile unsigned long long Settings::L1_cache_size = 16 << 10; volatile unsigned long long Settings::L2_cache_size = 256 << 10; volatile unsigned int Settings::TLB_size = 128; diff --git a/libstdc++-v3/include/parallel/sort.h b/libstdc++-v3/include/parallel/sort.h index 6b20edd9fab..5dc3470f410 100644 --- a/libstdc++-v3/include/parallel/sort.h +++ b/libstdc++-v3/include/parallel/sort.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -69,36 +69,37 @@ namespace __gnu_parallel * @callgraph */ template - inline void - parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, - Comparator comp, bool stable) - { - _GLIBCXX_CALL(end - begin) - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::difference_type difference_type; + inline void + parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, + Comparator comp, bool stable) + { + _GLIBCXX_CALL(end - begin) + typedef std::iterator_traits traits_type; + typedef typename traits_type::value_type value_type; + typedef typename traits_type::difference_type difference_type; - if (begin != end) - { - difference_type n = end - begin; + if (begin != end) + { + difference_type n = end - begin; - if (false) ; + if (false) ; #if _GLIBCXX_MERGESORT - else if (Settings::sort_algorithm == Settings::MWMS || stable) - parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable); + else if (Settings::sort_algorithm == Settings::MWMS || stable) + parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable); #endif #if _GLIBCXX_QUICKSORT - else if (Settings::sort_algorithm == Settings::QS && !stable) - parallel_sort_qs(begin, end, comp, n, get_max_threads()); + else if (Settings::sort_algorithm == Settings::QS && !stable) + parallel_sort_qs(begin, end, comp, n, get_max_threads()); #endif #if _GLIBCXX_BAL_QUICKSORT - else if (Settings::sort_algorithm == Settings::QS_BALANCED && !stable) - parallel_sort_qsb(begin, end, comp, n, get_max_threads()); + else if (Settings::sort_algorithm == Settings::QS_BALANCED + && !stable) + parallel_sort_qsb(begin, end, comp, n, get_max_threads()); #endif - else - __gnu_sequential::sort(begin, end, comp); - } - } + else + __gnu_sequential::sort(begin, end, comp); + } + } } // end namespace __gnu_parallel #endif diff --git a/libstdc++-v3/include/parallel/tree.h b/libstdc++-v3/include/parallel/tree.h index eed0b929315..52589b8db5a 100644 --- a/libstdc++-v3/include/parallel/tree.h +++ b/libstdc++-v3/include/parallel/tree.h @@ -77,11 +77,11 @@ namespace __gnu_parallel component, if present. Set kind component. * @param T Simple type, nothing to unconst */ template - struct unconst_first_component - { - /** @brief New type after removing the const */ - typedef T type; - }; + struct unconst_first_component + { + /** @brief New type after removing the const */ + typedef T type; + }; /** @brief Helper class: remove the const modifier from the first component, if present. Map kind component @@ -89,11 +89,11 @@ namespace __gnu_parallel * @param Load Second component * @sa unconst_first_component */ template - struct unconst_first_component > - { - /** @brief New type after removing the const */ - typedef std::pair type; - }; + struct unconst_first_component > + { + /** @brief New type after removing the const */ + typedef std::pair type; + }; /** @brief Helper class: set the appropriate comparator to deal with * repetitions. Comparator for unique dictionaries. @@ -103,24 +103,23 @@ namespace __gnu_parallel * @param _Key Keys to compare * @param _Compare Comparator equal to conceptual < */ template - struct StrictlyLess : public std::binary_function<_Key, _Key, bool> - { - /** @brief Comparator equal to conceptual < */ - _Compare c; - - /** @brief Constructor given a Comparator */ - StrictlyLess(const _Compare& _c) : c(_c) { } - - /** @brief Copy constructor */ - StrictlyLess(const StrictlyLess<_Key, _Compare>& strictly_less) - : c(strictly_less.c) { } - - /** @brief Operator() */ - bool operator()(const _Key& k1, const _Key& k2) const + struct StrictlyLess : public std::binary_function<_Key, _Key, bool> { - return c(k1, k2); - } - }; + /** @brief Comparator equal to conceptual < */ + _Compare c; + + /** @brief Constructor given a Comparator */ + StrictlyLess(const _Compare& _c) : c(_c) { } + + /** @brief Copy constructor */ + StrictlyLess(const StrictlyLess<_Key, _Compare>& strictly_less) + : c(strictly_less.c) { } + + /** @brief Operator() */ + bool + operator()(const _Key& k1, const _Key& k2) const + { return c(k1, k2); } + }; /** @brief Helper class: set the appropriate comparator to deal with * repetitions. Comparator for non-unique dictionaries. @@ -130,22 +129,23 @@ namespace __gnu_parallel * @param _Key Keys to compare * @param _Compare Comparator equal to conceptual <= */ template - struct LessEqual : public std::binary_function<_Key, _Key, bool> - { - /** @brief Comparator equal to conceptual < */ - _Compare c; + struct LessEqual : public std::binary_function<_Key, _Key, bool> + { + /** @brief Comparator equal to conceptual < */ + _Compare c; - /** @brief Constructor given a Comparator */ - LessEqual(const _Compare& _c) : c(_c) { } + /** @brief Constructor given a Comparator */ + LessEqual(const _Compare& _c) : c(_c) { } - /** @brief Copy constructor */ - LessEqual(const LessEqual<_Key, _Compare>& less_equal) - : c(less_equal.c) { } + /** @brief Copy constructor */ + LessEqual(const LessEqual<_Key, _Compare>& less_equal) + : c(less_equal.c) { } - /** @brief Operator() */ - bool operator()(const _Key& k1, const _Key& k2) const - { return !c(k2, k1); } - }; + /** @brief Operator() */ + bool + operator()(const _Key& k1, const _Key& k2) const + { return !c(k2, k1); } + }; /** @brief Parallel red-black tree. @@ -240,28 +240,28 @@ namespace __gnu_parallel * @param __last Last element of the input */ template - void - _M_insert_unique(_InputIterator __first, _InputIterator __last) - { - if (__first==__last) return; - if (_GLIBCXX_PARALLEL_CONDITION(true)) - if (base_type::_M_impl._M_node_count == 0) - { - _M_bulk_insertion_construction(__first, __last, true, - strictly_less); - _GLIBCXX_PARALLEL_ASSERT(rb_verify()); - } + void + _M_insert_unique(_InputIterator __first, _InputIterator __last) + { + if (__first == __last) + return; + + if (_GLIBCXX_PARALLEL_CONDITION(true)) + if (base_type::_M_impl._M_node_count == 0) + { + _M_bulk_insertion_construction(__first, __last, true, + strictly_less); + _GLIBCXX_PARALLEL_ASSERT(rb_verify()); + } + else + { + _M_bulk_insertion_construction(__first, __last, false, + strictly_less); + _GLIBCXX_PARALLEL_ASSERT(rb_verify()); + } else - { - _M_bulk_insertion_construction(__first, __last, false, - strictly_less); - _GLIBCXX_PARALLEL_ASSERT(rb_verify()); - } - else - { base_type::_M_insert_unique(__first, __last); - } - } + } /** @brief Parallel replacement of the sequential * std::_Rb_tree::_M_insert_equal() @@ -272,19 +272,21 @@ namespace __gnu_parallel * @param __first First element of the input * @param __last Last element of the input */ template - void - _M_insert_equal(_InputIterator __first, _InputIterator __last) - { - if (__first==__last) return; - if (_GLIBCXX_PARALLEL_CONDITION(true)) - if (base_type::_M_impl._M_node_count == 0) - _M_bulk_insertion_construction(__first, __last, true, less_equal); + void + _M_insert_equal(_InputIterator __first, _InputIterator __last) + { + if (__first == __last) + return; + + if (_GLIBCXX_PARALLEL_CONDITION(true)) + if (base_type::_M_impl._M_node_count == 0) + _M_bulk_insertion_construction(__first, __last, true, less_equal); + else + _M_bulk_insertion_construction(__first, __last, false, less_equal); else - _M_bulk_insertion_construction(__first, __last, false, less_equal); - else - base_type::_M_insert_equal(__first, __last); - _GLIBCXX_PARALLEL_ASSERT(rb_verify()); - } + base_type::_M_insert_equal(__first, __last); + _GLIBCXX_PARALLEL_ASSERT(rb_verify()); + } private: @@ -295,274 +297,273 @@ namespace __gnu_parallel * @param ranker Calculates the position of a node in an array of nodes */ template - class nodes_initializer - { - /** @brief Renaming of tree size_type */ + class nodes_initializer + { + /** @brief Renaming of tree size_type */ - typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type; - typedef typename tree_type::size_type size_type; - public: + typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type; + typedef typename tree_type::size_type size_type; + public: - /** @brief mask[%i]= 0..01..1, where the number of 1s is %i+1 */ - size_type mask[sizeof(size_type)*8]; + /** @brief mask[%i]= 0..01..1, where the number of 1s is %i+1 */ + size_type mask[sizeof(size_type)*8]; - /** @brief Array of nodes (initial address) */ - const _Rb_tree_node_ptr* r_init; + /** @brief Array of nodes (initial address) */ + const _Rb_tree_node_ptr* r_init; - /** @brief Total number of (used) nodes */ - size_type n; + /** @brief Total number of (used) nodes */ + size_type n; - /** @brief Rank of the last tree node that can be calculated - taking into account a complete tree - */ - size_type splitting_point; + /** @brief Rank of the last tree node that can be calculated + taking into account a complete tree + */ + size_type splitting_point; - /** @brief Rank of the tree root */ - size_type rank_root; + /** @brief Rank of the tree root */ + size_type rank_root; - /** @brief Height of the tree */ - int height; + /** @brief Height of the tree */ + int height; - /** @brief Number of threads into which divide the work */ - const thread_index_t num_threads; + /** @brief Number of threads into which divide the work */ + const thread_index_t num_threads; - /** @brief Helper object to mind potential gaps in r_init */ - const ranker& rank; + /** @brief Helper object to mind potential gaps in r_init */ + const ranker& rank; - /** @brief Constructor - * @param r Array of nodes - * @param _n Total number of (used) nodes - * @param _num_threads Number of threads into which divide the work - * @param _rank Helper object to mind potential gaps in @c r_init */ - nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n, - const thread_index_t _num_threads, const ranker& _rank): - r_init(r), - n(_n), - num_threads(_num_threads), - rank(_rank) - { - height = log2(n); - splitting_point = 2 * (n - ((1 << height) - 1)) -1; + /** @brief Constructor + * @param r Array of nodes + * @param _n Total number of (used) nodes + * @param _num_threads Number of threads into which divide the work + * @param _rank Helper object to mind potential gaps in @c r_init */ + nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n, + const thread_index_t _num_threads, + const ranker& _rank) + : r_init(r), n(_n), num_threads(_num_threads), rank(_rank) + { + height = log2(n); + splitting_point = 2 * (n - ((1 << height) - 1)) -1; - // Rank root. - size_type max = 1 << (height + 1); - rank_root= (max-2) >> 1; - if (rank_root > splitting_point) - rank_root = complete_to_original(rank_root); + // Rank root. + size_type max = 1 << (height + 1); + rank_root= (max-2) >> 1; + if (rank_root > splitting_point) + rank_root = complete_to_original(rank_root); - mask[0] = 0x1; - for (unsigned int i = 1; i < sizeof(size_type)*8; ++i) - { + mask[0] = 0x1; + for (unsigned int i = 1; i < sizeof(size_type)*8; ++i) mask[i] = (mask[i-1] << 1) + 1; - } - } + } - /** @brief Query for tree height - * @return Tree height */ - int - get_height() const - { return height; } + /** @brief Query for tree height + * @return Tree height */ + int + get_height() const + { return height; } - /** @brief Query for the splitting point - * @return Splitting point */ - size_type - get_shifted_splitting_point() const - { return rank.get_shifted_rank(splitting_point, 0); } + /** @brief Query for the splitting point + * @return Splitting point */ + size_type + get_shifted_splitting_point() const + { return rank.get_shifted_rank(splitting_point, 0); } - /** @brief Query for the tree root node - * @return Tree root node */ - _Rb_tree_node_ptr - get_root() const - { return r_init[rank.get_shifted_rank(rank_root,num_threads/2)]; } + /** @brief Query for the tree root node + * @return Tree root node */ + _Rb_tree_node_ptr + get_root() const + { return r_init[rank.get_shifted_rank(rank_root,num_threads/2)]; } - /** @brief Calculation of the parent position in the array of nodes - * @hideinitializer */ + /** @brief Calculation of the parent position in the array of nodes + * @hideinitializer */ #define CALCULATE_PARENT \ - if (p_s> splitting_point) \ - p_s = complete_to_original(p_s); \ - int s_r = rank.get_shifted_rank(p_s,iam); \ - r->_M_parent = r_init[s_r]; \ + if (p_s> splitting_point) \ + p_s = complete_to_original(p_s); \ + int s_r = rank.get_shifted_rank(p_s,iam); \ + r->_M_parent = r_init[s_r]; \ \ - /** @brief Link a node with its parent and children taking into - account that its rank (without gaps) is different to that in - a complete tree - * @param r Pointer to the node - * @param iam Partition of the array in which the node is, where - * iam is in [0..num_threads) - * @sa link_complete */ - void - link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const - { - size_type real_pos = rank.get_real_rank(&r-r_init, iam); - size_type l_s, r_s, p_s; - int mod_pos= original_to_complete(real_pos); - int zero= first_0_right(mod_pos); + /** @brief Link a node with its parent and children taking into + account that its rank (without gaps) is different to that in + a complete tree + * @param r Pointer to the node + * @param iam Partition of the array in which the node is, where + * iam is in [0..num_threads) + * @sa link_complete */ + void + link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const + { + size_type real_pos = rank.get_real_rank(&r-r_init, iam); + size_type l_s, r_s, p_s; + int mod_pos= original_to_complete(real_pos); + int zero= first_0_right(mod_pos); - // 1. Convert n to n', where n' will be its rank if the tree - // was complete - // 2. Calculate neighbours for n' - // 3. Convert the neighbors n1', n2' and n3' to their - // appropriate values n1, n2, n3. Note that it must be - // checked that these neighbors actually exist. - calculate_shifts_pos_level(mod_pos, zero, l_s, r_s, p_s); - if (l_s > splitting_point) - { - _GLIBCXX_PARALLEL_ASSERT(r_s > splitting_point); - if (zero == 1) - { - r->_M_left = 0; - r->_M_right = 0; - } - else - { - r->_M_left= r_init[rank.get_shifted_rank(complete_to_original(l_s),iam)]; - r->_M_right= r_init[rank.get_shifted_rank(complete_to_original(r_s),iam)]; - } - - } - else{ - r->_M_left= r_init[rank.get_shifted_rank(l_s,iam)]; - if (zero != 1) + // 1. Convert n to n', where n' will be its rank if the tree + // was complete + // 2. Calculate neighbours for n' + // 3. Convert the neighbors n1', n2' and n3' to their + // appropriate values n1, n2, n3. Note that it must be + // checked that these neighbors actually exist. + calculate_shifts_pos_level(mod_pos, zero, l_s, r_s, p_s); + if (l_s > splitting_point) { - r->_M_right= r_init[rank.get_shifted_rank(complete_to_original(r_s),iam)]; + _GLIBCXX_PARALLEL_ASSERT(r_s > splitting_point); + if (zero == 1) + { + r->_M_left = 0; + r->_M_right = 0; + } + else + { + r->_M_left = + r_init[rank.get_shifted_rank(complete_to_original(l_s), + iam)]; + r->_M_right = + r_init[rank.get_shifted_rank(complete_to_original(r_s), + iam)]; + } } else { - r->_M_right = 0; + r->_M_left= r_init[rank.get_shifted_rank(l_s,iam)]; + if (zero != 1) + r->_M_right + = r_init[rank.get_shifted_rank(complete_to_original(r_s), + iam)]; + else + r->_M_right = 0; } + r->_M_color = std::_S_black; + CALCULATE_PARENT; } - r->_M_color = std::_S_black; - CALCULATE_PARENT; - } - /** @brief Link a node with its parent and children taking into - account that its rank (without gaps) is the same as that in - a complete tree - * @param r Pointer to the node - * @param iam Partition of the array in which the node is, where - * iam is in [0..@c num_threads) - * @sa link_incomplete - */ - void - link_complete(const _Rb_tree_node_ptr& r, const int iam) const - { - size_type real_pos = rank.get_real_rank(&r-r_init, iam); - size_type p_s; + /** @brief Link a node with its parent and children taking into + account that its rank (without gaps) is the same as that in + a complete tree + * @param r Pointer to the node + * @param iam Partition of the array in which the node is, where + * iam is in [0..@c num_threads) + * @sa link_incomplete + */ + void + link_complete(const _Rb_tree_node_ptr& r, const int iam) const + { + size_type real_pos = rank.get_real_rank(&r-r_init, iam); + size_type p_s; - // Test if it is a leaf on the last not necessarily full level - if ((real_pos & mask[0]) == 0) - { - if ((real_pos & 0x2) == 0) - p_s = real_pos + 1; - else - p_s = real_pos - 1; - r->_M_color = std::_S_red; - r->_M_left = 0; + // Test if it is a leaf on the last not necessarily full level + if ((real_pos & mask[0]) == 0) + { + if ((real_pos & 0x2) == 0) + p_s = real_pos + 1; + else + p_s = real_pos - 1; + r->_M_color = std::_S_red; + r->_M_left = 0; r->_M_right = 0; - } - else - { - size_type l_s, r_s; - int zero = first_0_right(real_pos); - calculate_shifts_pos_level(real_pos, zero, l_s, r_s, p_s); - r->_M_color = std::_S_black; + } + else + { + size_type l_s, r_s; + int zero = first_0_right(real_pos); + calculate_shifts_pos_level(real_pos, zero, l_s, r_s, p_s); + r->_M_color = std::_S_black; - r->_M_left = r_init[rank.get_shifted_rank(l_s,iam)]; - if (r_s > splitting_point) - r_s = complete_to_original(r_s); - r->_M_right = r_init[rank.get_shifted_rank(r_s,iam)]; - } - CALCULATE_PARENT; - } + r->_M_left = r_init[rank.get_shifted_rank(l_s,iam)]; + if (r_s > splitting_point) + r_s = complete_to_original(r_s); + r->_M_right = r_init[rank.get_shifted_rank(r_s,iam)]; + } + CALCULATE_PARENT; + } #undef CALCULATE_PARENT - private: - /** @brief Change of "base": Convert the rank in the actual tree - into the corresponding rank if the tree was complete - * @param pos Rank in the actual incomplete tree - * @return Rank in the corresponding complete tree - * @sa complete_to_original */ - int - original_to_complete(const int pos) const - { return (pos << 1) - splitting_point; } + private: + /** @brief Change of "base": Convert the rank in the actual tree + into the corresponding rank if the tree was complete + * @param pos Rank in the actual incomplete tree + * @return Rank in the corresponding complete tree + * @sa complete_to_original */ + int + original_to_complete(const int pos) const + { return (pos << 1) - splitting_point; } - /** @brief Change of "base": Convert the rank if the tree was - complete into the corresponding rank in the actual tree - * @param pos Rank in the complete tree - * @return Rank in the actual incomplete tree - * @sa original_to_complete */ - int - complete_to_original(const int pos) const - { return (pos + splitting_point) >> 1; } + /** @brief Change of "base": Convert the rank if the tree was + complete into the corresponding rank in the actual tree + * @param pos Rank in the complete tree + * @return Rank in the actual incomplete tree + * @sa original_to_complete */ + int + complete_to_original(const int pos) const + { return (pos + splitting_point) >> 1; } - /** @brief Calculate the rank in the complete tree of the parent - and children of a node - * @param pos Rank in the complete tree of the node whose parent - * and children rank must be calculated - * @param level Tree level in which the node at pos is in - * (starting to count at leaves). @pre @c level > 1 - * @param left_shift Rank in the complete tree of the left child - * of pos (out parameter) - * @param right_shift Rank in the complete tree of the right - * child of pos (out parameter) - * @param parent_shift Rank in the complete tree of the parent - * of pos (out parameter) - */ - void - calculate_shifts_pos_level(const size_type pos, const int level, - size_type& left_shift, size_type& right_shift, - size_type& parent_shift) const - { - int stride = 1 << (level -1); - left_shift = pos - stride; - right_shift = pos + stride; - if (((pos >> (level + 1)) & 0x1) == 0) - parent_shift = pos + 2*stride; - else - parent_shift = pos - 2*stride; - } + /** @brief Calculate the rank in the complete tree of the parent + and children of a node + * @param pos Rank in the complete tree of the node whose parent + * and children rank must be calculated + * @param level Tree level in which the node at pos is in + * (starting to count at leaves). @pre @c level > 1 + * @param left_shift Rank in the complete tree of the left child + * of pos (out parameter) + * @param right_shift Rank in the complete tree of the right + * child of pos (out parameter) + * @param parent_shift Rank in the complete tree of the parent + * of pos (out parameter) + */ + void + calculate_shifts_pos_level(const size_type pos, const int level, + size_type& left_shift, + size_type& right_shift, + size_type& parent_shift) const + { + int stride = 1 << (level -1); + left_shift = pos - stride; + right_shift = pos + stride; + if (((pos >> (level + 1)) & 0x1) == 0) + parent_shift = pos + 2*stride; + else + parent_shift = pos - 2*stride; + } - /** @brief Search for the first 0 bit (growing the weight) - * @param x Binary number (corresponding to a rank in the tree) - * whose first 0 bit must be calculated - * @return Position of the first 0 bit in @c x (starting to - * count with 1) - */ - int - first_0_right(const size_type x) const - { - if ((x & 0x2) == 0) - return 1; - else - return first_0_right_bs(x); - } + /** @brief Search for the first 0 bit (growing the weight) + * @param x Binary number (corresponding to a rank in the tree) + * whose first 0 bit must be calculated + * @return Position of the first 0 bit in @c x (starting to + * count with 1) + */ + int + first_0_right(const size_type x) const + { + if ((x & 0x2) == 0) + return 1; + else + return first_0_right_bs(x); + } - /** @brief Search for the first 0 bit (growing the weight) using - * binary search - * - * Binary search can be used instead of a naive loop using the - * masks in mask array - * @param x Binary number (corresponding to a rank in the tree) - * whose first 0 bit must be calculated - * @param k_beg Position in which to start searching. By default is 2. - * @return Position of the first 0 bit in x (starting to count with 1) */ - int - first_0_right_bs(const size_type x, int k_beg=2) const - { - int k_end = sizeof(size_type)*8; - size_type not_x = x ^ mask[k_end-1]; - while ((k_end-k_beg) > 1) - { - int k = k_beg + (k_end-k_beg)/2; - if ((not_x & mask[k-1]) != 0) - k_end = k; - else - k_beg = k; - } - return k_beg; - } + /** @brief Search for the first 0 bit (growing the weight) using + * binary search + * + * Binary search can be used instead of a naive loop using the + * masks in mask array + * @param x Binary number (corresponding to a rank in the tree) + * whose first 0 bit must be calculated + * @param k_beg Position in which to start searching. By default is 2. + * @return Position of the first 0 bit in x (starting to count with 1) */ + int + first_0_right_bs(const size_type x, int k_beg=2) const + { + int k_end = sizeof(size_type)*8; + size_type not_x = x ^ mask[k_end-1]; + while ((k_end-k_beg) > 1) + { + int k = k_beg + (k_end-k_beg)/2; + if ((not_x & mask[k-1]) != 0) + k_end = k; + else + k_beg = k; + } + return k_beg; + } }; /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ @@ -605,18 +606,17 @@ namespace __gnu_parallel * @param _num_threads Number of partitions (and threads that * work on it) */ ranker_gaps(const size_type* size_p, const size_type* shift_r, - const thread_index_t _num_threads) : - beg_shift_partition(size_p), - rank_shift(shift_r), + const thread_index_t _num_threads) + : beg_shift_partition(size_p), rank_shift(shift_r), num_threads(_num_threads) { beg_partition = new size_type[num_threads+1]; beg_partition[0] = 0; for (int i = 1; i <= num_threads; ++i) - { - beg_partition[i] = beg_partition[i-1] + (beg_shift_partition[i] - beg_shift_partition[i-1]) - (rank_shift[i] - rank_shift[i-1]); - - } + beg_partition[i] = (beg_partition[i-1] + + (beg_shift_partition[i] + - beg_shift_partition[i-1]) + - (rank_shift[i] - rank_shift[i-1])); // Ghost element, strictly larger than any index requested. ++beg_partition[num_threads]; @@ -728,156 +728,163 @@ namespace __gnu_parallel * @param _Comp Comparator to invert * @param _Iterator Iterator to the elements to compare */ template - class gr_or_eq - { - /** @brief Renaming value_type of _Iterator */ - typedef typename std::iterator_traits<_Iterator>::value_type value_type; - - /** @brief Comparator to be inverted */ - const _Comp comp; - - public: - /** @brief Constructor - * @param c Comparator */ - gr_or_eq(const _Comp& c) : comp(c) { } - - /** @brief Operator() - * @param a First value to compare - * @param b Second value to compare */ - bool operator()(const value_type& a, const value_type& b) const + class gr_or_eq { - if (not (comp(_KeyOfValue()(a), _KeyOfValue()(b)))) - return true; - return false; - } - }; + /** @brief Renaming value_type of _Iterator */ + typedef typename std::iterator_traits<_Iterator>::value_type + value_type; + + /** @brief Comparator to be inverted */ + const _Comp comp; + + public: + /** @brief Constructor + * @param c Comparator */ + gr_or_eq(const _Comp& c) : comp(c) { } + + /** @brief Operator() + * @param a First value to compare + * @param b Second value to compare */ + bool + operator()(const value_type& a, const value_type& b) const + { + if (not (comp(_KeyOfValue()(a), _KeyOfValue()(b)))) + return true; + return false; + } + }; /** @brief Helper comparator class: Passed as a parameter of list_partition to check that a sequence is sorted * @param _InputIterator Iterator to the elements to compare * @param _CompIsSorted Comparator to check for sortednesss */ template - class is_sorted_functor - { - /** @brief Element to compare with (first parameter of comp) */ - _InputIterator prev; - - /** @brief Comparator to check for sortednesss */ - const _CompIsSorted comp; - - /** @brief Sum up the history of the operator() of this - * comparator class Its value is true if all calls to comp from - * this class have returned true. It is false otherwise */ - bool sorted; - - public: - /** @brief Constructor - * - * Sorted is set to true - * @param first Element to compare with the first time the - * operator() is called - * @param c Comparator to check for sortedness */ - is_sorted_functor(const _InputIterator first, const _CompIsSorted c) - : prev(first), comp(c), sorted(true) { } - - /** @brief Operator() with only one explicit parameter. Updates - the class member @c prev and sorted. - * @param it Iterator to the element which must be compared to - * the element pointed by the the class member @c prev */ - void operator()(const _InputIterator it) + class is_sorted_functor { - if (sorted and it != prev and comp(_KeyOfValue()(*it), - _KeyOfValue()(*prev))) - sorted = false; - prev = it; - } + /** @brief Element to compare with (first parameter of comp) */ + _InputIterator prev; - /** @brief Query method for sorted - * @return Current value of sorted */ - bool is_sorted() const - { - return sorted; - } - }; + /** @brief Comparator to check for sortednesss */ + const _CompIsSorted comp; + + /** @brief Sum up the history of the operator() of this + * comparator class Its value is true if all calls to comp from + * this class have returned true. It is false otherwise */ + bool sorted; + + public: + /** @brief Constructor + * + * Sorted is set to true + * @param first Element to compare with the first time the + * operator() is called + * @param c Comparator to check for sortedness */ + is_sorted_functor(const _InputIterator first, const _CompIsSorted c) + : prev(first), comp(c), sorted(true) { } + + /** @brief Operator() with only one explicit parameter. Updates + the class member @c prev and sorted. + * @param it Iterator to the element which must be compared to + * the element pointed by the the class member @c prev */ + void + operator()(const _InputIterator it) + { + if (sorted and it != prev and comp(_KeyOfValue()(*it), + _KeyOfValue()(*prev))) + sorted = false; + prev = it; + } + + /** @brief Query method for sorted + * @return Current value of sorted */ + bool + is_sorted() const + { return sorted; } + }; /** @brief Helper functor: sort the input based upon elements instead of keys * @param KeyComparator Comparator for the key of values */ template - class ValueCompare - : public std::binary_function - { - /** @brief Comparator for the key of values */ - const KeyComparator comp; + class ValueCompare + : public std::binary_function + { + /** @brief Comparator for the key of values */ + const KeyComparator comp; - public: - /** @brief Constructor - * @param c Comparator for the key of values */ - ValueCompare(const KeyComparator& c): comp(c) { } + public: + /** @brief Constructor + * @param c Comparator for the key of values */ + ValueCompare(const KeyComparator& c): comp(c) { } - /** @brief Operator(): Analogous to comp but for values and not keys - * @param v1 First value to compare - * @param v2 Second value to compare - * @return Result of the comparison */ - bool operator()(const value_type& v1, const value_type& v2) const - { return comp(_KeyOfValue()(v1),_KeyOfValue()(v2)); } - }; + /** @brief Operator(): Analogous to comp but for values and not keys + * @param v1 First value to compare + * @param v2 Second value to compare + * @return Result of the comparison */ + bool + operator()(const value_type& v1, const value_type& v2) const + { return comp(_KeyOfValue()(v1),_KeyOfValue()(v2)); } + }; /** @brief Helper comparator: compare a key with the key in a node * @param _Comparator Comparator for keys */ template - struct compare_node_key - { - /** @brief Comparator for keys */ - const _Comparator& c; + struct compare_node_key + { + /** @brief Comparator for keys */ + const _Comparator& c; - /** @brief Constructor - * @param _c Comparator for keys */ - compare_node_key(const _Comparator& _c) : c(_c) { } + /** @brief Constructor + * @param _c Comparator for keys */ + compare_node_key(const _Comparator& _c) : c(_c) { } - /** @brief Operator() with the first parameter being a node - * @param r Node whose key is to be compared - * @param k Key to be compared - * @return Result of the comparison */ - bool operator()(const _Rb_tree_node_ptr r, const key_type& k) const - { return c(base_type::_S_key(r),k); } + /** @brief Operator() with the first parameter being a node + * @param r Node whose key is to be compared + * @param k Key to be compared + * @return Result of the comparison */ + bool + operator()(const _Rb_tree_node_ptr r, const key_type& k) const + { return c(base_type::_S_key(r),k); } - /** @brief Operator() with the second parameter being a node - * @param k Key to be compared - * @param r Node whose key is to be compared - * @return Result of the comparison */ - bool operator()(const key_type& k, const _Rb_tree_node_ptr r) const - { return c(k, base_type::_S_key(r)); } - }; + /** @brief Operator() with the second parameter being a node + * @param k Key to be compared + * @param r Node whose key is to be compared + * @return Result of the comparison */ + bool + operator()(const key_type& k, const _Rb_tree_node_ptr r) const + { return c(k, base_type::_S_key(r)); } + }; /** @brief Helper comparator: compare a key with the key of a value pointed by an iterator * @param _Comparator Comparator for keys */ template - struct compare_value_key - { - /** @brief Comparator for keys */ - const _Comparator& c; + struct compare_value_key + { + /** @brief Comparator for keys */ + const _Comparator& c; - /** @brief Constructor - * @param _c Comparator for keys */ - compare_value_key(const _Comparator& _c) : c(_c){ } + /** @brief Constructor + * @param _c Comparator for keys */ + compare_value_key(const _Comparator& _c) : c(_c){ } - /** @brief Operator() with the first parameter being an iterator - * @param v Iterator to the value whose key is to be compared - * @param k Key to be compared - * @return Result of the comparison */ - bool operator()(const _Iterator& v, const key_type& k) const - { return c(_KeyOfValue()(*v),k); } + /** @brief Operator() with the first parameter being an iterator + * @param v Iterator to the value whose key is to be compared + * @param k Key to be compared + * @return Result of the comparison */ + bool + operator()(const _Iterator& v, const key_type& k) const + { return c(_KeyOfValue()(*v),k); } - /** @brief Operator() with the second parameter being an iterator - * @param k Key to be compared - * @param v Iterator to the value whose key is to be compared - * @return Result of the comparison */ - bool operator()(const key_type& k, const _Iterator& v) const - { return c(k, _KeyOfValue()(*v)); } - }; + /** @brief Operator() with the second parameter being an iterator + * @param k Key to be compared + * @param v Iterator to the value whose key is to be compared + * @return Result of the comparison */ + bool + operator()(const key_type& k, const _Iterator& v) const + { return c(k, _KeyOfValue()(*v)); } + }; /** @brief Helper class of _Rb_tree to avoid some symmetric code in tree operations */ @@ -886,13 +893,15 @@ namespace __gnu_parallel /** @brief Obtain the conceptual left child of a node * @param parent Node whose child must be obtained * @return Reference to the child node */ - static _Rb_tree_node_base*& left(_Rb_tree_node_base* parent) + static _Rb_tree_node_base*& + left(_Rb_tree_node_base* parent) { return parent->_M_left; } /** @brief Obtain the conceptual right child of a node * @param parent Node whose child must be obtained * @return Reference to the child node */ - static _Rb_tree_node_base*& right(_Rb_tree_node_base* parent) + static _Rb_tree_node_base*& + right(_Rb_tree_node_base* parent) { return parent->_M_right; } }; @@ -901,22 +910,24 @@ namespace __gnu_parallel * @param S Symmetry to inverse * @sa LeftRight */ template - struct Opposite - { - /** @brief Obtain the conceptual left child of a node, inverting - the symmetry - * @param parent Node whose child must be obtained - * @return Reference to the child node */ - static _Rb_tree_node_base*& left(_Rb_tree_node_base* parent) - { return S::right(parent);} + struct Opposite + { + /** @brief Obtain the conceptual left child of a node, inverting + the symmetry + * @param parent Node whose child must be obtained + * @return Reference to the child node */ + static _Rb_tree_node_base*& + left(_Rb_tree_node_base* parent) + { return S::right(parent);} - /** @brief Obtain the conceptual right child of a node, - inverting the symmetry - * @param parent Node whose child must be obtained - * @return Reference to the child node */ - static _Rb_tree_node_base*& right(_Rb_tree_node_base* parent) - { return S::left(parent);} - }; + /** @brief Obtain the conceptual right child of a node, + inverting the symmetry + * @param parent Node whose child must be obtained + * @return Reference to the child node */ + static _Rb_tree_node_base*& + right(_Rb_tree_node_base* parent) + { return S::left(parent);} + }; /** @brief Inverse symmetry of LeftRight */ typedef Opposite RightLeft; @@ -926,148 +937,153 @@ namespace __gnu_parallel * @param Comparator Comparator for values * @param _ValuePtr Pointer to values */ template - class PtrComparator - : public std::binary_function<_ValuePtr, _ValuePtr, bool> - { - /** @brief Comparator for values */ - Comparator comp; + class PtrComparator + : public std::binary_function<_ValuePtr, _ValuePtr, bool> + { + /** @brief Comparator for values */ + Comparator comp; - public: - /** @brief Constructor - * @param comp Comparator for values */ - PtrComparator(Comparator comp) : comp(comp) { } + public: + /** @brief Constructor + * @param comp Comparator for values */ + PtrComparator(Comparator comp) : comp(comp) { } - /** @brief Operator(): compare the values instead of the pointers - * @param v1 Pointer to the first element to compare - * @param v2 Pointer to the second element to compare */ - bool operator()(const _ValuePtr& v1, const _ValuePtr& v2) const - { return comp(*v1,*v2); } - }; + /** @brief Operator(): compare the values instead of the pointers + * @param v1 Pointer to the first element to compare + * @param v2 Pointer to the second element to compare */ + bool + operator()(const _ValuePtr& v1, const _ValuePtr& v2) const + { return comp(*v1,*v2); } + }; /** @brief Iterator whose elements are pointers * @param value_type Type pointed by the pointers */ template - class PtrIterator - { - public: - /** @brief The iterator category is random access iterator */ - typedef typename std::random_access_iterator_tag iterator_category; - typedef _ValueTp value_type; - typedef size_t difference_type; - typedef value_type* ValuePtr; - typedef ValuePtr& reference; - typedef value_type** pointer; - - /** @brief Element accessed by the iterator */ - value_type** ptr; - - /** @brief Trivial constructor */ - PtrIterator() { } - - /** @brief Constructor from an element */ - PtrIterator(const ValuePtr& __i) : ptr(&__i) { } - - /** @brief Constructor from a pointer */ - PtrIterator(const pointer& __i) : ptr(__i) { } - - /** @brief Copy constructor */ - PtrIterator(const PtrIterator& __i) : ptr(__i.ptr) { } - - reference - operator*() const - { return **ptr; } - - ValuePtr - operator->() const - { return *ptr; } - - /** @brief Bidirectional iterator requirement */ - PtrIterator& - operator++() + class PtrIterator { - ++ptr; - return *this; - } + public: + /** @brief The iterator category is random access iterator */ + typedef typename std::random_access_iterator_tag iterator_category; + typedef _ValueTp value_type; + typedef size_t difference_type; + typedef value_type* ValuePtr; + typedef ValuePtr& reference; + typedef value_type** pointer; - /** @brief Bidirectional iterator requirement */ - PtrIterator - operator++(int) - { return PtrIterator(ptr++); } + /** @brief Element accessed by the iterator */ + value_type** ptr; - /** @brief Bidirectional iterator requirement */ - PtrIterator& - operator--() - { - --ptr; - return *this; - } + /** @brief Trivial constructor */ + PtrIterator() { } - /** @brief Bidirectional iterator requirement */ - PtrIterator - operator--(int) - { return PtrIterator(ptr--); } + /** @brief Constructor from an element */ + PtrIterator(const ValuePtr& __i) : ptr(&__i) { } - /** @brief Random access iterator requirement */ - reference - operator[](const difference_type& __n) const - { return *ptr[__n]; } + /** @brief Constructor from a pointer */ + PtrIterator(const pointer& __i) : ptr(__i) { } - /** @brief Random access iterator requirement */ - PtrIterator& - operator+=(const difference_type& __n) - { - ptr += __n; - return *this; - } + /** @brief Copy constructor */ + PtrIterator(const PtrIterator& __i) : ptr(__i.ptr) { } - /** @brief Random access iterator requirement */ - PtrIterator - operator+(const difference_type& __n) const - { return PtrIterator(ptr + __n); } + reference + operator*() const + { return **ptr; } - /** @brief Random access iterator requirement */ - PtrIterator& - operator-=(const difference_type& __n) - { - ptr -= __n; - return *this; - } + ValuePtr + operator->() const + { return *ptr; } - /** @brief Random access iterator requirement */ - PtrIterator - operator-(const difference_type& __n) const - { return PtrIterator(ptr - __n); } + /** @brief Bidirectional iterator requirement */ + PtrIterator& + operator++() + { + ++ptr; + return *this; + } - /** @brief Random access iterator requirement */ - difference_type - operator-(const PtrIterator& iter) const - { return ptr - iter.ptr; } + /** @brief Bidirectional iterator requirement */ + PtrIterator + operator++(int) + { return PtrIterator(ptr++); } - /** @brief Random access iterator requirement */ - difference_type - operator+(const PtrIterator& iter) const - { return ptr + iter.ptr; } + /** @brief Bidirectional iterator requirement */ + PtrIterator& + operator--() + { + --ptr; + return *this; + } - /** @brief Allow assignment of an element ValuePtr to the iterator */ - PtrIterator& operator=(const ValuePtr sptr) - { - ptr = &sptr; - return *this; - } + /** @brief Bidirectional iterator requirement */ + PtrIterator + operator--(int) + { return PtrIterator(ptr--); } - PtrIterator& operator=(const PtrIterator& piter) - { - ptr = piter.ptr; - return *this; - } + /** @brief Random access iterator requirement */ + reference + operator[](const difference_type& __n) const + { return *ptr[__n]; } - bool operator==(const PtrIterator& piter) - { return ptr == piter.ptr; } + /** @brief Random access iterator requirement */ + PtrIterator& + operator+=(const difference_type& __n) + { + ptr += __n; + return *this; + } - bool operator!=(const PtrIterator& piter) - { return ptr != piter.ptr; } + /** @brief Random access iterator requirement */ + PtrIterator + operator+(const difference_type& __n) const + { return PtrIterator(ptr + __n); } - }; + /** @brief Random access iterator requirement */ + PtrIterator& + operator-=(const difference_type& __n) + { + ptr -= __n; + return *this; + } + + /** @brief Random access iterator requirement */ + PtrIterator + operator-(const difference_type& __n) const + { return PtrIterator(ptr - __n); } + + /** @brief Random access iterator requirement */ + difference_type + operator-(const PtrIterator& iter) const + { return ptr - iter.ptr; } + + /** @brief Random access iterator requirement */ + difference_type + operator+(const PtrIterator& iter) const + { return ptr + iter.ptr; } + + /** @brief Allow assignment of an element ValuePtr to the iterator */ + PtrIterator& + operator=(const ValuePtr sptr) + { + ptr = &sptr; + return *this; + } + + PtrIterator& + operator=(const PtrIterator& piter) + { + ptr = piter.ptr; + return *this; + } + + bool + operator==(const PtrIterator& piter) + { return ptr == piter.ptr; } + + bool + operator!=(const PtrIterator& piter) + { return ptr != piter.ptr; } + + }; /** @brief Bulk insertion helper: synchronization and construction @@ -1207,47 +1223,55 @@ namespace __gnu_parallel * saved so that afterwards the sequence can be processed * effectively in parallel. */ template - void - _M_bulk_insertion_construction(const _InputIterator __first, const _InputIterator __last, const bool is_construction, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - thread_index_t num_threads = get_max_threads(); - size_type n; - size_type beg_partition[num_threads+1]; - _InputIterator access[num_threads+1]; - beg_partition[0] = 0; - bool is_sorted= is_sorted_distance_accessors(__first, __last, access, beg_partition,n, num_threads, std::__iterator_category(__first)); + void + _M_bulk_insertion_construction(const _InputIterator __first, + const _InputIterator __last, + const bool is_construction, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + thread_index_t num_threads = get_max_threads(); + size_type n; + size_type beg_partition[num_threads+1]; + _InputIterator access[num_threads+1]; + beg_partition[0] = 0; + bool is_sorted = + is_sorted_distance_accessors(__first, __last, access, + beg_partition, n, num_threads, + std::__iterator_category(__first)); - if (not is_sorted) - { - _M_not_sorted_bulk_insertion_construction(access, beg_partition, n, num_threads, is_construction, strictly_less_or_less_equal); - } - else - { - // The vector must be moved... all ranges must have at least - // one element, or make just sequential??? - if (static_cast(num_threads) > n) - { - int j = 1; - for (int i = 1; i <= num_threads; ++i) - { - if (beg_partition[j-1] != beg_partition[i]) - { - beg_partition[j] = beg_partition[i]; - access[j] = access[i]; - ++j; - } - } - num_threads = static_cast(n); - } + if (not is_sorted) + _M_not_sorted_bulk_insertion_construction( + access, beg_partition, n, num_threads, + is_construction, strictly_less_or_less_equal); + else + { + // The vector must be moved... all ranges must have at least + // one element, or make just sequential??? + if (static_cast(num_threads) > n) + { + int j = 1; + for (int i = 1; i <= num_threads; ++i) + { + if (beg_partition[j-1] != beg_partition[i]) + { + beg_partition[j] = beg_partition[i]; + access[j] = access[i]; + ++j; + } + } + num_threads = static_cast(n); + } - if (is_construction) - _M_sorted_bulk_construction(access, beg_partition, n, num_threads, - strictly_less_or_less_equal); - else - _M_sorted_bulk_insertion(access, beg_partition, n, num_threads, - strictly_less_or_less_equal); - } - } + if (is_construction) + _M_sorted_bulk_construction(access, beg_partition, n, + num_threads, + strictly_less_or_less_equal); + else + _M_sorted_bulk_insertion(access, beg_partition, n, num_threads, + strictly_less_or_less_equal); + } + } /** @brief Bulk construction and insertion helper method on an * input sequence which is not sorted @@ -1273,39 +1297,54 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_not_sorted_bulk_insertion_construction(_InputIterator* access, - size_type* beg_partition, - const size_type n, - const thread_index_t num_threads, - const bool is_construction, - StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - // Copy entire elements. In the case of a map, we would be - // copying the pair. Therefore, the copy should be reconsidered - // when objects are big. Essentially two cases: - // - The key is small: make that the pair, is a pointer to data - // instead of a copy to it - // - The key is big: we simply have a pointer to the iterator + void + _M_not_sorted_bulk_insertion_construction(_InputIterator* access, + size_type* beg_partition, + const size_type n, + const thread_index_t + num_threads, + const bool is_construction, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + // Copy entire elements. In the case of a map, we would be + // copying the pair. Therefore, the copy should be reconsidered + // when objects are big. Essentially two cases: + // - The key is small: make that the pair, is a pointer to data + // instead of a copy to it + // - The key is big: we simply have a pointer to the iterator #if _GLIBCXX_TREE_FULL_COPY - nc_value_type* v = static_cast (::operator new(sizeof(nc_value_type)*(n+1))); + nc_value_type* v = + static_cast(::operator new(sizeof(nc_value_type) + * (n+1))); - uninitialized_copy_from_accessors(access, beg_partition, v, num_threads); + uninitialized_copy_from_accessors(access, beg_partition, + v, num_threads); - _M_not_sorted_bulk_insertion_construction > - (beg_partition, v, ValueCompare<_Compare>(base_type::_M_impl._M_key_compare), n, num_threads, is_construction, strictly_less_or_less_equal); + _M_not_sorted_bulk_insertion_construction > + (beg_partition, v, ValueCompare<_Compare>(base_type:: + _M_impl._M_key_compare), + n, num_threads, is_construction, strictly_less_or_less_equal); #else - // For sorting, we cannot use the new PtrIterator because we - // want the pointers to be exchanged and not the elements. - typedef PtrComparator, nc_value_type*> this_ptr_comparator; - nc_value_type** v = static_cast (::operator new(sizeof(nc_value_type*)*(n+1))); + // For sorting, we cannot use the new PtrIterator because we + // want the pointers to be exchanged and not the elements. + typedef PtrComparator, nc_value_type*> + this_ptr_comparator; + nc_value_type** v = + static_cast(::operator new(sizeof(nc_value_type*) + * (n+1))); - uninitialized_ptr_copy_from_accessors(access, beg_partition, v, num_threads); + uninitialized_ptr_copy_from_accessors(access, beg_partition, + v, num_threads); - _M_not_sorted_bulk_insertion_construction, this_ptr_comparator> - (beg_partition, v, this_ptr_comparator(ValueCompare<_Compare>(base_type::_M_impl._M_key_compare)), n, num_threads, is_construction, strictly_less_or_less_equal); + _M_not_sorted_bulk_insertion_construction, this_ptr_comparator> + (beg_partition, v, this_ptr_comparator( + ValueCompare<_Compare>(base_type::_M_impl._M_key_compare)), + n, num_threads, is_construction, strictly_less_or_less_equal); #endif - } + } /** @brief Bulk construction and insertion helper method on an * input sequence which is not sorted @@ -1327,25 +1366,40 @@ namespace __gnu_parallel * transparently with repetitions with respect to the uniqueness * of the wrapping container */ - template - void - _M_not_sorted_bulk_insertion_construction(size_type* beg_partition, ElementsToSort* v, Comparator comp, const size_type n, thread_index_t num_threads, const bool is_construction, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - // The accessors have been calculated for the non sorted. - num_threads = static_cast(std::min(num_threads, n)); + template + void + _M_not_sorted_bulk_insertion_construction(size_type* beg_partition, + ElementsToSort* v, + Comparator comp, + const size_type n, + thread_index_t num_threads, + const bool is_construction, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + // The accessors have been calculated for the non sorted. + num_threads = + static_cast(std::min(num_threads, n)); - std::stable_sort(v, v+n, comp); + std::stable_sort(v, v+n, comp); - IteratorSortedElements sorted_access[num_threads+1]; - range_accessors(IteratorSortedElements(v), IteratorSortedElements(v+n), sorted_access, beg_partition, n, num_threads, std::__iterator_category(v)); + IteratorSortedElements sorted_access[num_threads+1]; + range_accessors(IteratorSortedElements(v), + IteratorSortedElements(v + n), + sorted_access, beg_partition, n, num_threads, + std::__iterator_category(v)); - // Partial template specialization not available. - if (is_construction) - _M_sorted_bulk_construction(sorted_access, beg_partition, n, num_threads, strictly_less_or_less_equal); - else - _M_sorted_bulk_insertion(sorted_access, beg_partition, n, num_threads, strictly_less_or_less_equal); - ::operator delete(v); - } + // Partial template specialization not available. + if (is_construction) + _M_sorted_bulk_construction(sorted_access, beg_partition, n, + num_threads, + strictly_less_or_less_equal); + else + _M_sorted_bulk_insertion(sorted_access, beg_partition, n, + num_threads, strictly_less_or_less_equal); + ::operator delete(v); + } /** @brief Construct a tree sequentially using the parallel routine * @param r_array Array of nodes from which to take the nodes to @@ -1414,31 +1468,37 @@ namespace __gnu_parallel * going to be shared */ template - _Rb_tree_node_ptr* - _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access, const size_type* beg_partition, const size_type n, const thread_index_t num_threads) - { - _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1))); - - // Allocate and initialize the nodes (don't check for uniqueness - // because the sequence is not necessarily sorted. -#pragma omp parallel num_threads(num_threads) + _Rb_tree_node_ptr* + _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access, + const size_type* + beg_partition, + const size_type n, + const thread_index_t + num_threads) { + _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>( + ::operator new (sizeof(_Rb_tree_node_ptr) * (n + 1))); + + // Allocate and initialize the nodes (don't check for uniqueness + // because the sequence is not necessarily sorted. +#pragma omp parallel num_threads(num_threads) + { #if USE_PAPI - PAPI_register_thread(); + PAPI_register_thread(); #endif - int iam = omp_get_thread_num(); - _Iterator it = access[iam]; - size_type i = beg_partition[iam]; - while (it!= access[iam+1]) - { - r[i] = base_type::_M_create_node(*it); - ++i; - ++it; - } + int iam = omp_get_thread_num(); + _Iterator it = access[iam]; + size_type i = beg_partition[iam]; + while (it!= access[iam+1]) + { + r[i] = base_type::_M_create_node(*it); + ++i; + ++it; + } + } + return r; } - return r; - } /** @brief Allocation of an array of nodes and initialization of @@ -1470,104 +1530,123 @@ namespace __gnu_parallel * of the wrapping container */ template - _Rb_tree_node_ptr* - _M_sorted_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type n, thread_index_t& num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - // Ghost node at the end to avoid extra comparisons in nodes_initializer. - _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1))); - r[n] = NULL; - - // Dealing with repetitions (EFFICIENCY ISSUE). - _Iterator access_copy[num_threads+1]; - for (int i = 0; i <= num_threads; ++i) - access_copy[i] = access[i]; - // Allocate and initialize the nodes -#pragma omp parallel num_threads(num_threads) + _Rb_tree_node_ptr* + _M_sorted_bulk_allocation_and_initialization(_Iterator* access, + size_type* beg_partition, + size_type* rank_shift, + const size_type n, + thread_index_t& num_threads, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) { + // Ghost node at the end to avoid extra comparisons + // in nodes_initializer. + _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>( + ::operator new(sizeof(_Rb_tree_node_ptr) * (n + 1))); + r[n] = NULL; + + // Dealing with repetitions (EFFICIENCY ISSUE). + _Iterator access_copy[num_threads+1]; + for (int i = 0; i <= num_threads; ++i) + access_copy[i] = access[i]; + // Allocate and initialize the nodes +#pragma omp parallel num_threads(num_threads) + { #if USE_PAPI - PAPI_register_thread(); + PAPI_register_thread(); #endif - thread_index_t iam = omp_get_thread_num(); - _Iterator prev = access[iam]; - size_type i = beg_partition[iam]; - _Iterator it = prev; - if (iam != 0) - { - --prev; - // Dealing with repetitions (CORRECTNESS ISSUE). - while (it!= access_copy[iam+1] and not strictly_less_or_less_equal(_KeyOfValue()(*prev), _KeyOfValue()(*it))) - { - _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev))); + thread_index_t iam = omp_get_thread_num(); + _Iterator prev = access[iam]; + size_type i = beg_partition[iam]; + _Iterator it = prev; + if (iam != 0) + { + --prev; + // Dealing with repetitions (CORRECTNESS ISSUE). + while (it!= access_copy[iam+1] + and not strictly_less_or_less_equal(_KeyOfValue()(*prev), + _KeyOfValue()(*it))) + { + _GLIBCXX_PARALLEL_ASSERT(not base_type:: + _M_impl._M_key_compare + (_KeyOfValue()(*it), + _KeyOfValue()(*prev))); + ++it; + } + access[iam] = it; + if (it != access_copy[iam+1]){ + r[i] = base_type::_M_create_node(*it); + ++i; + prev=it; ++it; } - access[iam] = it; - if (it != access_copy[iam+1]){ - r[i] = base_type::_M_create_node(*it); + //} + } + else + { + r[i] = base_type::_M_create_node(*prev); ++i; - prev=it; ++it; } - //} - } - else - { - r[i] = base_type::_M_create_node(*prev); - ++i; - ++it; - } - while (it!= access_copy[iam+1]) - { + while (it != access_copy[iam+1]) + { /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/ - if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it))) + if (strictly_less_or_less_equal(_KeyOfValue()(*prev), + _KeyOfValue()(*it))) { r[i] = base_type::_M_create_node(*it); ++i; prev=it; } - else{ - _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev))); - } + else + _GLIBCXX_PARALLEL_ASSERT(not base_type:: + _M_impl._M_key_compare + (_KeyOfValue()(*it), + _KeyOfValue()(*prev))); ++it; } + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + rank_shift[iam+1] = beg_partition[iam+1] - i; + } /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - rank_shift[iam+1] = beg_partition[iam+1] - i; - } - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - rank_shift[0] = 0; - /* Guarantee that there are no empty intervals. - - If an empty interval is found, is joined with the previous one - (the rank_shift of the previous is augmented with all the new - repetitions) - */ - thread_index_t i = 1; - while (i <= num_threads and rank_shift[i] != (beg_partition[i] - beg_partition[i-1])) - { - rank_shift[i] += rank_shift[i-1]; - ++i; - } - if (i <= num_threads) - { - thread_index_t j = i - 1; - while (true) - { - do - { - rank_shift[j] += rank_shift[i]; - ++i; - } while (i <= num_threads and rank_shift[i] == (beg_partition[i] - beg_partition[i-1])); + rank_shift[0] = 0; + /* Guarantee that there are no empty intervals. + - If an empty interval is found, is joined with the previous one + (the rank_shift of the previous is augmented with all the new + repetitions) + */ + thread_index_t i = 1; + while (i <= num_threads + and rank_shift[i] != (beg_partition[i] - beg_partition[i-1])) + { + rank_shift[i] += rank_shift[i-1]; + ++i; + } + if (i <= num_threads) + { + thread_index_t j = i - 1; + while (true) + { + do + { + rank_shift[j] += rank_shift[i]; + ++i; + } + while (i <= num_threads + and rank_shift[i] == (beg_partition[i] + - beg_partition[i-1])); - beg_partition[j] = beg_partition[i-1]; - access[j] = access[i-1]; - if (i > num_threads) break; - ++j; - - // Initialize with the previous. - rank_shift[j] = rank_shift[j-1]; - } - num_threads = j; - } - return r; + beg_partition[j] = beg_partition[i-1]; + access[j] = access[i-1]; + if (i > num_threads) break; + ++j; + // Initialize with the previous. + rank_shift[j] = rank_shift[j-1]; + } + num_threads = j; + } + return r; } /** @brief Allocation of an array of nodes and initialization of @@ -1598,42 +1677,45 @@ namespace __gnu_parallel * of the wrapping container */ template - _Rb_tree_node_ptr* - _M_sorted_no_gapped_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type& n, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - size_type* sums = static_cast (::operator new (sizeof(size_type)*n)); - // Allocate and initialize the nodes - /* try - {*/ -#pragma omp parallel num_threads(num_threads) + _Rb_tree_node_ptr* + _M_sorted_no_gapped_bulk_allocation_and_initialization + (_Iterator* access, size_type* beg_partition, size_type& n, + const thread_index_t num_threads, + StrictlyLessOrLessEqual strictly_less_or_less_equal) { + size_type* sums = + static_cast(::operator new (sizeof(size_type) * n)); + // Allocate and initialize the nodes + /* try + {*/ +#pragma omp parallel num_threads(num_threads) + { #if USE_PAPI - PAPI_register_thread(); + PAPI_register_thread(); #endif - int iam = omp_get_thread_num(); - _Iterator prev = access[iam]; - size_type i = beg_partition[iam]; - _Iterator it = prev; - if (iam !=0) - { - --prev; + int iam = omp_get_thread_num(); + _Iterator prev = access[iam]; + size_type i = beg_partition[iam]; + _Iterator it = prev; + if (iam !=0) + { + --prev; - // First iteration here, to update accessor in case was - // equal to the last element of the previous range + // First iteration here, to update accessor in case was + // equal to the last element of the previous range - // Dealing with repetitions (CORRECTNESS ISSUE). - if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it))) - { - sums[i] = 0; - prev=it; - } - else - { + // Dealing with repetitions (CORRECTNESS ISSUE). + if (strictly_less_or_less_equal(_KeyOfValue()(*prev), + _KeyOfValue()(*it))) + { + sums[i] = 0; + prev=it; + } + else sums[i] = 1; - } - ++i; - ++it; - } + ++i; + ++it; + } else { sums[i] = 0; @@ -1643,7 +1725,8 @@ namespace __gnu_parallel while (it!= access[iam+1]) { // Dealing with repetitions (CORRECTNESS ISSUE). - if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it))) + if (strictly_less_or_less_equal(_KeyOfValue()(*prev), + _KeyOfValue()(*it))) { sums[i] = 0; prev=it; @@ -1658,7 +1741,8 @@ namespace __gnu_parallel partial_sum(sums,sums + n, sums); n -= sums[n-1]; - _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1))); + _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>( + ::operator new(sizeof(_Rb_tree_node_ptr) * (n + 1))); r[n]=0; #pragma omp parallel num_threads(num_threads) @@ -1721,70 +1805,79 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_sorted_bulk_construction(_Iterator* access, size_type* beg_partition, const size_type n, thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - // Dealing with repetitions (EFFICIENCY ISSUE). - size_type rank_shift[num_threads+1]; + void + _M_sorted_bulk_construction(_Iterator* access, size_type* beg_partition, + const size_type n, + thread_index_t num_threads, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + // Dealing with repetitions (EFFICIENCY ISSUE). + size_type rank_shift[num_threads+1]; - _Rb_tree_node_ptr* r = _M_sorted_bulk_allocation_and_initialization(access, beg_partition, rank_shift, n, num_threads, strictly_less_or_less_equal); - - // Link the tree appropriately. - // Dealing with repetitions (EFFICIENCY ISSUE). - ranker_gaps rank(beg_partition, rank_shift, num_threads); - nodes_initializer nodes_init(r, n - rank_shift[num_threads], num_threads, rank); - size_type split = nodes_init.get_shifted_splitting_point(); + _Rb_tree_node_ptr* r = _M_sorted_bulk_allocation_and_initialization + (access, beg_partition, rank_shift, n, num_threads, + strictly_less_or_less_equal); + + // Link the tree appropriately. + // Dealing with repetitions (EFFICIENCY ISSUE). + ranker_gaps rank(beg_partition, rank_shift, num_threads); + nodes_initializer + nodes_init(r, n - rank_shift[num_threads], num_threads, rank); + size_type split = nodes_init.get_shifted_splitting_point(); #pragma omp parallel num_threads(num_threads) - { -#if USE_PAPI - PAPI_register_thread(); -#endif - int iam = omp_get_thread_num(); - size_type beg = beg_partition[iam]; - // Dealing with repetitions (EFFICIENCY ISSUE). - size_type end = beg_partition[iam+1] - (rank_shift[iam+1] - rank_shift[iam]); - if (split >= end) - { - for (size_type i = beg; i < end; ++i) - { - nodes_init.link_complete(r[i],iam); - } - } - else - { - if (split <= beg) - { - for (size_type i = beg; i < end; ++i) - nodes_init.link_incomplete(r[i],iam); - } - else - { - for (size_type i = beg; i < split; ++i) - nodes_init.link_complete(r[i],iam); - for (size_type i = split; i < end; ++i) - nodes_init.link_incomplete(r[i],iam); - } - } - } - // If the execution reaches this point, there has been no - // exception, and so the structure can be initialized. - - // Join the tree laid on the array of ptrs with the header node. - // Dealing with repetitions (EFFICIENCY ISSUE). - base_type::_M_impl._M_node_count = n - rank_shift[num_threads]; - base_type::_M_impl._M_header._M_left = r[0]; - thread_index_t with_element = num_threads; - while ((beg_partition[with_element] - beg_partition[with_element-1]) == (rank_shift[with_element] - rank_shift[with_element-1])) { - --with_element; +#if USE_PAPI + PAPI_register_thread(); +#endif + int iam = omp_get_thread_num(); + size_type beg = beg_partition[iam]; + // Dealing with repetitions (EFFICIENCY ISSUE). + size_type end = (beg_partition[iam+1] + - (rank_shift[iam+1] - rank_shift[iam])); + if (split >= end) + { + for (size_type i = beg; i < end; ++i) + nodes_init.link_complete(r[i],iam); + } + else + { + if (split <= beg) + { + for (size_type i = beg; i < end; ++i) + nodes_init.link_incomplete(r[i],iam); + } + else + { + for (size_type i = beg; i < split; ++i) + nodes_init.link_complete(r[i],iam); + for (size_type i = split; i < end; ++i) + nodes_init.link_incomplete(r[i],iam); + } + } } - base_type::_M_impl._M_header._M_right = r[beg_partition[with_element] - (rank_shift[with_element] - rank_shift[with_element-1]) - 1]; - base_type::_M_impl._M_header._M_parent = nodes_init.get_root(); - nodes_init.get_root()->_M_parent= &base_type::_M_impl._M_header; + // If the execution reaches this point, there has been no + // exception, and so the structure can be initialized. - ::operator delete(r); - } + // Join the tree laid on the array of ptrs with the header node. + // Dealing with repetitions (EFFICIENCY ISSUE). + base_type::_M_impl._M_node_count = n - rank_shift[num_threads]; + base_type::_M_impl._M_header._M_left = r[0]; + thread_index_t with_element = num_threads; + while ((beg_partition[with_element] + - beg_partition[with_element-1]) + == (rank_shift[with_element] - rank_shift[with_element-1])) + --with_element; + + base_type::_M_impl._M_header._M_right = + r[beg_partition[with_element] + - (rank_shift[with_element] - rank_shift[with_element-1]) - 1]; + base_type::_M_impl._M_header._M_parent = nodes_init.get_root(); + nodes_init.get_root()->_M_parent= &base_type::_M_impl._M_header; + + ::operator delete(r); + } /** @brief Main bulk insertion method: perform the actual @@ -1807,204 +1900,272 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_sorted_bulk_insertion(_Iterator* access, size_type* beg_partition, size_type k, thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - _GLIBCXX_PARALLEL_ASSERT((size_type)num_threads <= k); - // num_thr-1 problems in the upper part of the tree - // num_thr problems to further parallelize - std::vector existing(num_threads,0); -#if _GLIBCXX_TREE_INITIAL_SPLITTING - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - size_type rank_shift[num_threads+1]; - - // Need to create them dynamically because they are so erased - concat_problem* conc[2*num_threads-1]; -#endif - _Rb_tree_node_ptr* r; - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - if (not strictly_less_or_less_equal(base_type::_S_key(base_type::_M_root()),base_type::_S_key(base_type::_M_root()) )) - { - // Unique container - // Set 1 and 2 could be done in parallel ... - // 1. Construct the nodes with their corresponding data -#if _GLIBCXX_TREE_INITIAL_SPLITTING - r = _M_sorted_bulk_allocation_and_initialization(access, beg_partition, rank_shift, k, num_threads, strictly_less_or_less_equal); -#else - r = _M_sorted_no_gapped_bulk_allocation_and_initialization(access, beg_partition, k, num_threads, strictly_less_or_less_equal); -#endif - } - else - { - // Not unique container. - r = _M_unsorted_bulk_allocation_and_initialization(access, beg_partition, k, num_threads); -#if _GLIBCXX_TREE_INITIAL_SPLITTING - // Trivial initialization of rank_shift. - for (int i=0; i <= num_threads; ++i) - rank_shift[i] = 0; -#endif - } -#if _GLIBCXX_TREE_INITIAL_SPLITTING - // Calculate position of last element to be inserted: must be - // done now, or otherwise becomes messy. - - /***** Dealing with - repetitions (EFFICIENCY ISSUE) *****/ - size_type last = beg_partition[num_threads] - (rank_shift[num_threads] - rank_shift[num_threads - 1]); - - //2. Split the tree according to access in num_threads parts - //Initialize upper concat_problems - //Allocate them dynamically because they are afterwards so erased - for (int i=0; i < (2*num_threads-1); ++i) - { - conc[i] = new concat_problem (); - } - concat_problem* root_problem = _M_bulk_insertion_initialize_upper_problems(conc, 0, num_threads, NULL); - - // The first position of access and the last are ignored, so we - // have exactly num_threads subtrees. - bool before = omp_get_nested(); - omp_set_nested(true); - _M_bulk_insertion_split_tree_by_pivot(static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), r, access, beg_partition, rank_shift, 0, num_threads-1, conc, num_threads, strictly_less_or_less_equal); - omp_set_nested(before); - - // Construct upper tree with the first elements of ranges if - // they are NULL We cannot do this by default because they could - // be repeated and would not be checked. - size_type r_s = 0; - for (int pos = 1; pos < num_threads; ++pos) - { - _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or conc[pos*2-1]->t == NULL or strictly_less_or_less_equal(base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)), base_type::_S_key(conc[pos*2-1]->t))); - _GLIBCXX_PARALLEL_ASSERT(conc[pos*2]->t == NULL or conc[pos*2-1]->t == NULL or strictly_less_or_less_equal( base_type::_S_key(conc[pos*2-1]->t), base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t)))); - /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/ - - // The first element of the range is the root. - if (conc[pos*2-1]->t == NULL or (not(strictly_less_or_less_equal(base_type::_S_key(static_cast<_Rb_tree_node_ptr>(conc[pos*2-1]->t)), _KeyOfValue()(*access[pos]))))) - { - // There was not a candidate element - // or - // Exists an initialized position in the array which - // corresponds to conc[pos*2-1]->t */ - if (conc[pos*2-1]->t == NULL) - { - size_t np = beg_partition[pos]; - _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or strictly_less_or_less_equal(base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)), base_type::_S_key(r[np]))); - _GLIBCXX_PARALLEL_ASSERT(conc[pos*2]->t == NULL or strictly_less_or_less_equal( base_type::_S_key(r[np]), base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t)))); - conc[pos*2-1]->t = r[np]; - r[np]->_M_color = std::_S_black; - ++base_type::_M_impl._M_node_count; - } - else - { - base_type::_M_destroy_node(r[beg_partition[pos]]); - } - ++(access[pos]); - ++(beg_partition[pos]); - ++r_s; - } - _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or conc[(pos-1)*2]->t->_M_color == std::_S_black); - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - rank_shift[pos] += r_s; - } - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - rank_shift[num_threads] += r_s; -#else - concat_problem root_problem_on_stack(static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), black_height(static_cast<_Rb_tree_node_ptr>(base_type::_M_root())), NULL); - concat_problem * root_problem = &root_problem_on_stack; - size_type last = k; -#endif - - // 3. Split the range according to tree and create - // 3. insertion/concatenation problems to be solved in parallel -#if _GLIBCXX_TREE_DYNAMIC_BALANCING - size_type min_problem = (k/num_threads) / (log2(k/num_threads + 1)+1); -#else - size_type min_problem = base_type::size() + k; -#endif - - RestrictedBoundedConcurrentQueue* ins_problems[num_threads]; - -#pragma omp parallel num_threads(num_threads) + void + _M_sorted_bulk_insertion(_Iterator* access, size_type* beg_partition, + size_type k, thread_index_t num_threads, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) { - int num_thread = omp_get_thread_num(); - ins_problems[num_thread] = new RestrictedBoundedConcurrentQueue(2*(log2(base_type::size())+1)); + _GLIBCXX_PARALLEL_ASSERT((size_type)num_threads <= k); + // num_thr-1 problems in the upper part of the tree + // num_thr problems to further parallelize + std::vector existing(num_threads,0); #if _GLIBCXX_TREE_INITIAL_SPLITTING /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - size_type end_k_thread = beg_partition[num_thread+1] - (rank_shift[num_thread+1] - rank_shift[num_thread]); - ins_problems[num_thread]->push_front(insertion_problem(beg_partition[num_thread], end_k_thread, num_thread, conc[num_thread*2])); -#else - // size_type end_k_thread = beg_partition[num_thread+1]; + size_type rank_shift[num_threads+1]; + + // Need to create them dynamically because they are so erased + concat_problem* conc[2*num_threads-1]; #endif - insertion_problem ip_to_solve; - bool change; + _Rb_tree_node_ptr* r; + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + if (not strictly_less_or_less_equal + (base_type::_S_key(base_type::_M_root()), + base_type::_S_key(base_type::_M_root()) )) + { + // Unique container + // Set 1 and 2 could be done in parallel ... + // 1. Construct the nodes with their corresponding data +#if _GLIBCXX_TREE_INITIAL_SPLITTING + r = _M_sorted_bulk_allocation_and_initialization + (access, beg_partition, rank_shift, k, num_threads, + strictly_less_or_less_equal); +#else + r = _M_sorted_no_gapped_bulk_allocation_and_initialization + (access, beg_partition, k, num_threads, + strictly_less_or_less_equal); +#endif + } + else + { + // Not unique container. + r = _M_unsorted_bulk_allocation_and_initialization + (access, beg_partition, k, num_threads); +#if _GLIBCXX_TREE_INITIAL_SPLITTING + // Trivial initialization of rank_shift. + for (int i=0; i <= num_threads; ++i) + rank_shift[i] = 0; +#endif + } +#if _GLIBCXX_TREE_INITIAL_SPLITTING + // Calculate position of last element to be inserted: must be + // done now, or otherwise becomes messy. + + /***** Dealing with + repetitions (EFFICIENCY ISSUE) *****/ + size_type last = (beg_partition[num_threads] + - (rank_shift[num_threads] + - rank_shift[num_threads - 1])); + + //2. Split the tree according to access in num_threads parts + //Initialize upper concat_problems + //Allocate them dynamically because they are afterwards so erased + for (int i=0; i < (2*num_threads-1); ++i) + conc[i] = new concat_problem (); + concat_problem* root_problem = + _M_bulk_insertion_initialize_upper_problems(conc, 0, + num_threads, NULL); + + // The first position of access and the last are ignored, so we + // have exactly num_threads subtrees. + bool before = omp_get_nested(); + omp_set_nested(true); + + _M_bulk_insertion_split_tree_by_pivot( + static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), r, + access, beg_partition, rank_shift, 0, num_threads - 1, conc, + num_threads, strictly_less_or_less_equal); + + omp_set_nested(before); + + // Construct upper tree with the first elements of ranges if + // they are NULL We cannot do this by default because they could + // be repeated and would not be checked. + size_type r_s = 0; + for (int pos = 1; pos < num_threads; ++pos) + { + _GLIBCXX_PARALLEL_ASSERT( + conc[(pos-1)*2]->t == NULL or conc[pos*2-1]->t == NULL + or strictly_less_or_less_equal + (base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)), + base_type::_S_key(conc[pos*2-1]->t))); + _GLIBCXX_PARALLEL_ASSERT( + conc[pos*2]->t == NULL or conc[pos*2-1]->t == NULL + or strictly_less_or_less_equal( + base_type::_S_key(conc[pos*2-1]->t), + base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t)))); + /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/ + + // The first element of the range is the root. + if (conc[pos*2-1]->t == NULL + or (not(strictly_less_or_less_equal( + base_type::_S_key(static_cast<_Rb_tree_node_ptr> + (conc[pos*2-1]->t)), + _KeyOfValue()(*access[pos]))))) + { + // There was not a candidate element + // or + // Exists an initialized position in the array which + // corresponds to conc[pos*2-1]->t */ + if (conc[pos*2-1]->t == NULL) + { + size_t np = beg_partition[pos]; + _GLIBCXX_PARALLEL_ASSERT( + conc[(pos-1)*2]->t == NULL + or strictly_less_or_less_equal + (base_type::_S_key(base_type:: + _S_maximum(conc[(pos-1)*2]->t)), + base_type::_S_key(r[np]))); + _GLIBCXX_PARALLEL_ASSERT( + conc[pos*2]->t == NULL + or strictly_less_or_less_equal( + base_type::_S_key(r[np]), + base_type::_S_key(base_type:: + _S_minimum(conc[pos*2]->t)))); + conc[pos*2-1]->t = r[np]; + r[np]->_M_color = std::_S_black; + ++base_type::_M_impl._M_node_count; + } + else + base_type::_M_destroy_node(r[beg_partition[pos]]); + ++(access[pos]); + ++(beg_partition[pos]); + ++r_s; + } + _GLIBCXX_PARALLEL_ASSERT( + conc[(pos-1)*2]->t == NULL + or conc[(pos-1)*2]->t->_M_color == std::_S_black); + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + rank_shift[pos] += r_s; + } + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + rank_shift[num_threads] += r_s; +#else + concat_problem root_problem_on_stack( + static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), + black_height(static_cast<_Rb_tree_node_ptr>(base_type::_M_root())), + NULL); + concat_problem * root_problem = &root_problem_on_stack; + size_type last = k; +#endif + + // 3. Split the range according to tree and create + // 3. insertion/concatenation problems to be solved in parallel +#if _GLIBCXX_TREE_DYNAMIC_BALANCING + size_type min_problem = (k/num_threads) / (log2(k/num_threads + 1)+1); +#else + size_type min_problem = base_type::size() + k; +#endif + + RestrictedBoundedConcurrentQueue* + ins_problems[num_threads]; + +#pragma omp parallel num_threads(num_threads) + { + int num_thread = omp_get_thread_num(); + ins_problems[num_thread] = + new RestrictedBoundedConcurrentQueue + (2 * (log2(base_type::size()) + 1)); +#if _GLIBCXX_TREE_INITIAL_SPLITTING + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + size_type end_k_thread = (beg_partition[num_thread+1] + - (rank_shift[num_thread+1] + - rank_shift[num_thread])); + ins_problems[num_thread]->push_front( + insertion_problem(beg_partition[num_thread], end_k_thread, + num_thread, conc[num_thread*2])); +#else + // size_type end_k_thread = beg_partition[num_thread+1]; +#endif + insertion_problem ip_to_solve; + bool change; #if _GLIBCXX_TREE_INITIAL_SPLITTING #pragma omp barrier #else #pragma omp single - ins_problems[num_thread]->push_front(insertion_problem(0, k, num_thread, root_problem)); + ins_problems[num_thread]->push_front(insertion_problem( + 0, k, num_thread, + root_problem)); #endif - do - { - // First do own work. - while (ins_problems[num_thread]->pop_front(ip_to_solve)) - { - _GLIBCXX_PARALLEL_ASSERT(ip_to_solve.pos_beg <= ip_to_solve.pos_end); - _M_bulk_insertion_split_sequence(r, ins_problems[num_thread], ip_to_solve, existing[num_thread], min_problem, strictly_less_or_less_equal); + do + { + // First do own work. + while (ins_problems[num_thread]->pop_front(ip_to_solve)) + { + _GLIBCXX_PARALLEL_ASSERT(ip_to_solve.pos_beg + <= ip_to_solve.pos_end); + _M_bulk_insertion_split_sequence( + r, ins_problems[num_thread], ip_to_solve, + existing[num_thread], min_problem, + strictly_less_or_less_equal); - } - yield(); - change = false; + } + yield(); + change = false; - //Then, try to steal from others (and become own). - for (int i=1; ipop_back(ip_to_solve)) - { - change = true; - _M_bulk_insertion_split_sequence(r, ins_problems[num_thread], ip_to_solve, existing[num_thread], min_problem, strictly_less_or_less_equal); - break; - } - } - } while (change); - } - - // Update root and sizes. - base_type::_M_root() = root_problem->t; - root_problem->t->_M_parent = &(base_type::_M_impl._M_header); - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - - // Add the k elements that wanted to be inserted, minus the ones - // that were repeated. -#if _GLIBCXX_TREE_INITIAL_SPLITTING - base_type::_M_impl._M_node_count += (k - (rank_shift[num_threads])); -#else - base_type::_M_impl._M_node_count += k; -#endif - // Also then, take out the ones that were already existing in the tree. - for (int i = 0; i< num_threads; ++i) - { - base_type::_M_impl._M_node_count -= existing[i]; + //Then, try to steal from others (and become own). + for (int i=1; ipop_back(ip_to_solve)) + { + change = true; + _M_bulk_insertion_split_sequence( + r, ins_problems[num_thread], ip_to_solve, + existing[num_thread], min_problem, + strictly_less_or_less_equal); + break; + } + } + } while (change); } - // Update leftmost and rightmost. - /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ - if (not strictly_less_or_less_equal(base_type::_S_key(base_type::_M_root()), base_type::_S_key(base_type::_M_root()))){ - // Unique container. - if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*(access[0])), base_type::_S_key(base_type::_M_leftmost()))) - base_type::_M_leftmost() = r[0]; - if (base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_M_rightmost()), _KeyOfValue()(*(--access[num_threads])))) - base_type::_M_rightmost() = r[last - 1]; - } - else{ - if (strictly_less_or_less_equal(_KeyOfValue()(*(access[0])), base_type::_S_key(base_type::_M_leftmost()))) - base_type::_M_leftmost() = base_type::_S_minimum(base_type::_M_root()); - if (strictly_less_or_less_equal(base_type::_S_key(base_type::_M_rightmost()), _KeyOfValue()(*(--access[num_threads])))) - base_type::_M_rightmost() = base_type::_S_maximum(base_type::_M_root()); - } - - + // Update root and sizes. + base_type::_M_root() = root_problem->t; + root_problem->t->_M_parent = &(base_type::_M_impl._M_header); + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + + // Add the k elements that wanted to be inserted, minus the ones + // that were repeated. +#if _GLIBCXX_TREE_INITIAL_SPLITTING + base_type::_M_impl._M_node_count += (k - (rank_shift[num_threads])); +#else + base_type::_M_impl._M_node_count += k; +#endif + // Also then, take out the ones that were already existing in the tree. + for (int i = 0; i< num_threads; ++i) + base_type::_M_impl._M_node_count -= existing[i]; + // Update leftmost and rightmost. + /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/ + if (not strictly_less_or_less_equal( + base_type::_S_key(base_type::_M_root()), + base_type::_S_key(base_type::_M_root()))) + { + // Unique container. + if (base_type::_M_impl._M_key_compare( + _KeyOfValue()(*(access[0])), + base_type::_S_key(base_type::_M_leftmost()))) + base_type::_M_leftmost() = r[0]; + if (base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_M_rightmost()), + _KeyOfValue()(*(--access[num_threads])))) + base_type::_M_rightmost() = r[last - 1]; + } + else + { + if (strictly_less_or_less_equal(_KeyOfValue()(*(access[0])), + base_type::_S_key(base_type:: + _M_leftmost()))) + base_type::_M_leftmost() = + base_type::_S_minimum(base_type::_M_root()); + if (strictly_less_or_less_equal( + base_type::_S_key(base_type::_M_rightmost()), + _KeyOfValue()(*(--access[num_threads])))) + base_type::_M_rightmost() = + base_type::_S_maximum(base_type::_M_root()); + } #if _GLIBCXX_TREE_INITIAL_SPLITTING // Delete root problem @@ -2013,9 +2174,7 @@ namespace __gnu_parallel // Delete queues for (int pos = 0; pos < num_threads; ++pos) - { - delete ins_problems[pos]; - } + delete ins_problems[pos]; // Delete array of pointers ::operator delete(r); @@ -2056,101 +2215,136 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_bulk_insertion_split_tree_by_pivot(_Rb_tree_node_ptr t, _Rb_tree_node_ptr* r, _Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type pos_beg, const size_type pos_end, concat_problem** conc, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - if (pos_beg == pos_end) - { - //Elements are in [pos_beg, pos_end] - conc[pos_beg*2]->t = t; - conc[pos_beg*2]->black_h = black_height(t); - force_black_root (conc[pos_beg*2]->t, conc[pos_beg*2]->black_h); - return; - } - if (t == 0) - { - for (size_type i = pos_beg; i < pos_end; ++i) - { - conc[i*2]->t = NULL; - conc[i*2]->black_h = 0; - conc[i*2+1]->t = NULL; - } - conc[pos_end*2]->t = NULL; - conc[pos_end*2]->black_h = 0; - return; - } + void + _M_bulk_insertion_split_tree_by_pivot(_Rb_tree_node_ptr t, + _Rb_tree_node_ptr* r, + _Iterator* access, + size_type* beg_partition, + size_type* rank_shift, + const size_type pos_beg, + const size_type pos_end, + concat_problem** conc, + const thread_index_t num_threads, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + if (pos_beg == pos_end) + { + //Elements are in [pos_beg, pos_end] + conc[pos_beg*2]->t = t; + conc[pos_beg*2]->black_h = black_height(t); + force_black_root (conc[pos_beg*2]->t, conc[pos_beg*2]->black_h); + return; + } + if (t == 0) + { + for (size_type i = pos_beg; i < pos_end; ++i) + { + conc[i*2]->t = NULL; + conc[i*2]->black_h = 0; + conc[i*2+1]->t = NULL; + } + conc[pos_end*2]->t = NULL; + conc[pos_end*2]->black_h = 0; + return; + } - // Return the last pos, in which key >= (pos-1). - // Search in the range [pos_beg, pos_end] - size_type pos = std::upper_bound(access + pos_beg, access + pos_end + 1, base_type::_S_key(t), compare_value_key<_Iterator, _Compare>(base_type::_M_impl._M_key_compare)) - access; - if (pos != pos_beg) - { + // Return the last pos, in which key >= (pos-1). + // Search in the range [pos_beg, pos_end] + size_type pos = (std::upper_bound(access + pos_beg, + access + pos_end + 1, + base_type::_S_key(t), + compare_value_key<_Iterator, + _Compare>(base_type:: + _M_impl._M_key_compare)) + - access); + if (pos != pos_beg) --pos; - } - _GLIBCXX_PARALLEL_ASSERT(pos == 0 or not base_type::_M_impl._M_key_compare(base_type::_S_key(t), _KeyOfValue()(*access[pos]))); + _GLIBCXX_PARALLEL_ASSERT( + pos == 0 + or not base_type::_M_impl._M_key_compare( + base_type::_S_key(t), _KeyOfValue()(*access[pos]))); - _Rb_tree_node_ptr ll, lr; - int black_h_ll, black_h_lr; - _Rb_tree_node_ptr rl, rr; - int black_h_rl, black_h_rr; + + _Rb_tree_node_ptr ll, lr; + int black_h_ll, black_h_lr; + _Rb_tree_node_ptr rl, rr; + int black_h_rl, black_h_rr; - if (pos != pos_beg) - { - _Rb_tree_node_ptr prev = r[beg_partition[pos] - 1 - (rank_shift[pos] - rank_shift[pos - 1])]; + if (pos != pos_beg) + { + _Rb_tree_node_ptr prev = (r[beg_partition[pos] - 1 + - (rank_shift[pos] + - rank_shift[pos - 1])]); - _GLIBCXX_PARALLEL_ASSERT(strictly_less_or_less_equal(base_type::_S_key(prev), _KeyOfValue()(*access[pos]))); + _GLIBCXX_PARALLEL_ASSERT( + strictly_less_or_less_equal(base_type::_S_key(prev), + _KeyOfValue()(*access[pos]))); - split(static_cast<_Rb_tree_node_ptr>(t->_M_left), - static_cast(_KeyOfValue()(*access[pos])), - static_cast(base_type::_S_key(prev)), - conc[pos*2-1]->t, ll, lr, black_h_ll, black_h_lr, - strictly_less_or_less_equal); + split(static_cast<_Rb_tree_node_ptr>(t->_M_left), + static_cast(_KeyOfValue()(*access[pos])), + static_cast(base_type::_S_key(prev)), + conc[pos*2-1]->t, ll, lr, black_h_ll, black_h_lr, + strictly_less_or_less_equal); - _M_bulk_insertion_split_tree_by_pivot(ll, r, access, beg_partition, rank_shift, pos_beg, pos-1, conc,num_threads, strictly_less_or_less_equal); - } - else - { - lr = static_cast<_Rb_tree_node_ptr>(t->_M_left); - black_h_lr = black_height (lr); - force_black_root (lr, black_h_lr); - } + _M_bulk_insertion_split_tree_by_pivot( + ll, r, access, beg_partition, rank_shift, pos_beg, pos-1, + conc, num_threads, strictly_less_or_less_equal); + } + else + { + lr = static_cast<_Rb_tree_node_ptr>(t->_M_left); + black_h_lr = black_height (lr); + force_black_root (lr, black_h_lr); + } - if (pos != pos_end) - { - _Rb_tree_node_ptr prev = r[beg_partition[pos+1] - 1 - (rank_shift[pos+1] - rank_shift[pos])]; + if (pos != pos_end) + { + _Rb_tree_node_ptr prev = (r[beg_partition[pos+1] - 1 + - (rank_shift[pos+1] + - rank_shift[pos])]); - _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*access[pos+1]), base_type::_S_key(prev))); - _GLIBCXX_PARALLEL_ASSERT(strictly_less_or_less_equal(base_type::_S_key(prev), _KeyOfValue()(*access[pos+1]))); + _GLIBCXX_PARALLEL_ASSERT( + not base_type::_M_impl._M_key_compare( + _KeyOfValue()(*access[pos+1]), base_type::_S_key(prev))); + _GLIBCXX_PARALLEL_ASSERT( + strictly_less_or_less_equal(base_type::_S_key(prev), + _KeyOfValue()(*access[pos+1]))); - split(static_cast<_Rb_tree_node_ptr>(t->_M_right), - static_cast(_KeyOfValue()(*access[pos+1])), - static_cast(base_type::_S_key(prev)), - conc[pos*2+1]->t, rl, rr, black_h_rl, black_h_rr, - strictly_less_or_less_equal); + split(static_cast<_Rb_tree_node_ptr>(t->_M_right), + static_cast(_KeyOfValue()(*access[pos+1])), + static_cast(base_type::_S_key(prev)), + conc[pos*2+1]->t, rl, rr, black_h_rl, black_h_rr, + strictly_less_or_less_equal); - _M_bulk_insertion_split_tree_by_pivot(rr, r, access, beg_partition, rank_shift, pos+1, pos_end, conc,num_threads, strictly_less_or_less_equal); - } - else - { - rl = static_cast<_Rb_tree_node_ptr>(t->_M_right); - black_h_rl = black_height (rl); - force_black_root (rl, black_h_rl); - } + _M_bulk_insertion_split_tree_by_pivot( + rr, r, access, beg_partition, rank_shift, pos+1, pos_end, + conc,num_threads, strictly_less_or_less_equal); + } + else + { + rl = static_cast<_Rb_tree_node_ptr>(t->_M_right); + black_h_rl = black_height (rl); + force_black_root (rl, black_h_rl); + } - // When key(t) is equal to key(access[pos]) and no other key in - // the left tree satisfies the criteria to be conc[pos*2-1]->t, - // key(t) must be assigned to it to avoid repetitions. - // Therefore, we do not have a root parameter for the - // concatenate function and a new concatenate function must be - // provided. - if (pos != pos_beg and conc[pos*2-1]->t == NULL and not strictly_less_or_less_equal(_KeyOfValue()(*access[pos]), base_type::_S_key(t))) - { - conc[pos*2-1]->t = t; - t = NULL; - } - concatenate(t, lr, rl, black_h_lr, black_h_rl, conc[pos*2]->t, conc[pos*2]->black_h); - } + // When key(t) is equal to key(access[pos]) and no other key in + // the left tree satisfies the criteria to be conc[pos*2-1]->t, + // key(t) must be assigned to it to avoid repetitions. + // Therefore, we do not have a root parameter for the + // concatenate function and a new concatenate function must be + // provided. + if (pos != pos_beg and conc[pos*2-1]->t == NULL + and not strictly_less_or_less_equal(_KeyOfValue()(*access[pos]), + base_type::_S_key(t))) + { + conc[pos*2-1]->t = t; + t = NULL; + } + concatenate(t, lr, rl, black_h_lr, black_h_rl, + conc[pos*2]->t, conc[pos*2]->black_h); + } /** @brief Divide the insertion problem until a leaf is reached or * the problem is small. @@ -2174,41 +2368,52 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_bulk_insertion_split_sequence(_Rb_tree_node_ptr* r, RestrictedBoundedConcurrentQueue* ins_problems, insertion_problem& ip, size_type& existing, const size_type min_problem, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - _GLIBCXX_PARALLEL_ASSERT(ip.t == ip.conc->t); - if (ip.t == NULL or (ip.pos_end- ip.pos_beg) <= min_problem) - { - // SOLVE PROBLEM SEQUENTIALLY - // Start solving the problem. - _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end); - _M_bulk_insertion_merge_concatenate(r, ip, existing, strictly_less_or_less_equal); - return; - } + void + _M_bulk_insertion_split_sequence( + _Rb_tree_node_ptr* r, + RestrictedBoundedConcurrentQueue* ins_problems, + insertion_problem& ip, size_type& existing, + const size_type min_problem, + StrictlyLessOrLessEqual strictly_less_or_less_equal) + { + _GLIBCXX_PARALLEL_ASSERT(ip.t == ip.conc->t); + if (ip.t == NULL or (ip.pos_end- ip.pos_beg) <= min_problem) + { + // SOLVE PROBLEM SEQUENTIALLY + // Start solving the problem. + _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end); + _M_bulk_insertion_merge_concatenate(r, ip, existing, + strictly_less_or_less_equal); + return; + } - size_type pos_beg_right; - size_type pos_end_left = divide(r, ip.pos_beg, ip.pos_end, base_type::_S_key(ip.t), pos_beg_right, existing, strictly_less_or_less_equal); + size_type pos_beg_right; + size_type pos_end_left = divide(r, ip.pos_beg, ip.pos_end, + base_type::_S_key(ip.t), pos_beg_right, + existing, strictly_less_or_less_equal); - int black_h_l, black_h_r; - if (ip.t->_M_color == std::_S_black) - { + int black_h_l, black_h_r; + if (ip.t->_M_color == std::_S_black) black_h_l = black_h_r = ip.conc->black_h - 1; - } - else - { + else black_h_l = black_h_r = ip.conc->black_h; - } // Right problem into the queue. - ip.conc->right_problem = new concat_problem(static_cast<_Rb_tree_node_ptr>(ip.t->_M_right), black_h_r, ip.conc); - ip.conc->left_problem = new concat_problem(static_cast<_Rb_tree_node_ptr>(ip.t->_M_left), black_h_l, ip.conc); + ip.conc->right_problem = new concat_problem( + static_cast<_Rb_tree_node_ptr>(ip.t->_M_right), black_h_r, ip.conc); + ip.conc->left_problem = new concat_problem( + static_cast<_Rb_tree_node_ptr>(ip.t->_M_left), black_h_l, ip.conc); - ins_problems->push_front(insertion_problem(pos_beg_right, ip.pos_end, ip.array_partition, ip.conc->right_problem)); + ins_problems->push_front(insertion_problem(pos_beg_right, ip.pos_end, + ip.array_partition, + ip.conc->right_problem)); // Solve left problem. - insertion_problem ip_left(ip.pos_beg, pos_end_left, ip.array_partition, ip.conc->left_problem); - _M_bulk_insertion_split_sequence(r, ins_problems, ip_left, existing, min_problem, strictly_less_or_less_equal); + insertion_problem ip_left(ip.pos_beg, pos_end_left, ip.array_partition, + ip.conc->left_problem); + _M_bulk_insertion_split_sequence(r, ins_problems, ip_left, existing, + min_problem, + strictly_less_or_less_equal); } @@ -2237,60 +2442,70 @@ namespace __gnu_parallel * @return Resulting tree after the elements have been inserted */ template - _Rb_tree_node_ptr - _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t, const size_type pos_beg, const size_type pos_end, size_type& existing, int& black_h, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { + _Rb_tree_node_ptr + _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t, + const size_type pos_beg, + const size_type pos_end, + size_type& existing, int& black_h, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { #ifndef NDEBUG - int count; + int count; #endif - _GLIBCXX_PARALLEL_ASSERT(pos_beg<=pos_end); + _GLIBCXX_PARALLEL_ASSERT(pos_beg<=pos_end); - // Leaf: a tree with the range must be constructed. Returns its - // height in black nodes and its root (in ip.t) If there is - // nothing to insert, we still need the height for balancing. - if (t == NULL) - { - if (pos_end == pos_beg) return NULL; - t = simple_tree_construct(r_array,pos_beg, pos_end, black_h); - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count)); + // Leaf: a tree with the range must be constructed. Returns its + // height in black nodes and its root (in ip.t) If there is + // nothing to insert, we still need the height for balancing. + if (t == NULL) + { + if (pos_end == pos_beg) + return NULL; + t = simple_tree_construct(r_array,pos_beg, pos_end, black_h); + _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count)); + return t; + } + if (pos_end == pos_beg) return t; - } - if (pos_end == pos_beg) - return t; - if ((pos_end - pos_beg) <= (size_type)(black_h)) - { - // Exponential size tree with respect the number of elements - // to be inserted. - for (size_type p = pos_beg; p < pos_end; ++p) - { - t = _M_insert_local(t, r_array[p], existing, black_h, strictly_less_or_less_equal); - } - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count)); - return t; - } + if ((pos_end - pos_beg) <= (size_type)(black_h)) + { + // Exponential size tree with respect the number of elements + // to be inserted. + for (size_type p = pos_beg; p < pos_end; ++p) + t = _M_insert_local(t, r_array[p], existing, black_h, + strictly_less_or_less_equal); + _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count)); + return t; + } - size_type pos_beg_right; - size_type pos_end_left = divide(r_array, pos_beg, pos_end, base_type::_S_key(t), pos_beg_right, existing, strictly_less_or_less_equal); + size_type pos_beg_right; + size_type pos_end_left = divide(r_array, pos_beg, pos_end, + base_type::_S_key(t), pos_beg_right, + existing, strictly_less_or_less_equal); - - int black_h_l, black_h_r; - if (t->_M_color == std::_S_black) - { + int black_h_l, black_h_r; + if (t->_M_color == std::_S_black) black_h_l = black_h_r = black_h - 1; - } - else - { + else black_h_l = black_h_r = black_h; - } - force_black_root(t->_M_left, black_h_l); - _Rb_tree_node_ptr l = _M_bulk_insertion_merge(r_array, static_cast<_Rb_tree_node_ptr>(t->_M_left), pos_beg, pos_end_left, existing, black_h_l, strictly_less_or_less_equal); - force_black_root(t->_M_right, black_h_r); - _Rb_tree_node_ptr r = _M_bulk_insertion_merge(r_array, static_cast<_Rb_tree_node_ptr>(t->_M_right), pos_beg_right, pos_end, existing, black_h_r, strictly_less_or_less_equal); + + force_black_root(t->_M_left, black_h_l); - concatenate(t, l, r, black_h_l, black_h_r, t, black_h); + _Rb_tree_node_ptr l = _M_bulk_insertion_merge( + r_array, static_cast<_Rb_tree_node_ptr>(t->_M_left), pos_beg, + pos_end_left, existing, black_h_l, strictly_less_or_less_equal); - return t; - } + force_black_root(t->_M_right, black_h_r); + + _Rb_tree_node_ptr r = _M_bulk_insertion_merge( + r_array, static_cast<_Rb_tree_node_ptr>(t->_M_right), pos_beg_right, + pos_end, existing, black_h_r, strictly_less_or_less_equal); + + concatenate(t, l, r, black_h_l, black_h_r, t, black_h); + + return t; + } /** @brief Solve a given insertion problem and all the parent * concatenation problem that are ready to be solved. @@ -2311,35 +2526,50 @@ namespace __gnu_parallel * of the wrapping container */ template - void - _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r, insertion_problem& ip, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - concat_problem* conc = ip.conc; - _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end); + void + _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r, + insertion_problem& ip, + size_type& existing, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) + { + concat_problem* conc = ip.conc; + _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end); - conc->t = _M_bulk_insertion_merge(r, ip.t, ip.pos_beg, ip.pos_end, existing, conc->black_h, strictly_less_or_less_equal); - _GLIBCXX_PARALLEL_ASSERT(conc->t == NULL or conc->t->_M_color == std::_S_black); + conc->t = _M_bulk_insertion_merge(r, ip.t, ip.pos_beg, ip.pos_end, + existing, conc->black_h, + strictly_less_or_less_equal); + _GLIBCXX_PARALLEL_ASSERT(conc->t == NULL + or conc->t->_M_color == std::_S_black); - bool is_ready = true; - while (conc->par_problem != NULL and is_ready) - { - // Pre: exists left and right problem, so there is not a deadlock - if (compare_and_swap(&conc->par_problem->is_ready, concat_problem::READY_NO, concat_problem::READY_YES)) - is_ready = false; + bool is_ready = true; + while (conc->par_problem != NULL and is_ready) + { + // Pre: exists left and right problem, so there is not a deadlock + if (compare_and_swap(&conc->par_problem->is_ready, + concat_problem::READY_NO, + concat_problem::READY_YES)) + is_ready = false; - if (is_ready) - { - conc = conc->par_problem; - _GLIBCXX_PARALLEL_ASSERT(conc->left_problem!=NULL and conc->right_problem!=NULL); - _GLIBCXX_PARALLEL_ASSERT (conc->left_problem->black_h >=0 and conc->right_problem->black_h>=0); - // Finished working with the problems. - concatenate(conc->t, conc->left_problem->t, conc->right_problem->t, conc->left_problem->black_h, conc->right_problem->black_h, conc->t, conc->black_h); + if (is_ready) + { + conc = conc->par_problem; + _GLIBCXX_PARALLEL_ASSERT(conc->left_problem!=NULL + and conc->right_problem!=NULL); + _GLIBCXX_PARALLEL_ASSERT(conc->left_problem->black_h >=0 + and conc->right_problem->black_h>=0); + // Finished working with the problems. + concatenate(conc->t, conc->left_problem->t, + conc->right_problem->t, + conc->left_problem->black_h, + conc->right_problem->black_h, + conc->t, conc->black_h); - delete conc->left_problem; - delete conc->right_problem; - } - } - } + delete conc->left_problem; + delete conc->right_problem; + } + } + } // Begin of sorting, searching and related comparison-based helper methods. @@ -2351,15 +2581,19 @@ namespace __gnu_parallel * @param dist Size of the sequence (out) * @return sequence is sorted. */ template - bool - is_sorted_distance(const _RandomAccessIterator __first, const _RandomAccessIterator __last, size_type& dist, std::random_access_iterator_tag) const - { - gr_or_eq<_Compare, _RandomAccessIterator> geq(base_type::_M_impl._M_key_compare); - dist = __last - __first; + bool + is_sorted_distance(const _RandomAccessIterator __first, + const _RandomAccessIterator __last, + size_type& dist, + std::random_access_iterator_tag) const + { + gr_or_eq<_Compare, _RandomAccessIterator> + geq(base_type::_M_impl._M_key_compare); + dist = __last - __first; - // In parallel. - return equal(__first + 1, __last, __first, geq); - } + // In parallel. + return equal(__first + 1, __last, __first, geq); + } /** @brief Check whether an input sequence is sorted, and * calculate its size. @@ -2371,32 +2605,35 @@ namespace __gnu_parallel * @param dist Size of the sequence (out) * @return sequence is sorted. */ template - bool - is_sorted_distance(const _InputIterator __first, const _InputIterator __last, size_type& dist, std::input_iterator_tag) const - { - dist = 1; - bool is_sorted = true; - _InputIterator it = __first; - _InputIterator prev = it++; - while (it != __last) - { - ++dist; - if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev))) - { - is_sorted = false; - ++it; - break; - } - prev = it; - ++it; - } - while (it != __last) - { - ++dist; - ++it; - } - return is_sorted; - } + bool + is_sorted_distance(const _InputIterator __first, + const _InputIterator __last, size_type& dist, + std::input_iterator_tag) const + { + dist = 1; + bool is_sorted = true; + _InputIterator it = __first; + _InputIterator prev = it++; + while (it != __last) + { + ++dist; + if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*it), + _KeyOfValue()(*prev))) + { + is_sorted = false; + ++it; + break; + } + prev = it; + ++it; + } + while (it != __last) + { + ++dist; + ++it; + } + return is_sorted; + } /** @brief Check whether a random-access sequence is sorted, * calculate its size, and obtain intermediate accessors to the @@ -2416,17 +2653,24 @@ namespace __gnu_parallel * @param num_pieces Number of pieces to generate. * @return Sequence is sorted. */ template - bool - is_sorted_distance_accessors(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _RandomAccessIterator* access, size_type* beg_partition, size_type& dist, thread_index_t& num_pieces, std::random_access_iterator_tag) const - { - bool is_sorted = is_sorted_distance(__first, __last, dist,std::__iterator_category(__first)); - if (dist < (unsigned int) num_pieces) - num_pieces = dist; + bool + is_sorted_distance_accessors(const _RandomAccessIterator __first, + const _RandomAccessIterator __last, + _RandomAccessIterator* access, + size_type* beg_partition, size_type& dist, + thread_index_t& num_pieces, + std::random_access_iterator_tag) const + { + bool is_sorted = is_sorted_distance(__first, __last, dist, + std::__iterator_category(__first)); + if (dist < (unsigned int) num_pieces) + num_pieces = dist; - // Do it opposite way to use accessors in equal function??? - range_accessors(__first,__last, access, beg_partition, dist, num_pieces, std::__iterator_category(__first)); - return is_sorted; - } + // Do it opposite way to use accessors in equal function??? + range_accessors(__first,__last, access, beg_partition, dist, + num_pieces, std::__iterator_category(__first)); + return is_sorted; + } /** @brief Check whether an input sequence is sorted, calculate * its size, and obtain intermediate accessors to the sequence to @@ -2448,23 +2692,28 @@ namespace __gnu_parallel * @param num_pieces Number of pieces to generate. * @return Sequence is sorted. */ template - bool - is_sorted_distance_accessors(const _InputIterator __first, const _InputIterator __last, _InputIterator* access, size_type* beg_partition, size_type& dist, thread_index_t& num_pieces, std::input_iterator_tag) const - { - is_sorted_functor<_InputIterator, _Compare> sorted(__first, base_type::_M_impl._M_key_compare); - dist = list_partition(__first, __last, access, (beg_partition+1), num_pieces, sorted, 0); + bool + is_sorted_distance_accessors(const _InputIterator __first, + const _InputIterator __last, + _InputIterator* access, + size_type* beg_partition, size_type& dist, + thread_index_t& num_pieces, + std::input_iterator_tag) const + { + is_sorted_functor<_InputIterator, _Compare> + sorted(__first, base_type::_M_impl._M_key_compare); + dist = list_partition(__first, __last, access, (beg_partition+1), + num_pieces, sorted, 0); - // Calculate the rank of the beginning each partition from the - // sequence sizes (what is stored at this point in beg_partition - // array). - beg_partition[0] = 0; - for (int i = 0; i < num_pieces; ++i) - { + // Calculate the rank of the beginning each partition from the + // sequence sizes (what is stored at this point in beg_partition + // array). + beg_partition[0] = 0; + for (int i = 0; i < num_pieces; ++i) beg_partition[i+1] += beg_partition[i]; - } - return sorted.is_sorted(); - } + return sorted.is_sorted(); + } /** @brief Make a full copy of the elements of a sequence * @@ -2481,15 +2730,19 @@ namespace __gnu_parallel * @param out Begin iterator of output sequence. * @param num_threads Number of threads to use. */ template - static void - uninitialized_copy_from_accessors(_InputIterator* access, size_type* beg_partition, _OutputIterator out, const thread_index_t num_threads) - { -#pragma omp parallel num_threads(num_threads) + static void + uninitialized_copy_from_accessors(_InputIterator* access, + size_type* beg_partition, + _OutputIterator out, + const thread_index_t num_threads) { - int iam = omp_get_thread_num(); - uninitialized_copy(access[iam], access[iam+1], out+beg_partition[iam]); +#pragma omp parallel num_threads(num_threads) + { + int iam = omp_get_thread_num(); + uninitialized_copy(access[iam], access[iam + 1], + out + beg_partition[iam]); + } } - } /** @brief Make a copy of the pointers of the elements of a sequence * @param access Array of size @c num_threads + 1 that defines @c @@ -2502,20 +2755,23 @@ namespace __gnu_parallel * @param out Begin iterator of output sequence. * @param num_threads Number of threads to use. */ template - static void - uninitialized_ptr_copy_from_accessors(_InputIterator* access, size_type* beg_partition, _OutputIterator out, const thread_index_t num_threads) - { -#pragma omp parallel num_threads(num_threads) + static void + uninitialized_ptr_copy_from_accessors(_InputIterator* access, + size_type* beg_partition, + _OutputIterator out, + const thread_index_t num_threads) { - int iam = omp_get_thread_num(); - _OutputIterator itout = out + beg_partition[iam]; - for (_InputIterator it = access[iam]; it != access[iam+1]; ++it) - { - *itout = &(*it); - ++itout; - } +#pragma omp parallel num_threads(num_threads) + { + int iam = omp_get_thread_num(); + _OutputIterator itout = out + beg_partition[iam]; + for (_InputIterator it = access[iam]; it != access[iam+1]; ++it) + { + *itout = &(*it); + ++itout; + } + } } - } /** @brief Split a sorted node array in two parts according to a key. * @@ -2540,28 +2796,44 @@ namespace __gnu_parallel * resulting left partition (out) */ template - size_type - divide(_Rb_tree_node_ptr* r, const size_type pos_beg, const size_type pos_end, const key_type& key, size_type& pos_beg_right, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - pos_beg_right = std::lower_bound(r + pos_beg, r + pos_end, key, compare_node_key<_Compare>(base_type::_M_impl._M_key_compare)) - r; + size_type + divide(_Rb_tree_node_ptr* r, const size_type pos_beg, + const size_type pos_end, const key_type& key, + size_type& pos_beg_right, size_type& existing, + StrictlyLessOrLessEqual strictly_less_or_less_equal) + { + pos_beg_right = std::lower_bound( + r + pos_beg, r + pos_end, key, compare_node_key<_Compare>( + base_type::_M_impl._M_key_compare)) - r; - //Check if the element exists. - size_type pos_end_left = pos_beg_right; + //Check if the element exists. + size_type pos_end_left = pos_beg_right; - // If r[pos_beg_right] is equal to key, must be erased - /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/ - _GLIBCXX_PARALLEL_ASSERT((pos_beg_right == pos_end) or not base_type::_M_impl._M_key_compare(base_type::_S_key(r[pos_beg_right]),key)); - _GLIBCXX_PARALLEL_ASSERT((pos_beg_right + 1 >= pos_end) or strictly_less_or_less_equal(key, base_type::_S_key(r[pos_beg_right + 1]))); - if (pos_beg_right != pos_end and not strictly_less_or_less_equal(key, base_type::_S_key(r[pos_beg_right]))) - { - _M_destroy_node(r[pos_beg_right]); - r[pos_beg_right] = NULL; - ++pos_beg_right; - ++existing; - } - _GLIBCXX_PARALLEL_ASSERT(pos_end_left <= pos_beg_right and pos_beg_right <= pos_end and pos_end_left >= pos_beg); - return pos_end_left; - } + // If r[pos_beg_right] is equal to key, must be erased + /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/ + _GLIBCXX_PARALLEL_ASSERT( + (pos_beg_right == pos_end) + or not base_type::_M_impl._M_key_compare( + base_type::_S_key(r[pos_beg_right]),key)); + _GLIBCXX_PARALLEL_ASSERT( + (pos_beg_right + 1 >= pos_end) + or strictly_less_or_less_equal( + key, base_type::_S_key(r[pos_beg_right + 1]))); + + if (pos_beg_right != pos_end + and not strictly_less_or_less_equal( + key, base_type::_S_key(r[pos_beg_right]))) + { + _M_destroy_node(r[pos_beg_right]); + r[pos_beg_right] = NULL; + ++pos_beg_right; + ++existing; + } + _GLIBCXX_PARALLEL_ASSERT(pos_end_left <= pos_beg_right + and pos_beg_right <= pos_end + and pos_end_left >= pos_beg); + return pos_end_left; + } /** @brief Parallelization helper method: Given a random-access @@ -2579,18 +2851,26 @@ namespace __gnu_parallel * @param n Sequence size * @param num_pieces Number of pieces. */ template - static void - range_accessors(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _RandomAccessIterator* access, size_type* beg_partition, const size_type n, const thread_index_t num_pieces, std::random_access_iterator_tag) - { - access[0] = __first; - for (int i=1; i< num_pieces; ++i) - { - access[i] = access[i-1] + (__last-__first)/num_pieces; - beg_partition[i]= beg_partition[i-1]+ (__last-__first)/num_pieces; - } - beg_partition[num_pieces] = __last - access[num_pieces-1] + beg_partition[num_pieces-1]; - access[num_pieces]= __last; - } + static void + range_accessors(const _RandomAccessIterator __first, + const _RandomAccessIterator __last, + _RandomAccessIterator* access, + size_type* beg_partition, + const size_type n, + const thread_index_t num_pieces, + std::random_access_iterator_tag) + { + access[0] = __first; + for (int i = 1; i< num_pieces; ++i) + { + access[i] = access[i-1] + (__last-__first)/num_pieces; + beg_partition[i] = (beg_partition[i - 1] + + (__last - __first) / num_pieces); + } + beg_partition[num_pieces] = (__last - access[num_pieces - 1] + + beg_partition[num_pieces - 1]); + access[num_pieces]= __last; + } /** @brief Parallelization helper method: Given an input-access sequence of known size, divide it into pieces of almost the @@ -2607,21 +2887,26 @@ namespace __gnu_parallel * @param n Sequence size * @param num_pieces Number of pieces. */ template - static void - range_accessors(const _InputIterator __first, const _InputIterator __last, _InputIterator* access, size_type* beg_partition, const size_type n, const thread_index_t num_pieces, std::input_iterator_tag) - { - access[0] = __first; - _InputIterator it= __first; - for (int i=1; i< num_pieces; ++i) - { - for (int j=0; j< n/num_pieces; ++j) + static void + range_accessors(const _InputIterator __first, + const _InputIterator __last, _InputIterator* access, + size_type* beg_partition, const size_type n, + const thread_index_t num_pieces, std::input_iterator_tag) + { + access[0] = __first; + _InputIterator it= __first; + for (int i = 1; i < num_pieces; ++i) + { + for (int j=0; j< n/num_pieces; ++j) ++it; - access[i] = it; - beg_partition[i]= n/num_pieces + beg_partition[i-1]; + access[i] = it; + beg_partition[i]= n / num_pieces + beg_partition[i - 1]; } - access[num_pieces] = __last; - beg_partition[num_pieces] = n - (num_pieces-1)*(n/num_pieces) + beg_partition[num_pieces-1]; - } + access[num_pieces] = __last; + beg_partition[num_pieces] = (n - (num_pieces - 1) + * (n / num_pieces) + + beg_partition[num_pieces - 1]); + } /** @brief Initialize an array of concatenation problems for bulk insertion. They are linked as a tree with (end - beg) leaves. @@ -2631,21 +2916,27 @@ namespace __gnu_parallel * @param parent Pointer to the parent concatenation problem. */ static concat_problem* - _M_bulk_insertion_initialize_upper_problems(concat_problem** conc, const int beg, const int end, concat_problem* parent) - { - if (beg + 1 == end) - { - conc[2*beg]->par_problem = parent; - return conc[2*beg]; - } + _M_bulk_insertion_initialize_upper_problems(concat_problem** conc, + const int beg, const int end, + concat_problem* parent) + { + if (beg + 1 == end) + { + conc[2*beg]->par_problem = parent; + return conc[2*beg]; + } - int size = end - beg; - int mid = beg + size/2; - conc[2*mid-1]->par_problem = parent; - conc[2*mid-1]->left_problem = _M_bulk_insertion_initialize_upper_problems(conc, beg, mid, conc[2*mid-1]); - conc[2*mid-1]->right_problem = _M_bulk_insertion_initialize_upper_problems(conc, mid, end, conc[2*mid-1]); - return conc[2*mid-1]; - } + int size = end - beg; + int mid = beg + size/2; + conc[2*mid-1]->par_problem = parent; + conc[2*mid-1]->left_problem = + _M_bulk_insertion_initialize_upper_problems(conc, beg, mid, + conc[2*mid-1]); + conc[2*mid-1]->right_problem = + _M_bulk_insertion_initialize_upper_problems(conc, mid, end, + conc[2*mid-1]); + return conc[2*mid-1]; + } /** @brief Determine black height of a node recursively. @@ -2656,7 +2947,7 @@ namespace __gnu_parallel { if (t == NULL) return 0; - int bh = black_height (static_cast (t->_M_left)); + int bh = black_height(static_cast(t->_M_left)); if (t->_M_color == std::_S_black) ++bh; return bh; @@ -2735,8 +3026,10 @@ namespace __gnu_parallel _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1)); _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2)); - _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color != std::_S_red and black_h_l > 0 : black_h_l == 0); - _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color != std::_S_red and black_h_r > 0 : black_h_r == 0); + _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color != std::_S_red + and black_h_l > 0 : black_h_l == 0); + _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color != std::_S_red + and black_h_r > 0 : black_h_r == 0); if (black_h_l > black_h_r) if (root != NULL) @@ -2751,13 +3044,16 @@ namespace __gnu_parallel else { // XXX SHOULD BE the same as extract_min but slower. - /* - root = static_cast<_Rb_tree_node_ptr>(_Rb_tree_node_base::_S_minimum(r)); - split(r, _S_key(_Rb_tree_increment(root)), _S_key(root), root, t, r, black_h, black_h_r); + /* root = static_cast<_Rb_tree_node_ptr>( + _Rb_tree_node_base::_S_minimum(r)); + + split(r, _S_key(_Rb_tree_increment(root)), + _S_key(root), root, t, r, black_h, black_h_r); */ extract_min(r, root, r, black_h_r); _GLIBCXX_PARALLEL_ASSERT(root != NULL); - concatenate(root, l, r, black_h_l, black_h_r, t, black_h); + concatenate(root, l, r, black_h_l, + black_h_r, t, black_h); } } else @@ -2774,12 +3070,16 @@ namespace __gnu_parallel { // XXX SHOULD BE the same as extract_max but slower /* - root = static_cast<_Rb_tree_node_ptr>(_Rb_tree_node_base::_S_maximum(l)); - split(l, _S_key(root), _S_key(_Rb_tree_decrement(root)), root, l, t, black_h_l, black_h); + root = static_cast<_Rb_tree_node_ptr>( + _Rb_tree_node_base::_S_maximum(l)); + + split(l, _S_key(root), _S_key(_Rb_tree_decrement(root)), + root, l, t, black_h_l, black_h); */ extract_max(l, root, l, black_h_l); _GLIBCXX_PARALLEL_ASSERT(root != NULL); - concatenate(root, r, l, black_h_r, black_h_l, t, black_h); + concatenate(root, r, l, black_h_r, + black_h_l, t, black_h); } } #ifndef NDEBUG @@ -2808,47 +3108,55 @@ namespace __gnu_parallel * @post @c t is correct red-black tree with height @c black_h. */ template - static void - concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l, - _Rb_tree_node_ptr r, int black_h_l, int black_h_r, - _Rb_tree_node_ptr& t, int& black_h) - { - _Rb_tree_node_base* root = l; - _Rb_tree_node_ptr parent = NULL; - black_h = black_h_l; - _GLIBCXX_PARALLEL_ASSERT(black_h_l >= black_h_r); - while (black_h_l != black_h_r) - { - if (l->_M_color == std::_S_black) - --black_h_l; - parent = l; - l = static_cast<_Rb_tree_node_ptr>(S::right(l)); - _GLIBCXX_PARALLEL_ASSERT((black_h_l == 0 and (l == NULL or l->_M_color == std::_S_red)) or (black_h_l != 0 and l != NULL)); - _GLIBCXX_PARALLEL_ASSERT((black_h_r == 0 and (r == NULL or r->_M_color == std::_S_red)) or (black_h_r != 0 and r != NULL)); - } - if (l != NULL and l->_M_color == std::_S_red) - { - //the root needs to be black - parent = l; - l = static_cast<_Rb_tree_node_ptr>(S::right(l)); - } - _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color == std::_S_black : true); - _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color == std::_S_black : true); - t = plant(rt, l, r); - t->_M_parent = parent; - if (parent != NULL) - { - S::right(parent) = t; - black_h += _Rb_tree_rebalance(t, root); - t = static_cast<_Rb_tree_node_ptr> (root); - } - else - { - ++black_h; - t->_M_color = std::_S_black; - } - _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black); - } + static void + concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l, + _Rb_tree_node_ptr r, int black_h_l, int black_h_r, + _Rb_tree_node_ptr& t, int& black_h) + { + _Rb_tree_node_base* root = l; + _Rb_tree_node_ptr parent = NULL; + black_h = black_h_l; + _GLIBCXX_PARALLEL_ASSERT(black_h_l >= black_h_r); + while (black_h_l != black_h_r) + { + if (l->_M_color == std::_S_black) + --black_h_l; + parent = l; + l = static_cast<_Rb_tree_node_ptr>(S::right(l)); + _GLIBCXX_PARALLEL_ASSERT( + (black_h_l == 0 and (l == NULL or l->_M_color == std::_S_red)) + or (black_h_l != 0 and l != NULL)); + _GLIBCXX_PARALLEL_ASSERT( + (black_h_r == 0 and (r == NULL or r->_M_color == std::_S_red)) + or (black_h_r != 0 and r != NULL)); + } + if (l != NULL and l->_M_color == std::_S_red) + { + //the root needs to be black + parent = l; + l = static_cast<_Rb_tree_node_ptr>(S::right(l)); + } + + _GLIBCXX_PARALLEL_ASSERT( + l != NULL ? l->_M_color == std::_S_black : true); + _GLIBCXX_PARALLEL_ASSERT( + r != NULL ? r->_M_color == std::_S_black : true); + + t = plant(rt, l, r); + t->_M_parent = parent; + if (parent != NULL) + { + S::right(parent) = t; + black_h += _Rb_tree_rebalance(t, root); + t = static_cast<_Rb_tree_node_ptr> (root); + } + else + { + ++black_h; + t->_M_color = std::_S_black; + } + _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black); + } /** @brief Split a tree according to key in three parts: a left * child, a right child and an intermediate node. @@ -2872,36 +3180,48 @@ namespace __gnu_parallel * of the wrapping container * @return Black height of t */ template - int - split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k, - _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, - int& black_h_l, int& black_h_r, - StrictlyLessOrEqual strictly_less_or_less_equal) const - { - if (t != NULL) - { - // Must be initialized, in case we never go left!!! - root = NULL; - int h = split_not_null(t, key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_less_equal); + int + split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k, + _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, + _Rb_tree_node_ptr& r, int& black_h_l, int& black_h_r, + StrictlyLessOrEqual strictly_less_or_less_equal) + { + if (t != NULL) + { + // Must be initialized, in case we never go left!!! + root = NULL; + int h = split_not_null(t, key, prev_k, root, l, r, black_h_l, + black_h_r, strictly_less_or_less_equal); #ifndef NDEBUG - _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key)); - _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key)); - int count1, count2; - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1)); - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2)); - _GLIBCXX_PARALLEL_ASSERT(root == NULL or base_type::_M_impl._M_key_compare(prev_k, base_type::_S_key(root)) and not base_type::_M_impl._M_key_compare(key, base_type::_S_key(root))); - _GLIBCXX_PARALLEL_ASSERT(root != NULL or l==NULL or not base_type::_M_impl._M_key_compare(prev_k, base_type::_S_key(base_type::_S_maximum(l)))); + _GLIBCXX_PARALLEL_ASSERT( + l == NULL or base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_maximum(l)),key)); + _GLIBCXX_PARALLEL_ASSERT( + r == NULL or not base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_minimum(r)),key)); + int count1, count2; + _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1)); + _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2)); + _GLIBCXX_PARALLEL_ASSERT( + root == NULL or base_type::_M_impl._M_key_compare( + prev_k, base_type::_S_key(root)) + and not base_type::_M_impl._M_key_compare( + key, base_type::_S_key(root))); + _GLIBCXX_PARALLEL_ASSERT( + root != NULL or l==NULL + or not base_type::_M_impl._M_key_compare( + prev_k, base_type::_S_key(base_type::_S_maximum(l)))); #endif - return h; - } + return h; + } - r = NULL; - root = NULL; - l = NULL; - black_h_r = 0; - black_h_l = 0; - return 0; - } + r = NULL; + root = NULL; + l = NULL; + black_h_r = 0; + black_h_l = 0; + return 0; + } /** @brief Split a tree according to key in three parts: a left * child, a right child and an intermediate node. @@ -2923,98 +3243,119 @@ namespace __gnu_parallel * @pre t != NULL * @return Black height of t */ template - int - split_not_null(const _Rb_tree_node_ptr t, const key_type& key, - const key_type& prev_k, _Rb_tree_node_ptr& root, - _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l, - int& black_h_r, - StrictlyLessOrEqual strictly_less_or_equal) const - { - _GLIBCXX_PARALLEL_ASSERT (t != NULL); - int black_h, b_h; - int black_node = 0; - if (t->_M_color == std::_S_black) - ++black_node; - if (strictly_less_or_equal(key, base_type::_S_key(t))) - { - if (t->_M_left != NULL ) - { - // t->M_right is at most one node - // go to the left - b_h = black_h = split_not_null( static_cast<_Rb_tree_node_ptr>(t->_M_left), key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_equal); - // Moin root and right subtree to already existing right - // half, leave left subtree. - force_black_root(t->_M_right, b_h); - concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r); - } - else - { - // t->M_right is at most one node - r = t; - black_h_r = black_node; - force_black_root(r, black_h_r); + int + split_not_null(const _Rb_tree_node_ptr t, const key_type& key, + const key_type& prev_k, _Rb_tree_node_ptr& root, + _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, + int& black_h_l, int& black_h_r, + StrictlyLessOrEqual strictly_less_or_equal) + { + _GLIBCXX_PARALLEL_ASSERT (t != NULL); + int black_h, b_h; + int black_node = 0; + if (t->_M_color == std::_S_black) + ++black_node; + if (strictly_less_or_equal(key, base_type::_S_key(t))) + { + if (t->_M_left != NULL ) + { + // t->M_right is at most one node + // go to the left + b_h = black_h = split_not_null( + static_cast<_Rb_tree_node_ptr>(t->_M_left), key, prev_k, + root, l, r, black_h_l, black_h_r, + strictly_less_or_equal); + // Moin root and right subtree to already existing right + // half, leave left subtree. + force_black_root(t->_M_right, b_h); + concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), + black_h_r, b_h, r, black_h_r); + } + else + { + // t->M_right is at most one node + r = t; + black_h_r = black_node; + force_black_root(r, black_h_r); - black_h = 0; - l = NULL; - black_h_l = 0; - } - _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key)); - _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key)); - } - else - { - if (t->_M_right != NULL ) - { - // Go to the right. - if (strictly_less_or_equal(prev_k, base_type::_S_key(t))) - root = t; - b_h = black_h = split_not_null(static_cast<_Rb_tree_node_ptr>(t->_M_right), key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_equal); - // Join root and left subtree to already existing left - // half, leave right subtree. - force_black_root(t->_M_left, b_h); - if (root != t) - { - // There was another point where we went right. - concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l); - } - else - { - l = static_cast<_Rb_tree_node_ptr>(t->_M_left); - black_h_l = b_h; - } - _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key)); - _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key)); - } - else - { - if (strictly_less_or_equal(prev_k, base_type::_S_key(t))) - { + black_h = 0; + l = NULL; + black_h_l = 0; + } + _GLIBCXX_PARALLEL_ASSERT( + l == NULL or base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_maximum(l)),key)); + _GLIBCXX_PARALLEL_ASSERT( + r == NULL or not base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_minimum(r)),key)); + } + else + { + if (t->_M_right != NULL ) + { + // Go to the right. + if (strictly_less_or_equal(prev_k, base_type::_S_key(t))) root = t; - l= static_cast<_Rb_tree_node_ptr>(t->_M_left); - make_black_leaf(l, black_h_l); - _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key)); - } - else - { - l= t; - black_h_l = black_node; - force_black_root(l, black_h_l); - _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key)); - } + b_h = black_h = split_not_null( + static_cast<_Rb_tree_node_ptr>(t->_M_right), key, prev_k, + root, l, r, black_h_l, black_h_r, strictly_less_or_equal); + // Join root and left subtree to already existing left + // half, leave right subtree. + force_black_root(t->_M_left, b_h); + if (root != t) + { + // There was another point where we went right. + concatenate(t, static_cast<_Rb_tree_node_ptr>( + t->_M_left), l, b_h, black_h_l, + l, black_h_l); + } + else + { + l = static_cast<_Rb_tree_node_ptr>(t->_M_left); + black_h_l = b_h; + } + _GLIBCXX_PARALLEL_ASSERT( + l == NULL or base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_maximum(l)),key)); + _GLIBCXX_PARALLEL_ASSERT( + r == NULL or not base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_minimum(r)),key)); + } + else + { + if (strictly_less_or_equal(prev_k, base_type::_S_key(t))) + { + root = t; + l= static_cast<_Rb_tree_node_ptr>(t->_M_left); + make_black_leaf(l, black_h_l); + _GLIBCXX_PARALLEL_ASSERT( + l == NULL or base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_maximum(l)),key)); + } + else + { + l= t; + black_h_l = black_node; + force_black_root(l, black_h_l); + _GLIBCXX_PARALLEL_ASSERT( + l == NULL or base_type::_M_impl._M_key_compare( + base_type::_S_key(base_type::_S_maximum(l)),key)); + } - r = NULL; - black_h = 0; - black_h_r = 0; - } - } - return black_h + black_node; - } + r = NULL; + black_h = 0; + black_h_r = 0; + } + } + return black_h + black_node; + } /** @brief Color the root black and update the black height accordingly. * * @param t Root of the tree. * @param black_h Black height of the tree @c t (out) */ - static void force_black_root(_Rb_tree_node_base* t, int& black_h) + static void + force_black_root(_Rb_tree_node_base* t, int& black_h) { if (t != NULL and t->_M_color == std::_S_red) { @@ -3032,7 +3373,7 @@ namespace __gnu_parallel * @return Black height of the original tree */ int extract_min(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root, - _Rb_tree_node_ptr& r, int& black_h_r) const + _Rb_tree_node_ptr& r, int& black_h_r) { _GLIBCXX_PARALLEL_ASSERT (t != NULL); int black_h, b_h; @@ -3044,12 +3385,14 @@ namespace __gnu_parallel { // t->M_right is at most one node // go to the left - b_h = black_h = extract_min( static_cast<_Rb_tree_node_ptr>(t->_M_left), root, r, black_h_r); + b_h = black_h = extract_min( + static_cast<_Rb_tree_node_ptr>(t->_M_left), root, r, black_h_r); // Join root and right subtree to already existing right // half, leave left subtree force_black_root(t->_M_right, b_h); - concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r); + concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), + black_h_r, b_h, r, black_h_r); } else { @@ -3091,13 +3434,15 @@ namespace __gnu_parallel if (t->_M_right != NULL ) { - b_h = black_h = extract_max(static_cast<_Rb_tree_node_ptr>(t->_M_right), root, l, black_h_l); + b_h = black_h = extract_max( + static_cast<_Rb_tree_node_ptr>(t->_M_right), root, l, black_h_l); // Join root and left subtree to already existing left half, // leave right subtree. force_black_root(t->_M_left, b_h); - concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l); + concatenate(t, static_cast<_Rb_tree_node_ptr>( + t->_M_left), l, b_h, black_h_l, l, black_h_l); } else { @@ -3142,25 +3487,32 @@ namespace __gnu_parallel int black_node = 0; if (t->_M_color == std::_S_black) ++black_node; - if (not (base_type::_M_impl._M_key_compare(base_type::_S_key(t), key))) + if (not (base_type::_M_impl._M_key_compare(base_type::_S_key(t), + key))) { // Go to the left. - b_h = black_h = split( static_cast<_Rb_tree_node_ptr>(t->_M_left), key, l, r, black_h_l, black_h_r); + b_h = black_h = split( + static_cast<_Rb_tree_node_ptr>(t->_M_left), key, l, r, + black_h_l, black_h_r); // Join root and right subtree to already existing right // half, leave left subtree. force_black_root(t->_M_right, b_h); - concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r); + concatenate(t, r, static_cast<_Rb_tree_node_ptr>( + t->_M_right), black_h_r, b_h, r, black_h_r); } else { // Go to the right. - b_h = black_h = split(static_cast<_Rb_tree_node_ptr>(t->_M_right), key, l, r, black_h_l, black_h_r); + b_h = black_h = split(static_cast<_Rb_tree_node_ptr>( + t->_M_right), key, l, r, + black_h_l, black_h_r); // Join root and left subtree to already existing left // half, leave right subtree. force_black_root(t->_M_left, b_h); - concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l); + concatenate(t, static_cast<_Rb_tree_node_ptr>( + t->_M_left), l, b_h, black_h_l, l, black_h_l); } return black_h + black_node; } @@ -3192,19 +3544,20 @@ namespace __gnu_parallel * of the wrapping container * @return Resulting tree after insertion */ template - _Rb_tree_node_ptr - _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t, - size_type& existing, int& black_h, - StrictlyLessOrLessEqual strictly_less_or_less_equal) - { - _GLIBCXX_PARALLEL_ASSERT(t != NULL); - if (_M_insert_local_top_down(t, new_t, NULL, NULL, true, strictly_less_or_less_equal)) - { - t->_M_parent = NULL; - black_h += _Rb_tree_rebalance(new_t, t); - _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black); - return static_cast<_Rb_tree_node_ptr>(t); - } + _Rb_tree_node_ptr + _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t, + size_type& existing, int& black_h, + StrictlyLessOrLessEqual strictly_less_or_less_equal) + { + _GLIBCXX_PARALLEL_ASSERT(t != NULL); + if (_M_insert_local_top_down(t, new_t, NULL, NULL, + true, strictly_less_or_less_equal)) + { + t->_M_parent = NULL; + black_h += _Rb_tree_rebalance(new_t, t); + _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black); + return static_cast<_Rb_tree_node_ptr>(t); + } else { base_type::_M_destroy_node(new_t); @@ -3230,50 +3583,47 @@ namespace __gnu_parallel * @return Success of the insertion */ template - bool - _M_insert_local_top_down(_Rb_tree_node_base* t, - const _Rb_tree_node_ptr new_t, - _Rb_tree_node_base* eq_t, - _Rb_tree_node_base* parent, const bool is_left, - StrictlyLessOrLessEqual strictly_less_or_less_equal) const - { - if (t != NULL) - { - if (strictly_less_or_less_equal(_S_key(new_t), _S_key(static_cast<_Rb_tree_node_ptr>(t)))) - { - return _M_insert_local_top_down(t->_M_left, new_t, eq_t, t, true, strictly_less_or_less_equal); - } - else - { - return _M_insert_local_top_down(t->_M_right, new_t, t, t, false, strictly_less_or_less_equal); - } - } + bool + _M_insert_local_top_down(_Rb_tree_node_base* t, + const _Rb_tree_node_ptr new_t, + _Rb_tree_node_base* eq_t, + _Rb_tree_node_base* parent, const bool is_left, + StrictlyLessOrLessEqual + strictly_less_or_less_equal) const + { + if (t != NULL) + { + if (strictly_less_or_less_equal( + _S_key(new_t), _S_key(static_cast<_Rb_tree_node_ptr>(t)))) + return _M_insert_local_top_down(t->_M_left, new_t, eq_t, t, true, + strictly_less_or_less_equal); + else + return _M_insert_local_top_down(t->_M_right, new_t, t, t, false, + strictly_less_or_less_equal); + } - _GLIBCXX_PARALLEL_ASSERT(parent != NULL); + _GLIBCXX_PARALLEL_ASSERT(parent != NULL); - // Base case. - if (eq_t == NULL or strictly_less_or_less_equal(_S_key(static_cast<_Rb_tree_node_ptr>(eq_t)), _S_key(new_t))) - { - // The element to be inserted did not existed. - if (is_left) - { + // Base case. + if (eq_t == NULL or strictly_less_or_less_equal( + _S_key(static_cast<_Rb_tree_node_ptr>(eq_t)), _S_key(new_t))) + { + // The element to be inserted did not existed. + if (is_left) parent->_M_left = new_t; - } - else - { + else parent->_M_right = new_t; - } - new_t->_M_parent = parent; - new_t->_M_left = NULL; - new_t->_M_right = NULL; - new_t->_M_color = std::_S_red; + new_t->_M_parent = parent; + new_t->_M_left = NULL; + new_t->_M_right = NULL; + new_t->_M_color = std::_S_red; - return true; - } - else - return false; - } + return true; + } + else + return false; + } /** @brief Rebalance a tree locally. * @@ -3343,10 +3693,14 @@ namespace __gnu_parallel if (__root->_M_color == std::_S_red) { __root->_M_color = std::_S_black; - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(static_cast(__root))); + _GLIBCXX_PARALLEL_ASSERT( + rb_verify_tree(static_cast(__root))); return 1; } - _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(static_cast(__root))); + _GLIBCXX_PARALLEL_ASSERT( + rb_verify_tree(static_cast(__root))); return 0; } @@ -3356,7 +3710,8 @@ namespace __gnu_parallel * @return Tree correct. */ bool - rb_verify_tree(const typename base_type::_Const_Link_type __x, int& count) const + rb_verify_tree(const typename base_type::_Const_Link_type __x, + int& count) const { int bh; return rb_verify_tree_node(__x) and rb_verify_tree(__x, count, bh); @@ -3374,9 +3729,9 @@ namespace __gnu_parallel return true; else { - return rb_verify_node(__x) and - rb_verify_tree_node(base_type::_S_left(__x)) and - rb_verify_tree_node( base_type::_S_right(__x)); + return rb_verify_node(__x) + and rb_verify_tree_node(base_type::_S_left(__x)) + and rb_verify_tree_node( base_type::_S_right(__x)); } } @@ -3432,25 +3787,24 @@ namespace __gnu_parallel if (__x->_M_color == std::_S_red) if ((__L && __L->_M_color == std::_S_red) || (__R && __R->_M_color == std::_S_red)) - { - return false; - } + return false; + if (__L != NULL) { - __L = static_cast(base_type::_S_maximum(__L)); - if (base_type::_M_impl._M_key_compare(base_type::_S_key(__x), base_type::_S_key(__L))) - { - return false; - } + __L = static_cast( + base_type::_S_maximum(__L)); + if (base_type::_M_impl._M_key_compare(base_type::_S_key(__x), + base_type::_S_key(__L))) + return false; } if (__R != NULL) { - __R = static_cast(base_type::_S_minimum(__R)); - if (base_type::_M_impl._M_key_compare(base_type::_S_key(__R), base_type::_S_key(__x))) - { - return false; - } + __R = static_cast( + base_type::_S_minimum(__R)); + if (base_type::_M_impl._M_key_compare(base_type::_S_key(__R), + base_type::_S_key(__x))) + return false; } return true; @@ -3532,21 +3886,27 @@ namespace __gnu_parallel bool rb_verify() { - if (base_type::_M_impl._M_node_count == 0 || base_type::begin() == base_type::end()) + if (base_type::_M_impl._M_node_count == 0 + || base_type::begin() == base_type::end()) { - bool res = base_type::_M_impl._M_node_count == 0 && base_type::begin() == base_type::end() + bool res = base_type::_M_impl._M_node_count == 0 + && base_type::begin() == base_type::end() && base_type::_M_impl._M_header._M_left ==base_type::_M_end() && base_type::_M_impl._M_header._M_right == base_type::_M_end(); _GLIBCXX_PARALLEL_ASSERT(res); return res; } size_type i=0; - unsigned int __len = _Rb_tree_black_count(base_type::_M_leftmost(), base_type::_M_root()); - for (typename base_type::const_iterator __it =base_type::begin(); __it != base_type::end(); ++__it) + unsigned int __len = _Rb_tree_black_count(base_type::_M_leftmost(), + base_type::_M_root()); + for (typename base_type::const_iterator __it =base_type::begin(); + __it != base_type::end(); ++__it) { - typename base_type::_Const_Link_type __x = static_cast(__it._M_node); + typename base_type::_Const_Link_type __x = + static_cast(__it._M_node); if (not rb_verify_node(__x)) return false; - if (!base_type::_S_left(__x)&& !base_type::_S_right(__x) && _Rb_tree_black_count(__x,base_type::_M_root()) != __len) + if (!base_type::_S_left(__x)&& !base_type::_S_right(__x) + && _Rb_tree_black_count(__x,base_type::_M_root()) != __len) { _GLIBCXX_PARALLEL_ASSERT(false); return false; @@ -3557,12 +3917,14 @@ namespace __gnu_parallel if (i != base_type::_M_impl._M_node_count) printf("%ld != %ld\n", i, base_type::_M_impl._M_node_count); - if (base_type::_M_leftmost() != std::_Rb_tree_node_base::_S_minimum(base_type::_M_root())) + if (base_type::_M_leftmost() + != std::_Rb_tree_node_base::_S_minimum(base_type::_M_root())) { _GLIBCXX_PARALLEL_ASSERT(false); return false; } - if (base_type::_M_rightmost() != std::_Rb_tree_node_base::_S_maximum(base_type::_M_root())) + if (base_type::_M_rightmost() + != std::_Rb_tree_node_base::_S_maximum(base_type::_M_root())) { _GLIBCXX_PARALLEL_ASSERT(false); return false; diff --git a/libstdc++-v3/include/parallel/unique_copy.h b/libstdc++-v3/include/parallel/unique_copy.h index e3599b4a312..01bd1077c1b 100644 --- a/libstdc++-v3/include/parallel/unique_copy.h +++ b/libstdc++-v3/include/parallel/unique_copy.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -50,11 +50,10 @@ namespace __gnu_parallel * @param result Begin iterator of result sequence. * @param binary_pred Equality predicate. * @return End iterator of result sequence. */ -template< - typename InputIterator, - class OutputIterator, - class BinaryPredicate> - inline OutputIterator +template + OutputIterator parallel_unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred) { @@ -79,10 +78,10 @@ template< { # pragma omp single { - num_threads = omp_get_num_threads(); - borders = new difference_type[num_threads + 2]; - equally_split(size, num_threads + 1, borders); - counter = new difference_type[num_threads + 1]; + num_threads = omp_get_num_threads(); + borders = new difference_type[num_threads + 2]; + equally_split(size, num_threads + 1, borders); + counter = new difference_type[num_threads + 1]; } thread_index_t iam = omp_get_thread_num(); @@ -99,14 +98,14 @@ template< begin = borders[0] + 1; // == 1 end = borders[iam + 1]; - i++; + ++i; *out++ = *first; for (InputIterator iter = first + begin; iter < first + end; ++iter) { if (!binary_pred(*iter, *(iter-1))) { - i++; + ++i; *out++ = *iter; } } @@ -118,11 +117,9 @@ template< for (InputIterator iter = first + begin; iter < first + end; ++iter) { - if (!binary_pred(*iter, *(iter-1))) - { - i++; - } - } + if (!binary_pred(*iter, *(iter - 1))) + ++i; + } } counter[iam] = i; @@ -136,7 +133,7 @@ template< if (iam == 0) { - for (int t = 0; t < num_threads; t++) + for (int t = 0; t < num_threads; ++t) begin_output += counter[t]; i = 0; @@ -148,9 +145,9 @@ template< for (InputIterator 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; } } @@ -166,10 +163,8 @@ template< for (InputIterator iter = first + begin; iter < first + end; ++iter) { if (!binary_pred(*iter, *(iter-1))) - { - *iter_out++ = *iter; - } - } + *iter_out++ = *iter; + } } } @@ -193,8 +188,8 @@ template OutputIterator result) { typedef typename std::iterator_traits::value_type value_type; - - return parallel_unique_copy(first, last, result, std::equal_to()); + return parallel_unique_copy(first, last, result, + std::equal_to()); } }//namespace __gnu_parallel diff --git a/libstdc++-v3/include/parallel/workstealing.h b/libstdc++-v3/include/parallel/workstealing.h index 60c873951e1..4f0c7482c2f 100644 --- a/libstdc++-v3/include/parallel/workstealing.h +++ b/libstdc++-v3/include/parallel/workstealing.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008 Free Software Foundation, Inc. // // 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 @@ -96,20 +96,19 @@ template * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ -template< - typename RandomAccessIterator, - typename Op, - typename Fu, - typename Red, - typename Result> +template Op - for_each_template_random_access_workstealing( - RandomAccessIterator begin, - RandomAccessIterator end, - Op op, Fu& f, Red r, - Result base, Result& output, - typename std::iterator_traits::difference_type - bound) + for_each_template_random_access_workstealing(RandomAccessIterator begin, + RandomAccessIterator end, + Op op, Fu& f, Red r, + Result base, Result& output, + typename std::iterator_traits + :: + difference_type bound) { _GLIBCXX_CALL(end - begin) @@ -180,7 +179,7 @@ template< // This thread is currently working. # pragma omp atomic - busy++; + ++busy; iam_working = true; @@ -198,8 +197,8 @@ template< // Cannot use volatile variable directly. difference_type my_first = my_job.first; result = f(op, begin + my_first); - my_job.first++; - my_job.load--; + ++my_job.first; + --my_job.load; } RandomAccessIterator current; @@ -226,11 +225,11 @@ template< my_job.load = my_job.last - my_job.first + 1; for (difference_type job_counter = 0; job_counter < chunk_size && current_job <= my_job.last; - job_counter++) + ++job_counter) { // Yes: process it! current = begin + current_job; - current_job++; + ++current_job; // Do actual work. result = r(result, f(op, current)); @@ -244,7 +243,7 @@ template< { // This thread no longer has work. # pragma omp atomic - busy--; + --busy; iam_working = false; } @@ -286,7 +285,7 @@ template< // Has potential work again. # pragma omp atomic - busy++; + ++busy; iam_working = true; # pragma omp flush(busy)