12 template <
bool Stable,
typename W,
typename RandomAccessIterator,
typename Compare>
13 inline void merge_sort(
const execution::parallel_policy<W>& policy,
14 RandomAccessIterator first,
15 RandomAccessIterator last,
17 std::size_t d = std::distance(first, last);
21 if (d <= policy.cutoff_count) {
22 auto [css, its] = checkout_global_iterators(d, first);
23 auto first_ = std::get<0>(its);
27 auto middle = std::next(first, d / 2);
30 [=] { merge_sort<Stable>(policy, first, middle, comp); },
31 [=] { merge_sort<Stable>(policy, middle, last, comp); });
33 internal::inplace_merge_aux<Stable>(policy, first, middle, last, comp);
70 template <
typename ExecutionPolicy,
typename RandomAccessIterator,
typename Compare>
72 RandomAccessIterator first,
73 RandomAccessIterator last,
75 if constexpr (ori::is_global_ptr_v<RandomAccessIterator>) {
83 internal::merge_sort<true>(policy, first, last, comp);
103 template <
typename ExecutionPolicy,
typename RandomAccessIterator>
105 RandomAccessIterator first,
106 RandomAccessIterator last) {
110 ITYR_TEST_CASE(
"[ityr::pattern::parallel_sort] stable_sort") {
123 ori::global_ptr<item> p = ori::malloc_coll<item>(n);
127 execution::parallel_policy(100),
128 count_iterator<long>(0), count_iterator<long>(n), p,
129 [=](
long i) {
return item{i % n_keys, (3 * i + 5) % 13}; });
132 p, p + n, [](
const auto& a,
const auto& b) {
return a.val < b.val; });
135 p, p + n, [](
const auto& a,
const auto& b) {
return a.key < b.key; });
137 long n_values_per_key = n / n_keys;
138 for (
long key = 0; key < n_keys; key++) {
139 bool sorted =
is_sorted(execution::parallel_policy(100),
140 p + key * n_values_per_key,
141 p + (key + 1) * n_values_per_key,
142 [=](
const auto& a,
const auto& b) {
145 return a.val < b.val;
156 ori::global_ptr<long> p = ori::malloc_coll<long>(n);
160 execution::parallel_policy(100),
161 count_iterator<long>(0), count_iterator<long>(n), p,
162 [=](
long i) {
return i; });
165 p, p + n, [](
const auto&,
const auto&) {
return false; });
168 execution::parallel_policy(100),
169 count_iterator<long>(0), count_iterator<long>(n),
209 template <
typename ExecutionPolicy,
typename RandomAccessIterator,
typename Compare>
210 inline void sort(
const ExecutionPolicy& policy,
211 RandomAccessIterator first,
212 RandomAccessIterator last,
214 if constexpr (ori::is_global_ptr_v<RandomAccessIterator>) {
222 internal::merge_sort<false>(policy, first, last, comp);
248 template <
typename ExecutionPolicy,
typename RandomAccessIterator>
249 inline void sort(
const ExecutionPolicy& policy,
250 RandomAccessIterator first,
251 RandomAccessIterator last) {
252 sort(policy, first, last, std::less<>{});
255 ITYR_TEST_CASE(
"[ityr::pattern::parallel_sort] sort") {
260 ori::global_ptr<long> p = ori::malloc_coll<long>(n);
264 execution::parallel_policy(100),
265 count_iterator<long>(0), count_iterator<long>(n), p,
266 [=](
long i) {
return (3 * i + 5) % 13; });
271 sort(execution::parallel_policy(100), p, p + n);
#define ITYR_SUBCASE(name)
Definition: util.hpp:41
#define ITYR_CHECK(cond)
Definition: util.hpp:48
constexpr read_write_t read_write
Read+Write checkout mode.
Definition: checkout_span.hpp:39
constexpr read_t read
Read-only checkout mode.
Definition: checkout_span.hpp:19
void fini()
Definition: ito.hpp:45
auto root_exec(Fn &&fn, Args &&... args)
Definition: ito.hpp:50
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ito.hpp:41
void fini()
Definition: ori.hpp:49
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ori.hpp:45
void free_coll(global_ptr< T > ptr)
Definition: ori.hpp:70
Definition: allocator.hpp:16
void stable_sort(const ExecutionPolicy &policy, RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Stable sort for a range.
Definition: parallel_sort.hpp:71
auto parallel_invoke(Args &&... args)
Fork parallel tasks and join them.
Definition: parallel_invoke.hpp:238
ForwardIteratorD transform(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d, UnaryOp unary_op)
Transform elements in a given range and store them in another range.
Definition: parallel_loop.hpp:583
void for_each(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Op op)
Apply an operator to each element in a range.
Definition: parallel_loop.hpp:136
void sort(const ExecutionPolicy &policy, RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Sort a range.
Definition: parallel_sort.hpp:210
void stable_sort(const ExecutionPolicy &policy, RandomAccessIterator first, RandomAccessIterator last)
Stable sort for a range.
Definition: parallel_sort.hpp:104
global_iterator< T, Mode > make_global_iterator(ori::global_ptr< T > gptr, Mode)
Make a global iterator to enable/disable automatic checkout.
Definition: global_iterator.hpp:158
bool is_sorted(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Compare comp)
Check if a range is sorted.
Definition: parallel_reduce.hpp:1054