1 #ifndef DIY_DETAIL_ALGORITHMS_SORT_HPP
2 #define DIY_DETAIL_ALGORITHMS_SORT_HPP
13 template<
class Block,
class T,
class Cmp>
16 typedef std::vector<T> Block::*ValuesVector;
20 SampleSort(ValuesVector values_, ValuesVector samples_,
const Cmp& cmp_,
size_t num_samples_):
21 values(values_), samples(samples_),
22 cmp(cmp_), num_samples(num_samples_) {}
24 Sampler sample()
const {
return Sampler(values, samples, cmp, num_samples); }
25 Exchanger exchange()
const {
return Exchanger(values, samples, cmp); }
27 static void dequeue_values(std::vector<T>& v,
const ReduceProxy& rp,
bool skip_self =
true)
29 auto log = get_logger();
31 int k_in = rp.in_link().size();
33 log->trace(
"dequeue_values(): gid={}, round={}; v.size()={}", rp.gid(), rp.round(), v.size());
35 if (detail::is_default< Serialization<T> >::value)
39 size_t end = v.size();
40 for (
int i = 0; i < k_in; ++i)
42 log->trace(
" incoming size from {}: {}", rp.in_link().target(i).gid, sz);
43 if (skip_self && rp.in_link().target(i).gid == rp.gid())
continue;
44 MemoryBuffer&
in = rp.incoming(rp.in_link().target(i).gid);
45 sz += in.size() /
sizeof(T);
47 log->trace(
" incoming size: {}", sz);
50 for (
int i = 0; i < k_in; ++i)
52 if (skip_self && rp.in_link().target(i).gid == rp.gid())
continue;
53 MemoryBuffer& in = rp.incoming(rp.in_link().target(i).gid);
54 size_t sz = in.size() /
sizeof(T);
55 T* bg = (T*) &in.buffer[0];
56 std::copy(bg, bg + sz, &v[end]);
61 for (
int i = 0; i < k_in; ++i)
63 if (skip_self && rp.in_link().target(i).gid == rp.gid())
continue;
64 MemoryBuffer& in = rp.incoming(rp.in_link().target(i).gid);
69 v.emplace_back(std::move(x));
73 log->trace(
" v.size()={}", v.size());
82 template<
class Block,
class T,
class Cmp>
83 struct SampleSort<Block,T,Cmp>::Sampler
85 Sampler(ValuesVector values_, ValuesVector dividers_,
const Cmp& cmp_,
size_t num_samples_):
86 values(values_), dividers(dividers_), cmp(cmp_), num_samples(num_samples_) {}
88 void operator()(Block* b,
const ReduceProxy& srp,
const RegularSwapPartners& partners)
const
90 int k_in = srp.in_link().size();
91 int k_out = srp.out_link().size();
93 std::vector<T> samples;
98 for (
size_t i = 0; i < num_samples; ++i)
99 samples.push_back((b->*values)[std::rand() % (b->*values).size()]);
101 dequeue_values(samples, srp,
false);
106 std::sort(samples.begin(), samples.end(), cmp);
107 std::vector<T> subsamples(srp.nblocks() - 1);
108 int step = samples.size() / srp.nblocks();
109 for (
size_t i = 0; i < subsamples.size(); ++i)
110 subsamples[i] = samples[(i+1)*step];
111 (b->*dividers).swap(subsamples);
115 for (
int i = 0; i < k_out; ++i)
117 MemoryBuffer& out = srp.outgoing(srp.out_link().target(i));
118 save(out, &samples[0], samples.size());
124 ValuesVector dividers;
129 template<
class Block,
class T,
class Cmp>
130 struct SampleSort<Block,T,Cmp>::Exchanger
132 Exchanger(ValuesVector values_, ValuesVector samples_,
const Cmp& cmp_):
133 values(values_), samples(samples_), cmp(cmp_) {}
135 void operator()(Block* b,
const ReduceProxy& rp)
const
140 for (
size_t i = 0; i < (b->*values).size(); ++i)
142 int to = std::lower_bound((b->*samples).begin(), (b->*samples).end(), (b->*values)[i], cmp) - (b->*samples).begin();
143 rp.enqueue(rp.out_link().target(to), (b->*values)[i]);
145 (b->*values).clear();
148 dequeue_values((b->*values), rp,
false);
149 std::sort((b->*values).begin(), (b->*values).end(), cmp);
154 ValuesVector samples;
void load(BinaryBuffer &bb, T &x)
Loads x from bb by calling diy::Serialization<T>::load(bb,x).
Definition: serialization.hpp:106
void save(BinaryBuffer &bb, const T &x)
Saves x to bb by calling diy::Serialization<T>::save(bb,x).
Definition: serialization.hpp:102
void in(const RegularLink< Bounds > &link, const Point &p, OutIter out, const Bounds &domain)
Finds the neighbor(s) containing the target point.
Definition: pick.hpp:102
void sort(Master &master, const Assigner &assigner, std::vector< T > Block::*values, std::vector< T > Block::*samples, size_t num_samples, const Cmp &cmp, int k=2, bool samples_only=false)
sample sort values of each block, store the boundaries between blocks in samples
Definition: algorithms.hpp:25