reduce.h
Go to the documentation of this file.
1 //
2 // Created by Eduard Valeyev on 12/22/17.
3 //
4 
5 #ifndef TTG_REDUCE_H
6 #define TTG_REDUCE_H
7 
8 #include <cassert>
9 #include <cstdlib>
10 #include <mutex>
11 
12 #include "ttg/util/tree.h"
13 
14 namespace ttg {
15 
28  template <typename Value, typename BinaryOp, typename OutKey>
30  : public TT<int, std::tuple<Out<int, Value>, Out<int, Value>, Out<int, Value>, Out<OutKey, Value>>,
31  BinaryTreeReduce<Value, BinaryOp, OutKey>, ttg::typelist<Value, Value, Value>> {
32  public:
33  using baseT = typename BinaryTreeReduce::ttT;
34 
35  BinaryTreeReduce(Edge<int, Value> &in, Edge<OutKey, Value> &out, int root = 0, OutKey dest_key = OutKey(),
36  BinaryOp op = BinaryOp{}, World world = ttg::default_execution_context(), int max_key = -1,
37  Edge<int, Value> inout = Edge<int, Value>{}, Edge<int, Value> inout_l = Edge<int, Value>{},
38  Edge<int, Value> inout_r = Edge<int, Value>{})
39  : baseT(edges(fuse(in, inout), inout_l, inout_r), edges(inout, inout_l, inout_r, out), "BinaryTreeReduce",
40  {"in|inout", "inout_l", "inout_r"}, {"inout", "inout_l", "inout_r", "out"}, world, [](int key) { return key; })
41  , tree_((max_key == -1 ? world.size() : max_key), root)
42  , dest_key_(dest_key)
43  , op_(std::move(op)) {
44  init();
45  }
46 
47  void op(const int &key, typename baseT::input_values_tuple_type &&indata,
49  assert(key < tree_.size());
50  assert(key == this->get_world().rank());
52  auto children = tree_.child_keys(key);
53  Value result;
54  if (children.first != -1 && children.second != -1)
55  // left-associative in-order reduction: L op This op R = ((L op This) op R)
56  result = op_(op_(baseT::template get<1, Value &&>(indata), baseT::template get<0, Value &&>(indata)),
57  baseT::template get<2, Value &&>(indata));
58  else {
59  if (children.first != -1)
60  result = op_(baseT::template get<1, Value &&>(indata), baseT::template get<0, Value &&>(indata));
61  else if (children.second != -1)
62  result = op_(baseT::template get<0, Value &&>(indata), baseT::template get<2, Value &&>(indata));
63  else
64  result = baseT::template get<0, Value &&>(indata);
65  }
66  auto parent = tree_.parent_key(key);
67  if (parent != -1) {
68  // is this left or right child of the parent?
69  bool this_is_left_child;
70  {
71  auto parents_children = tree_.child_keys(parent);
72  assert(parents_children.first == key || parents_children.second == key);
73  this_is_left_child = (parents_children.first == key);
74  }
75  if (this_is_left_child)
76  send<1>(parent, std::move(result), outdata);
77  else
78  send<2>(parent, std::move(result), outdata);
79  } else
80  send<3>(dest_key_, std::move(result), outdata);
81  }
82 
83  private:
84  BinarySpanningTree tree_;
85  OutKey dest_key_;
86  BinaryOp op_;
87 
90  void init() {
91  // iterate over keys that map to me ... if keys are equivalent to ranks this can be made simpler
92  const auto my_rank = this->get_world().rank();
93  for (auto key = 0; key != tree_.size(); ++key) {
94  if (my_rank == this->get_keymap()(key)) {
95  auto keys = tree_.child_keys(key);
96  if (keys.first == -1) this->template set_arg<1>(key, Value());
97  if (keys.second == -1) this->template set_arg<2>(key, Value());
98  }
99  }
100  }
101  };
102 
103 #if 0
108 template <typename InKey, template Value, template Reducer, template OutKey>
109 class Reduce : public TT<InKey, std::tuple<Out<OutKey, Value>>, Reduce<InKey, Value, Reducer, OutKey>, Value> {
110  public:
111  using baseT = TT<InKey, std::tuple<Out<OutKey, Value>>, Reduce<InKey, Value, Reducer, OutKey>, Value>;
112 
113  Reduce(Edge<InKey, Value> &in, Edge<OutKey, Value> &out, OutKey dest_key = OutKey(), std::size_t nitems = 1,
114  World &world = default_execution_context())
115  : baseT(edges(in), edges(out, Edge<OutKey, Value>("reduce")), "Reduce", {"in"}, {"out"}, world)
116  , dest_key_(dest_key)
117  , nitems_(nitems) {}
118 
119  void op(const InKey &key, baseT::input_values_tuple_type &&indata, std::tuple<Out<OutKey, Value>> &outdata) {
120  std::lock_guard<std::mutex> lock(mutex_);
121  if (nitems_) {
122  reducer_(value_, baseT::get<0>(indata));
123  --nitems_;
124  }
125  if (nitems_ == 0) {
126  binary_tree_reduce_.set_arg<0>(world.rank(), std::move(value_));
127  }
128  }
129 
130  private:
131  OutKey dest_key_;
132  size_t nitems_;
133  std::mutex mutex_;
134  Value value_;
135  Reducer reducer_;
136 }; // class Reduce
137 #endif
138 
139 } // namespace ttg
140 
141 #endif // TTG_REDUCE_H
a binary spanning tree of integers in the [0,size) interval
Definition: tree.h:17
int parent_key(const int child_key) const
Definition: tree.h:32
const auto size() const
Definition: tree.h:26
std::pair< int, int > child_keys(const int parent_key) const
Definition: tree.h:40
generic binary reduction of a set of key-value pairs.
Definition: reduce.h:31
void op(const int &key, typename baseT::input_values_tuple_type &&indata, std::tuple< Out< int, Value >, Out< int, Value >, Out< int, Value >, Out< OutKey, Value >> &outdata)
Definition: reduce.h:47
typename BinaryTreeReduce::ttT baseT
Definition: reduce.h:33
BinaryTreeReduce(Edge< int, Value > &in, Edge< OutKey, Value > &out, int root=0, OutKey dest_key=OutKey(), BinaryOp op=BinaryOp{}, World world=ttg::default_execution_context(), int max_key=-1, Edge< int, Value > inout=Edge< int, Value >{}, Edge< int, Value > inout_l=Edge< int, Value >{}, Edge< int, Value > inout_r=Edge< int, Value >{})
Definition: reduce.h:35
Edge is used to connect In and Out terminals.
Definition: edge.h:25
int size() const
Definition: world.h:198
int rank() const
Definition: world.h:204
top-level TTG namespace contains runtime-neutral functionality
Definition: keymap.h:8
auto fuse(const Edge< keyT, valuesT > &...args)
Fuse edges into one This allows receiving one data from either of the combined edges.
Definition: func.h:137
World default_execution_context()
Accesses the default backend's default execution context.
Definition: run.h:68
int rank(World world=default_execution_context())
Definition: run.h:85
auto edges(inedgesT &&...args)
Make a tuple of Edges to pass to.
Definition: func.h:147