Itoyori  v0.0.1
reducer_extra.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "ityr/common/util.hpp"
7 
8 namespace ityr::reducer {
9 
10 template <typename T, typename Counter = std::size_t>
11 struct histogram {
12  static_assert(std::is_arithmetic_v<T>);
13 
14  using value_type = T;
16 
17  histogram(std::size_t n_bins) : n_bins_(n_bins) {}
18  histogram(std::size_t n_bins, const value_type& lowest, const value_type& highest)
19  : n_bins_(n_bins), lowest_(lowest), highest_(highest) {}
20 
21  void operator()(accumulator_type& acc, const value_type& x) const {
22  if (lowest_ <= x && x <= highest_) {
23  auto delta = (highest_ - lowest_) / n_bins_;
24  std::size_t key = (x - lowest_) / delta;
25  ITYR_CHECK(key < n_bins_);
26  acc[key]++;
27  }
28  }
29 
30  void operator()(accumulator_type& acc_l, const accumulator_type& acc_r) const {
31  transform(
33  acc_l.begin(), acc_l.end(), acc_r.begin(), acc_l.begin(),
34  [](const Counter& c1, const Counter& c2) { return c1 + c2; });
35  }
36 
37  void operator()(const accumulator_type& acc_l, accumulator_type& acc_r) const {
38  // commutative
39  foldl(acc_r, acc_l);
40  }
41 
43  return global_vector<Counter>(n_bins_, 0);
44  }
45 
46 private:
47  std::size_t n_bins_;
48  value_type lowest_ = std::numeric_limits<value_type>::lowest();
50 };
51 
52 template <typename T>
53 struct vec_concat {
56 
57  void operator()(accumulator_type& acc_l, accumulator_type&& acc_r) const {
58  acc_l.insert(acc_l.end(), make_move_iterator(acc_r.begin()), make_move_iterator(acc_r.end()));
59  }
60 
61  void operator()(accumulator_type&& acc_l, accumulator_type& acc_r) const {
62  acc_r.insert(acc_r.begin(), make_move_iterator(acc_l.begin()), make_move_iterator(acc_l.end()));
63  }
64 
66  return global_vector<T>();
67  }
68 };
69 
70 template <typename T, typename BinaryOp>
74 
75  void operator()(accumulator_type& acc_l, value_type&& acc_r) const {
76  if (acc_l.empty()) {
77  acc_l = std::move(acc_r);
78  } else {
79  ITYR_CHECK(acc_l.size() == acc_r.size());
80  for_each(
85  [&](auto&& x, const auto& y) { x = bop_(x, y); });
86  }
87  }
88 
89  void operator()(accumulator_type&& acc_l, accumulator_type& acc_r) const {
90  if (acc_r.empty()) {
91  acc_r = std::move(acc_l);
92  } else {
93  ITYR_CHECK(acc_l.size() == acc_r.size());
94  for_each(
95  execution::sequenced_policy(acc_l.size()),
99  [&](const auto& x, auto&& y) { y = bop_(x, y); });
100  }
101  }
102 
104  return global_vector<T>();
105  }
106 
107 private:
108  static constexpr auto bop_ = BinaryOp();
109 };
110 
111 template <typename T>
113 
114 template <typename T>
116 
117 template <typename T>
119 
120 template <typename T>
122 
123 ITYR_TEST_CASE("[ityr::reducer] extra reducer test") {
124  ito::init();
125  ori::init();
126 
127  ITYR_SUBCASE("histogram") {
128  root_exec([=] {
129  int n_samples = 100000;
130  int n_bins = 1000;
131  global_vector<double> v(global_vector_options(true, 1024), n_samples);
132 
133  transform(
135  count_iterator<int>(0), count_iterator<int>(n_samples), v.begin(),
136  [=](int i) {
137  double x = (static_cast<double>(i) + 0.5) / n_bins;
138  return x - static_cast<int>(x); // within [0.0, 1.0)
139  });
140 
141  auto bins = reduce(
143  v.begin(), v.end(), histogram<double>(n_bins, 0.0, 1.0));
144  ITYR_CHECK(bins.size() == n_bins);
145 
146  auto count_sum = reduce(execution::par, bins.begin(), bins.end());
147  ITYR_CHECK(count_sum == n_samples);
148 
149  for_each(
153  [=](auto count) {
154  ITYR_CHECK(count == n_samples / n_bins);
155  });
156  });
157  }
158 
159  ITYR_SUBCASE("vec_concat") {
160  root_exec([=] {
161  int n = 10000;
162 
168  [](int i) { return global_vector<int>(1, i); });
169  ITYR_CHECK(ret.size() == n);
170 
171  global_vector<int> ans(n);
172  copy(
176  ans.begin());
177 
178  ITYR_CHECK(ret == ans);
179  });
180  }
181 
182  ITYR_SUBCASE("vec_element_wise") {
183  root_exec([=] {
184  int n = 10000;
185  int vec_size = 100;
186 
192  [=](int i) { return global_vector<int>(vec_size, i); });
193  ITYR_CHECK(ret.size() == vec_size);
194 
195  for_each(
199  [=](int x) { ITYR_CHECK(x == n * (n - 1) / 2); });
200  });
201  }
202 
203  ori::fini();
204  ito::fini();
205 }
206 
207 }
Count iterator.
Definition: count_iterator.hpp:33
Global vector to manage a global memory region.
Definition: global_vector.hpp:129
iterator begin() noexcept
Definition: global_vector.hpp:233
size_type size() const noexcept
Definition: global_vector.hpp:228
bool empty() const noexcept
Definition: global_vector.hpp:274
iterator insert(const_iterator position, const T &x)
Definition: global_vector.hpp:333
iterator end() noexcept
Definition: global_vector.hpp:234
#define ITYR_SUBCASE(name)
Definition: util.hpp:41
#define ITYR_CHECK(cond)
Definition: util.hpp:48
constexpr read_write_t read_write
Read+Write checkout mode.
Definition: checkout_span.hpp:39
constexpr read_t read
Read-only checkout mode.
Definition: checkout_span.hpp:19
constexpr parallel_policy par
Default parallel execution policy for iterator-based loop functions.
Definition: execution.hpp:89
void fini()
Definition: ito.hpp:45
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ito.hpp:41
void fini()
Definition: ori.hpp:49
void init(MPI_Comm comm=MPI_COMM_WORLD)
Definition: ori.hpp:45
Definition: reducer.hpp:5
monoid< T, max_functor<>, lowest< T > > max
Definition: reducer.hpp:104
ForwardIteratorD copy(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d)
Copy a range to another.
Definition: parallel_loop.hpp:856
ForwardIteratorD transform(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d, UnaryOp unary_op)
Transform elements in a given range and store them in another range.
Definition: parallel_loop.hpp:583
void for_each(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Op op)
Apply an operator to each element in a range.
Definition: parallel_loop.hpp:136
auto root_exec(Fn &&fn, Args &&... args)
Spawn the root thread (collective).
Definition: root_exec.hpp:47
Reducer::accumulator_type transform_reduce(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Reducer reducer, UnaryTransformOp unary_transform_op)
Calculate reduction while transforming each element.
Definition: parallel_reduce.hpp:167
Reducer::accumulator_type reduce(const ExecutionPolicy &policy, ForwardIterator first, ForwardIterator last, Reducer reducer)
Calculate reduction.
Definition: parallel_reduce.hpp:340
global_iterator< T, Mode > make_global_iterator(ori::global_ptr< T > gptr, Mode)
Make a global iterator to enable/disable automatic checkout.
Definition: global_iterator.hpp:158
global_move_iterator< global_iterator< T, internal::src_checkout_mode_t< T > > > make_move_iterator(ori::global_ptr< T > gptr)
Make a global iterator for moving objects.
Definition: global_iterator.hpp:258
ForwardIteratorD move(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d)
Move a range to another.
Definition: parallel_loop.hpp:934
Parallel execution policy for iterator-based loop functions.
Definition: execution.hpp:36
Serial execution policy for iterator-based loop functions.
Definition: execution.hpp:16
Options for ityr::global_vector.
Definition: global_vector.hpp:18
Definition: reducer.hpp:56
Definition: reducer_extra.hpp:11
histogram(std::size_t n_bins, const value_type &lowest, const value_type &highest)
Definition: reducer_extra.hpp:18
T value_type
Definition: reducer_extra.hpp:14
histogram(std::size_t n_bins)
Definition: reducer_extra.hpp:17
void operator()(accumulator_type &acc, const value_type &x) const
Definition: reducer_extra.hpp:21
void operator()(accumulator_type &acc_l, const accumulator_type &acc_r) const
Definition: reducer_extra.hpp:30
accumulator_type operator()() const
Definition: reducer_extra.hpp:42
void operator()(const accumulator_type &acc_l, accumulator_type &acc_r) const
Definition: reducer_extra.hpp:37
Definition: reducer.hpp:47
Definition: reducer_extra.hpp:53
accumulator_type operator()() const
Definition: reducer_extra.hpp:65
void operator()(accumulator_type &&acc_l, accumulator_type &acc_r) const
Definition: reducer_extra.hpp:61
void operator()(accumulator_type &acc_l, accumulator_type &&acc_r) const
Definition: reducer_extra.hpp:57
Definition: reducer_extra.hpp:71
void operator()(accumulator_type &&acc_l, accumulator_type &acc_r) const
Definition: reducer_extra.hpp:89
void operator()(accumulator_type &acc_l, value_type &&acc_r) const
Definition: reducer_extra.hpp:75
accumulator_type operator()() const
Definition: reducer_extra.hpp:103