1 #ifndef DIY_DETAIL_ALL_TO_ALL_HPP
2 #define DIY_DETAIL_ALL_TO_ALL_HPP
4 #include "../block_traits.hpp"
14 using Block =
typename block_traits<Op>::type;
16 AllToAllReduce(
const Op& op_,
const Assigner& assigner):
19 for (
int gid = 0; gid < assigner.nblocks(); ++gid)
21 BlockID nbr = { gid, assigner.rank(gid) };
22 all_neighbors_link.add_neighbor(nbr);
26 void operator()(Block* b,
const ReduceProxy& srp,
const RegularSwapPartners& partners)
const
28 int k_in = srp.in_link().size();
29 int k_out = srp.out_link().size();
31 if (k_in == 0 && k_out == 0)
33 ReduceProxy all_srp_out(srp, srp.block(), 0, srp.assigner(), empty_link, all_neighbors_link);
34 ReduceProxy all_srp_in (srp, srp.block(), 1, srp.assigner(), all_neighbors_link, empty_link);
37 MemoryBuffer& in_queue = all_srp_in.incoming(all_srp_in.in_link().target(0).gid);
38 in_queue.swap(all_srp_out.outgoing(all_srp_out.out_link().target(0)));
47 ReduceProxy all_srp(srp, srp.block(), 0, srp.assigner(), empty_link, all_neighbors_link);
50 Master::OutgoingQueues all_queues;
51 all_queues.swap(*all_srp.outgoing());
54 int group = all_srp.out_link().size() / k_out;
55 for (
int i = 0; i < k_out; ++i)
57 std::pair<int,int> range(i*group, (i+1)*group);
58 srp.enqueue(srp.out_link().target(i), range);
59 for (
int j = i*group; j < (i+1)*group; ++j)
62 int to = all_srp.out_link().target(j).gid;
63 srp.enqueue(srp.out_link().target(i), std::make_pair(from, to));
64 srp.enqueue(srp.out_link().target(i), all_queues[all_srp.out_link().target(j)]);
67 }
else if (k_out == 0)
70 ReduceProxy all_srp(srp, srp.block(), 1, srp.assigner(), all_neighbors_link, empty_link);
72 Master::IncomingQueues all_incoming;
73 all_incoming.swap(*srp.incoming());
75 std::pair<int, int> range;
76 for (
int i = 0; i < k_in; ++i)
78 int gid_in = srp.in_link().target(i).gid;
79 MemoryBuffer&
in = all_incoming[gid_in];
83 std::pair<int, int> from_to;
85 load(in, all_srp.incoming(from_to.first));
86 all_srp.incoming(from_to.first).reset();
94 std::vector<size_t> sizes_out(k_out,
sizeof(std::pair<int,int>));
95 std::pair<int, int> range;
96 for (
int i = 0; i < k_in; ++i)
98 MemoryBuffer& in = srp.incoming(srp.in_link().target(i).gid);
101 int group = (range.second - range.first)/k_out;
103 std::pair<int, int> from_to;
110 int j = (from_to.second - range.first) / group;
111 sizes_out[j] += s +
sizeof(size_t) +
sizeof(std::pair<int,int>);
118 int group = (range.second - range.first)/k_out;
119 for (
int i = 0; i < k_out; ++i)
121 MemoryBuffer& out = srp.outgoing(srp.out_link().target(i));
122 out.reserve(sizes_out[i]);
124 std::pair<int, int> out_range;
125 out_range.first = range.first + group*i;
126 out_range.second = range.first + group*(i+1);
127 save(out, out_range);
131 for (
int i = 0; i < k_in; ++i)
133 MemoryBuffer& in = srp.incoming(srp.in_link().target(i).gid);
137 std::pair<int, int> from_to;
141 int j = (from_to.second - range.first) / group;
143 MemoryBuffer& out = srp.outgoing(srp.out_link().target(j));
152 Link all_neighbors_link, empty_link;
155 struct SkipIntermediate
157 SkipIntermediate(
size_t rounds_):
160 bool operator()(
int round,
int,
const Master&)
const {
if (round == 0 || round == (
int) rounds)
return false;
return true; }
void load(BinaryBuffer &bb, T &x)
Loads x from bb by calling diy::Serialization<T>::load(bb,x).
Definition: serialization.hpp:106
static void copy(MemoryBuffer &from, MemoryBuffer &to)
copy a memory buffer from one buffer to another, bypassing making a temporary copy first ...
Definition: serialization.hpp:450
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