14 template <
typename W,
typename RandomAccessIterator,
15 typename SplittableUniformRandomBitGenerator>
16 inline RandomAccessIterator
17 random_partition(
const execution::parallel_policy<W>& policy,
18 RandomAccessIterator first,
19 RandomAccessIterator last,
20 SplittableUniformRandomBitGenerator&& urbg) {
21 std::size_t d = std::distance(first, last);
23 if (d <= policy.cutoff_count) {
25 ITYR_CHECK(policy.cutoff_count == policy.checkout_count);
27 auto&& [css, its] = checkout_global_iterators(d, first);
28 auto&& first_ = std::get<0>(its);
30 [&](
auto&&) {
return urbg() % 2 == 0; });
31 return std::next(first, std::distance(first_, m));
34 auto mid = std::next(first, d / 2);
36 auto child_urbg1 = urbg.split();
37 auto child_urbg2 = urbg.split();
40 [=]()
mutable {
return random_partition(policy, first, mid , child_urbg1); },
41 [=]()
mutable {
return random_partition(policy, mid , last, child_urbg2); });
44 return rotate(policy, m1, mid, m2);
47 template <
typename W,
typename RandomAccessIterator,
48 typename SplittableUniformRandomBitGenerator>
49 inline void shuffle(
const execution::parallel_policy<W>& policy,
50 RandomAccessIterator first,
51 RandomAccessIterator last,
52 SplittableUniformRandomBitGenerator&& urbg) {
53 std::size_t d = std::distance(first, last);
57 if (d <= policy.cutoff_count) {
58 auto [css, its] = checkout_global_iterators(d, first);
59 auto first_ = std::get<0>(its);
63 auto mid = random_partition(policy, first, last, urbg);
65 auto child_urbg1 = urbg.split();
66 auto child_urbg2 = urbg.split();
69 [=]()
mutable {
shuffle(policy, first, mid , child_urbg1); },
70 [=]()
mutable {
shuffle(policy, mid , last, child_urbg2); });
111 template <
typename ExecutionPolicy,
typename RandomAccessIterator,
112 typename UniformRandomBitGenerator>
113 inline void shuffle(
const ExecutionPolicy& policy,
114 RandomAccessIterator first,
115 RandomAccessIterator last,
116 UniformRandomBitGenerator&& urbg) {
117 if constexpr (ori::is_global_ptr_v<RandomAccessIterator>) {
122 std::forward<UniformRandomBitGenerator>(urbg));
125 internal::shuffle(policy, first, last, std::forward<UniformRandomBitGenerator>(urbg));
129 ITYR_TEST_CASE(
"[ityr::pattern::parallel_shuffle] shuffle") {
134 ori::global_ptr<long> p1 = ori::malloc_coll<long>(n);
135 ori::global_ptr<long> p2 = ori::malloc_coll<long>(n);
139 execution::parallel_policy(100),
140 count_iterator<long>(0), count_iterator<long>(n), p1,
141 [=](
long i) {
return i; });
144 execution::parallel_policy(100),
145 count_iterator<long>(0), count_iterator<long>(n), p2,
146 [=](
long i) {
return i; });
149 p1, p1 + n, p2) ==
true);
154 shuffle(execution::parallel_policy(100), p1, p1 + n,
158 p1, p1 + n, p2) ==
false);
161 p1, p1 + n) == n * (n - 1) / 2);
163 sort(execution::parallel_policy(100), p1, p1 + n);
166 p1, p1 + n, p2) ==
true);
177 shuffle(execution::parallel_policy(100), p1, p1 + n, rng);
178 shuffle(execution::parallel_policy(100), p2, p2 + n, rng_copy);
181 p1, p1 + n, p2) ==
true);
190 uint64_t seed2 = 417;
193 shuffle(execution::parallel_policy(100), p1, p1 + n, rng1);
194 shuffle(execution::parallel_policy(100), p2, p2 + n, rng2);
197 p1, p1 + n, p2) ==
false);
#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
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 shuffle(const ExecutionPolicy &policy, RandomAccessIterator first, RandomAccessIterator last, UniformRandomBitGenerator &&urbg)
Randomly shuffle elements in a range.
Definition: parallel_shuffle.hpp:113
BidirectionalIterator rotate(const ExecutionPolicy &policy, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last)
Rotate a range.
Definition: parallel_loop.hpp:1135
internal::random_engine_dummy default_random_engine
Definition: random.hpp:41
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
BidirectionalIterator stable_partition(const ExecutionPolicy &policy, BidirectionalIterator first, BidirectionalIterator last, Predicate pred)
Partition elements into two disjoint parts in place.
Definition: parallel_filter.hpp:76
void sort(const ExecutionPolicy &policy, RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Sort a range.
Definition: parallel_sort.hpp:210
Reducer::accumulator_type reduce(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Reducer reducer)
Calculate reduction.
Definition: parallel_reduce.hpp:340
bool equal(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred)
Check if two ranges have equal values.
Definition: parallel_reduce.hpp:887