6 #include "assigner.hpp"
7 #include "detail/block_traits.hpp"
17 typedef std::vector<int> GIDVector;
23 const GIDVector& incoming_gids,
24 const GIDVector& outgoing_gids):
31 for (
unsigned i = 0; i < incoming_gids.size(); ++i)
34 nbr.gid = incoming_gids[i];
35 nbr.proc = assigner.
rank(nbr.gid);
36 in_link_.add_neighbor(nbr);
40 for (
unsigned i = 0; i < outgoing_gids.size(); ++i)
43 nbr.gid = outgoing_gids[i];
44 nbr.proc = assigner.
rank(nbr.gid);
45 out_link_.add_neighbor(nbr);
64 void*
block()
const {
return block_; }
66 unsigned round()
const {
return round_; }
90 template<
class Block,
class Partners>
91 struct ReductionFunctor;
93 template<
class Partners,
class Skip>
94 struct SkipInactiveOr;
96 struct ReduceNeverSkip
98 bool operator()(
int,
int,
const Master&)
const {
return false; }
108 template<
class Reduce,
class Partners,
class Skip>
111 const Partners& partners,
115 auto log = get_logger();
117 int original_expected = master.expected();
119 using Block =
typename detail::block_traits<Reduce>::type;
122 for (round = 0; round < partners.rounds(); ++round)
124 log->debug(
"Round {}", round);
125 master.foreach(detail::ReductionFunctor<Block,Partners>(round, reduce, partners, assigner),
126 detail::SkipInactiveOr<Partners,Skip>(round, partners, skip));
130 for (
unsigned i = 0; i < master.
size(); ++i)
132 if (partners.active(round + 1, master.
gid(i), master))
134 std::vector<int> incoming_gids;
135 partners.incoming(round + 1, master.
gid(i), incoming_gids, master);
136 expected +=
static_cast<int>(incoming_gids.size());
137 master.incoming(master.
gid(i)).clear();
140 master.set_expected(expected);
144 log->debug(
"Round {}", round);
145 master.foreach(detail::ReductionFunctor<Block,Partners>(round, reduce, partners, assigner),
146 detail::SkipInactiveOr<Partners,Skip>(round, partners, skip));
148 master.set_expected(original_expected);
157 template<
class Reduce,
class Partners>
160 const Partners& partners,
161 const Reduce& reducer)
163 reduce(master, assigner, partners, reducer, detail::ReduceNeverSkip());
168 template<
class Block,
class Partners>
169 struct ReductionFunctor
171 using Callback = std::function<void(Block*, const ReduceProxy&, const Partners&)>;
173 ReductionFunctor(
unsigned round_,
const Callback& reduce_,
const Partners& partners_,
const Assigner& assigner_):
174 round(round_),
reduce(reduce_), partners(partners_), assigner(assigner_) {}
176 void operator()(Block* b,
const Master::ProxyWithLink& cp)
const
178 if (!partners.active(round, cp.gid(), *cp.master()))
return;
180 std::vector<int> incoming_gids, outgoing_gids;
182 partners.incoming(round, cp.gid(), incoming_gids, *cp.master());
183 if (round < partners.rounds())
184 partners.outgoing(round, cp.gid(), outgoing_gids, *cp.master());
186 ReduceProxy rp(cp, b, round, assigner, incoming_gids, outgoing_gids);
190 Master::OutgoingQueues& outgoing = *cp.outgoing();
191 if (outgoing.size() < (size_t) rp.out_link().size())
192 for (
int j = 0; j < rp.out_link().size(); ++j)
193 outgoing[rp.out_link().target(j)];
199 const Assigner& assigner;
202 template<
class Partners,
class Skip>
203 struct SkipInactiveOr
205 SkipInactiveOr(
int round_,
const Partners& partners_,
const Skip& skip_):
206 round(round_), partners(partners_), skip(skip_) {}
207 bool operator()(
int i,
const Master& master)
const {
return !partners.active(round, master.gid(i), master) || skip(round, i, master); }
209 const Partners& partners;
216 #endif // DIY_REDUCE_HPP
const Link & out_link() const
returns outgoing link
Definition: reduce.hpp:70
Enables communication within a group during a reduction. DIY creates the ReduceProxy for you in diy::...
Definition: reduce.hpp:15
unsigned round() const
returns current round number
Definition: reduce.hpp:66
int nblocks() const
returns the total number of global blocks
Definition: assigner.hpp:26
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
unsigned int size() const
return the number of local blocks
Definition: master.hpp:233
virtual int rank(int gid) const =0
returns the process rank of the block with global id gid (need not be local)
void set_round(unsigned r)
advanced: change current round number
Definition: reduce.hpp:77
Definition: assigner.hpp:11
ReduceProxy(const Master::Proxy &proxy, void *block, unsigned round, const Assigner &assigner, const Link &in_link, const Link &out_link)
Definition: reduce.hpp:49
const Link & in_link() const
returns incoming link
Definition: reduce.hpp:68
Definition: master.hpp:35
Communication proxy, used for enqueueing and dequeueing items for future exchange.
Definition: proxy.hpp:8
ReduceProxy(const Master::Proxy &proxy, void *block, unsigned round, const Assigner &assigner, const GIDVector &incoming_gids, const GIDVector &outgoing_gids)
Definition: reduce.hpp:19
void * block() const
returns pointer to block
Definition: reduce.hpp:64
int nblocks() const
returns total number of blocks
Definition: reduce.hpp:72
const Assigner & assigner() const
returns the assigner
Definition: reduce.hpp:74