20 #ifndef RAJA_util_sort_HPP
21 #define RAJA_util_sort_HPP
23 #include "RAJA/config.hpp"
44 template<
typename Iter,
typename Predicate>
57 Iter first_false = begin;
58 for (; first_false != end; ++first_false)
61 if (!pred(first_false))
68 if (first_false == end)
74 for (Iter next_true =
RAJA::next(first_false); next_true != end; ++next_true)
95 template<
typename Iter,
typename Compare>
108 for (Iter next_unsorted =
RAJA::next(begin); next_unsorted != end;
113 for (Iter to_insert = next_unsorted; to_insert != begin; --to_insert)
119 if (comp(*to_insert, *next_sorted))
149 1llu, 4llu, 10llu, 23llu, 57llu, 132llu, 301llu, 701llu, 1750llu,
151 3937llu, 8858llu, 19930llu, 44842llu, 100894llu, 227011llu, 510774llu,
152 1149241llu, 2585792llu, 5818032llu, 13090572llu, 29453787llu, 66271020llu,
153 149109795llu, 335497038llu, 754868335llu, 1698453753llu, 3821520944llu,
154 8598422124llu, 19346449779llu, 43529512002llu, 97941402004llu,
155 220368154509llu, 495828347645llu, 1115613782201llu, 2510131009952llu,
156 5647794772392llu, 12707538237882llu, 28591961035234llu,
157 64331912329276llu})[i];
164 template<
typename Iter,
typename Compare>
170 diff_type n = end - begin;
172 if (n <=
static_cast<diff_type
>(1))
182 for (; i_stride < num_strides; ++i_stride)
194 for (; i_stride > 0; --i_stride)
199 for (diff_type i_next_unsorted = stride; i_next_unsorted != n;
204 for (diff_type i_to_insert = i_next_unsorted; i_to_insert >= stride;
205 i_to_insert -= stride)
208 Iter to_insert = begin + i_to_insert;
209 Iter next_sorted = to_insert - stride;
212 if (comp(*to_insert, *next_sorted))
238 template<
typename Iter,
typename Compare>
246 auto N = end - begin;
250 for (
auto i = root - begin; 2 * i + 1 < N; i = root - begin)
257 Iter child = begin + 2 * i + 1;
258 if (comp(*maxit, *child))
265 if (child != end && comp(*maxit, *child))
287 template<
typename Iter,
typename Compare>
292 auto N = end - begin;
302 for (Iter root = begin + (N - 1) / 2; root != begin; --root)
305 heapify(begin, root, end, comp);
308 heapify(begin, begin, end, comp);
311 for (--end; begin != end; --end)
318 heapify(begin, begin, end, comp);
327 static constexpr
unsigned get() {
return 4; }
335 static constexpr
size_t get() {
return 16; }
342 template<
typename Iter,
typename Compare>
351 diff_type N = end - begin;
354 constexpr diff_type insertion_sort_cutoff =
362 else if (N < insertion_sort_cutoff)
379 Iter mid = begin + N / 2;
383 ? (comp(*mid, *last) ? mid : (comp(*begin, *last) ? last : begin))
384 : (comp(*mid, *last) ? (comp(*begin, *last) ? begin : last) : mid);
394 mid =
partition(begin, last, [&](Iter it) {
395 return comp(*it, *pivot);
416 template<
typename Iter,
typename Compare>
419 auto N = end - begin;
424 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
440 template<
typename Iter,
typename Compare>
441 void RAJA_INLINE
inplace_merge(Iter first, Iter middle, Iter last, Compare comp)
446 diff_type copylen = middle - first;
448 if (first == middle || middle == last)
454 if (!comp(*middle, *(middle - 1)))
462 buf_deleter_type buf_deleter;
464 std::unique_ptr<value_type, buf_deleter_type&> copy_buf(
465 RAJA::allocate_aligned_type<value_type>(RAJA::DATA_ALIGN,
466 copylen *
sizeof(value_type)),
469 value_type* copyarr = copy_buf.get();
472 if (copyarr ==
nullptr)
479 for (diff_type& cc = buf_deleter.size; cc < copylen; ++cc)
481 new (©arr[cc]) value_type(std::move(first[cc]));
485 for (diff_type cur = 0; cur < copylen;)
489 std::move(copyarr + cur, copyarr + copylen, first);
492 else if (first == middle)
497 if (comp(*middle, copyarr[cur]))
499 *first = std::move(*middle);
504 *first = std::move(copyarr[cur]);
516 template<
typename Iter1,
typename Iter2,
typename OutIter,
typename Compare>
528 if (first1 == last2 - 1)
533 if ((last2 - first1) == 2)
535 if (!comp(*d_first, *(d_first + 1)))
542 while (first1 < last1 || first2 < last2)
546 *d_first = std::move(*first2);
549 else if (first2 >= last2)
551 *d_first = std::move(*first1);
556 if (comp(*first2, *first1))
558 *d_first = std::move(*first2);
563 *d_first = std::move(*first1);
578 template<
typename Iter,
typename Compare>
579 RAJA_INLINE
void merge_sort(Iter begin, Iter end, Compare comp)
587 auto minlam = [](diff_type a, diff_type b) {
588 return (a < b) ? a : b;
592 diff_type len = end - begin;
593 static constexpr diff_type insertion_sort_cutoff = 16;
594 if (len <= insertion_sort_cutoff && len > 0)
601 for (diff_type start = 0; start < len; start += insertion_sort_cutoff)
603 diff_type lastchunk = minlam(insertion_sort_cutoff, len - start);
611 buf_deleter_type buf_deleter;
613 std::unique_ptr<value_type, buf_deleter_type&> copy_buf(
614 RAJA::allocate_aligned_type<value_type>(RAJA::DATA_ALIGN,
615 len *
sizeof(value_type)),
618 value_type* copyarr = copy_buf.get();
621 if (copyarr ==
nullptr)
628 for (diff_type& cc = buf_deleter.size; cc < len; ++cc)
630 new (©arr[cc]) value_type(std::move(begin[cc]));
633 bool copyvalid =
true;
636 for (diff_type midpoint = 16; midpoint < len;
639 for (diff_type start = 0; start < len;
640 start += midpoint * 2)
642 diff_type finish = minlam(start + midpoint * 2, len);
646 "merge_sort invalid finish point");
649 if (start + midpoint >= len)
654 std::move(copyarr + start, copyarr + finish, begin + start);
658 std::move(begin + start, begin + finish, copyarr + start);
667 copyarr + start + midpoint, copyarr + finish,
668 begin + start, comp);
673 begin + start + midpoint, begin + finish,
674 copyarr + start, comp);
678 copyvalid = !copyvalid;
685 std::move(copyarr, copyarr + len, begin);
703 template<
typename Container,
704 typename Compare = operators::less<detail::ContainerVal<Container>>>
706 concepts::enable_if<type_traits::is_range<Container>>
712 static_assert(type_traits::is_binary_function<Compare, bool, T, T>::value,
713 "Compare must model BinaryFunction");
714 static_assert(type_traits::is_random_access_range<Container>::value,
715 "Container must model RandomAccessRange");
717 auto begin_it = begin(c);
718 auto end_it = end(c);
720 if (begin_it != end_it)
722 auto next = begin_it;
723 if (++
next != end_it)
734 template<
typename Container,
735 typename Compare = operators::less<detail::ContainerVal<Container>>>
737 concepts::enable_if<type_traits::is_range<Container>>
743 static_assert(type_traits::is_binary_function<Compare, bool, T, T>::value,
744 "Compare must model BinaryFunction");
745 static_assert(type_traits::is_random_access_range<Container>::value,
746 "Container must model RandomAccessRange");
748 auto begin_it = begin(c);
749 auto end_it = end(c);
751 if (begin_it != end_it)
753 auto next = begin_it;
754 if (++
next != end_it)
765 template<
typename Container,
766 typename Compare = operators::less<detail::ContainerVal<Container>>>
768 concepts::enable_if<type_traits::is_range<Container>>
774 static_assert(type_traits::is_binary_function<Compare, bool, T, T>::value,
775 "Compare must model BinaryFunction");
776 static_assert(type_traits::is_random_access_range<Container>::value,
777 "Container must model RandomAccessRange");
779 auto begin_it = begin(c);
780 auto end_it = end(c);
782 if (begin_it != end_it)
784 auto next = begin_it;
785 if (++
next != end_it)
796 template<
typename Container,
797 typename Compare = operators::less<detail::ContainerVal<Container>>>
799 concepts::enable_if<type_traits::is_range<Container>>
805 static_assert(type_traits::is_binary_function<Compare, bool, T, T>::value,
806 "Compare must model BinaryFunction");
807 static_assert(type_traits::is_random_access_range<Container>::value,
808 "Container must model RandomAccessRange");
810 auto begin_it = begin(c);
811 auto end_it = end(c);
813 if (begin_it != end_it)
815 auto next = begin_it;
816 if (++
next != end_it)
827 template<
typename Container,
828 typename Compare = operators::less<detail::ContainerVal<Container>>>
829 RAJA_INLINE concepts::enable_if<type_traits::is_range<Container>>
merge_sort(
831 Compare comp = Compare {})
836 static_assert(type_traits::is_binary_function<Compare, bool, T, T>::value,
837 "Compare must model BinaryFunction");
838 static_assert(type_traits::is_random_access_range<Container>::value,
839 "Container must model RandomAccessRange");
841 auto begin_it = begin(c);
842 auto end_it = end(c);
844 if (begin_it != end_it)
846 auto next = begin_it;
847 if (++
next != end_it)
Header file for RAJA algorithm definitions.
Header file for RAJA concept definitions.
Header file for common RAJA internal macro definitions.
RAJA_HOST_DEVICE void RAJA_ABORT_OR_THROW(const char *str)
Definition: macros.hpp:143
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
Header file providing RAJA math templates.
RAJA_HOST_DEVICE constexpr RAJA_INLINE size_t num_shell_strides()
get number of strides for shell sort
Definition: sort.hpp:138
void RAJA_INLINE inplace_merge(Iter first, Iter middle, Iter last, Compare comp)
merge a range with midpoint using comparison function with local range/2 copy
Definition: sort.hpp:441
RAJA_HOST_DEVICE RAJA_INLINE void heapify(Iter begin, Iter root, Iter end, Compare comp)
insert the given element into the heaps below it using comparison function and using O(lg(N)) compari...
Definition: sort.hpp:239
camp::decay< decltype(*camp::val< camp::iterator_from< Container > >())> ContainerVal
Definition: algorithm.hpp:51
void RAJA_INLINE merge_like_std(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, OutIter d_first, Compare comp)
merge given two ranges using comparison function while copies are outside, somewhat follows STL API
Definition: sort.hpp:519
RAJA_HOST_DEVICE void heap_sort(Iter begin, Iter end, Compare comp)
unstable heap sort given range inplace using comparison function and using O(N*lg(N)) comparisons and...
Definition: sort.hpp:288
RAJA_HOST_DEVICE constexpr RAJA_INLINE long long unsigned get_shell_stride(int i)
get strides for shell sort
Definition: sort.hpp:143
RAJA_HOST_DEVICE RAJA_INLINE Iter partition(Iter begin, Iter end, Predicate pred)
unstable partition given range inplace using predicate function and using O(N) predicate evaluations ...
Definition: sort.hpp:45
RAJA_HOST_DEVICE void intro_sort_depth(Iter begin, Iter end, Compare comp, unsigned depth)
unstable intro sort given range inplace using comparison function and using O(N*lg(N)) comparisons an...
Definition: sort.hpp:343
RAJA_HOST_DEVICE RAJA_INLINE void insertion_sort(Iter begin, Iter end, Compare comp)
stable insertion sort given range inplace using comparison function and using O(N^2) comparisons and ...
Definition: sort.hpp:96
typename ::std::iterator_traits< Iter >::difference_type IterDiff
Definition: algorithm.hpp:44
typename ::std::iterator_traits< Iter >::value_type IterVal
Definition: algorithm.hpp:38
RAJA_INLINE void merge_sort(Iter begin, Iter end, Compare comp)
stable merge sort given range inplace using comparison function and using O(N*lg(N)) comparisons and ...
Definition: sort.hpp:579
RAJA_HOST_DEVICE RAJA_INLINE void shell_sort(Iter begin, Iter end, Compare comp)
unstable shell sort given range inplace using comparison function and using O(N^?) comparisons and O(...
Definition: sort.hpp:165
RAJA_HOST_DEVICE void intro_sort(Iter begin, Iter end, Compare comp)
unstable intro sort given range inplace using comparison function and using O(N*lg(N)) comparisons an...
Definition: sort.hpp:417
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE RAJA_INLINE Iter next(Iter it)
returns iterator to next item
Definition: algorithm.hpp:90
RAJA_HOST_DEVICE RAJA_INLINE concepts::enable_if< type_traits::is_range< Container > > insertion_sort(Container &&c, Compare comp=Compare {})
stable insertion sort given range inplace using comparison function and using O(N^2) comparisons and ...
Definition: sort.hpp:707
RAJA_INLINE concepts::enable_if< type_traits::is_range< Container > > merge_sort(Container &&c, Compare comp=Compare {})
stable merge sort given range inplace using comparison function and using O(N*lg(N)) comparisons and ...
Definition: sort.hpp:829
RAJA_HOST_DEVICE RAJA_INLINE concepts::enable_if< type_traits::is_range< Container > > heap_sort(Container &&c, Compare comp=Compare {})
unstable heap sort given range inplace using comparison function and using O(N*lg(N)) comparisons and...
Definition: sort.hpp:769
RAJA_HOST_DEVICE constexpr RAJA_INLINE T log2(T n) noexcept
evaluate log base 2 of n
Definition: math.hpp:40
RAJA_HOST_DEVICE RAJA_INLINE void safe_iter_swap(Iter lhs, Iter rhs)
swap values at iterators lhs and rhs
Definition: algorithm.hpp:75
RAJA_HOST_DEVICE RAJA_INLINE concepts::enable_if< type_traits::is_range< Container > > shell_sort(Container &&c, Compare comp=Compare {})
unstable shell sort given range inplace using comparison function and using O(N^?) comparisons and O(...
Definition: sort.hpp:738
RAJA_HOST_DEVICE RAJA_INLINE Iter prev(Iter it)
returns iterator to next item
Definition: algorithm.hpp:100
RAJA_HOST_DEVICE RAJA_INLINE concepts::enable_if< type_traits::is_range< Container > > intro_sort(Container &&c, Compare comp=Compare {})
unstable intro sort given range inplace using comparison function and using O(N*lg(N)) comparisons an...
Definition: sort.hpp:800
Definition: MemUtils_CPU.hpp:109
max recursion depth for intro sort when compiling device code.
Definition: sort.hpp:326
static constexpr unsigned get()
Definition: sort.hpp:327
cutoff for intro sort to use insertion sort on small ranges.
Definition: sort.hpp:334
static constexpr size_t get()
Definition: sort.hpp:335