1 #ifndef DIY_ALGORITHMS_HPP
2 #define DIY_ALGORITHMS_HPP
7 #include "assigner.hpp"
9 #include "reduce-operations.hpp"
10 #include "partners/swap.hpp"
12 #include "detail/algorithms/sort.hpp"
13 #include "detail/algorithms/kdtree.hpp"
14 #include "detail/algorithms/kdtree-sampling.hpp"
24 template<
class Block,
class T,
class Cmp>
27 std::vector<T> Block::* values,
28 std::vector<T> Block::* samples,
32 bool samples_only =
false)
34 bool immediate = master.immediate();
35 master.set_immediate(
false);
39 detail::SampleSort<Block,T,Cmp> sorter(values, samples, cmp, num_samples);
44 reduce(master, assigner, partners, sorter.sample(), detail::SkipIntermediate(partners.rounds()));
48 all_to_all(master, assigner, sorter.exchange(), k);
50 master.set_immediate(immediate);
60 template<
class Block,
class T>
63 std::vector<T> Block::* values,
64 std::vector<T> Block::* samples,
68 sort(master, assigner, values, samples, num_samples, std::less<T>(), k);
75 template<
class Block,
class Po
int>
80 std::vector<Point> Block::* points,
85 throw std::runtime_error(fmt::format(
"KD-tree requires a number of blocks that's a power of 2, got {}", assigner.
nblocks()));
89 for (
size_t i = 0; i < master.
size(); ++i)
91 RCLink* link =
static_cast<RCLink*
>(master.link(i));
92 *link = RCLink(dim, domain, domain);
97 for (
int j = 0; j < dim; ++j)
102 dir[j] = -1; wrap_dir[j] = -1;
103 link->add_neighbor(
self);
104 link->add_bounds(domain);
105 link->add_direction(dir);
106 link->add_wrap(wrap_dir);
109 dir[j] = 1; wrap_dir[j] = 1;
110 link->add_neighbor(
self);
111 link->add_bounds(domain);
112 link->add_direction(dir);
113 link->add_wrap(wrap_dir);
118 detail::KDTreePartition<Block,Point> kdtree_partition(dim, points, bins);
120 detail::KDTreePartners partners(dim, assigner.
nblocks(), wrap, domain);
121 reduce(master, assigner, partners, kdtree_partition);
125 for (
size_t i = 0; i < master.
size(); ++i)
126 expected += master.link(i)->size_unique();
127 master.set_expected(expected);
134 template<
class Block,
class Po
int>
140 std::vector<Point> Block::* points,
145 throw std::runtime_error(fmt::format(
"KD-tree requires a number of blocks that's a power of 2, got {}", assigner.
nblocks()));
149 for (
size_t i = 0; i < master.
size(); ++i)
151 RCLink* link =
static_cast<RCLink*
>(master.link(i));
152 *link = RCLink(dim, domain, domain);
157 for (
int j = 0; j < dim; ++j)
162 dir[j] = -1; wrap_dir[j] = -1;
163 link->add_neighbor(
self);
164 link->add_bounds(domain);
165 link->add_direction(dir);
166 link->add_wrap(wrap_dir);
169 dir[j] = 1; wrap_dir[j] = 1;
170 link->add_neighbor(
self);
171 link->add_bounds(domain);
172 link->add_direction(dir);
173 link->add_wrap(wrap_dir);
178 detail::KDTreeSamplingPartition<Block,Point> kdtree_partition(dim, points, samples);
180 detail::KDTreePartners partners(dim, assigner.
nblocks(), wrap, domain);
181 reduce(master, assigner, partners, kdtree_partition);
185 for (
size_t i = 0; i < master.
size(); ++i)
186 expected += master.link(i)->size_unique();
187 master.set_expected(expected);
void kdtree_sampling(Master &master, const Assigner &assigner, int dim, const ContinuousBounds &domain, std::vector< Point > Block::*points, size_t samples, bool wrap=false)
build a kd-tree and sort a set of points into it (use sampling to determine split values) ...
Definition: algorithms.hpp:136
int nblocks() const
returns the total number of global blocks
Definition: assigner.hpp:26
Decomposes a regular (discrete or continuous) domain into even blocks; creates Links with Bounds alon...
Definition: decomposition.hpp:75
int gid(int i) const
return gid of the i-th block
Definition: master.hpp:219
void reduce(Master &master, const Assigner &assigner, const Partners &partners, const Reduce &reduce, const Skip &skip)
Implementation of the reduce communication pattern (includes swap-reduce, merge-reduce, and any other global communication).
Definition: reduce.hpp:109
void all_to_all(Master &master, const Assigner &assigner, const Op &op, int k=2)
all to all reduction
Definition: reduce-operations.hpp:18
Definition: assigner.hpp:11
Definition: master.hpp:35
void kdtree(Master &master, const Assigner &assigner, int dim, const ContinuousBounds &domain, std::vector< Point > Block::*points, size_t bins, bool wrap=false)
build a kd-tree and sort a set of points into it (use histograms to determine split values) ...
Definition: algorithms.hpp:76
const mpi::communicator & communicator() const
return the MPI communicator
Definition: master.hpp:212
diy::DiscreteBounds interval(int from, int to)
Helper to create a 1-dimensional discrete domain with the specified extents.
Definition: types.hpp:28
unsigned size() const
return the number of local blocks
Definition: master.hpp:233
Partners for swap-reduce.
Definition: swap.hpp:16
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