RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
multi_reduce.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_PATTERN_DETAIL_MULTI_REDUCE_HPP
21 #define RAJA_PATTERN_DETAIL_MULTI_REDUCE_HPP
22 
24 
25 #include "RAJA/util/macros.hpp"
26 #include "RAJA/util/Operators.hpp"
27 #include "RAJA/util/types.hpp"
28 #include "RAJA/util/RepeatView.hpp"
29 
30 
31 #define RAJA_DECLARE_MULTI_REDUCER(OP_NAME, OP, POL, DATA) \
32  template<typename tuning, typename T> \
33  struct MultiReduce##OP_NAME<POL<tuning>, T> \
34  : reduce::detail::BaseMultiReduce##OP_NAME< \
35  DATA<T, RAJA::reduce::OP<T>, tuning>> \
36  { \
37  using policy = POL<tuning>; \
38  using Base = reduce::detail::BaseMultiReduce##OP_NAME< \
39  DATA<T, RAJA::reduce::OP<T>, tuning>>; \
40  using Base::Base; \
41  using typename Base::value_type; \
42  using typename Base::reference; \
43  \
44  RAJA_SUPPRESS_HD_WARN \
45  RAJA_HOST_DEVICE \
46  reference operator[](size_t bin) const { return reference(*this, bin); } \
47  };
48 
49 #define RAJA_DECLARE_ALL_MULTI_REDUCERS(POL, DATA) \
50  RAJA_DECLARE_MULTI_REDUCER(Sum, sum, POL, DATA) \
51  RAJA_DECLARE_MULTI_REDUCER(Min, min, POL, DATA) \
52  RAJA_DECLARE_MULTI_REDUCER(Max, max, POL, DATA) \
53  RAJA_DECLARE_MULTI_REDUCER(BitOr, or_bit, POL, DATA) \
54  RAJA_DECLARE_MULTI_REDUCER(BitAnd, and_bit, POL, DATA)
55 
56 namespace RAJA
57 {
58 
59 namespace reduce
60 {
61 
62 namespace detail
63 {
64 
65 template<typename t_MultiReduceData>
67 {
68  using MultiReduceData = t_MultiReduceData;
69  using MultiReduceOp = typename t_MultiReduceData::MultiReduceOp;
70  using value_type = typename t_MultiReduceData::value_type;
71 
74  {}
75 
76  explicit BaseMultiReduce(size_t num_bins,
77  value_type init_val = MultiReduceOp::identity(),
78  value_type identity = MultiReduceOp::identity())
79  : BaseMultiReduce {RepeatView<value_type>(init_val, num_bins), identity}
80  {}
81 
82  template<typename Container,
83  concepts::enable_if_t<
84  type_traits::is_range<Container>,
85  concepts::negate<std::is_convertible<Container, size_t>>,
86  concepts::negate<std::is_base_of<BaseMultiReduce, Container>>>* =
87  nullptr>
88  explicit BaseMultiReduce(Container const& container,
89  value_type identity = MultiReduceOp::identity())
90  : data {container, identity}
91  {}
92 
94  BaseMultiReduce(BaseMultiReduce const&) = default;
100  ~BaseMultiReduce() = default;
101 
102  void reset()
103  {
104  reset(RepeatView<value_type>(MultiReduceOp::identity(), size()));
105  }
106 
107  void reset(size_t num_bins,
108  value_type init_val = MultiReduceOp::identity(),
109  value_type identity = MultiReduceOp::identity())
110  {
111  reset(RepeatView<value_type>(init_val, num_bins), identity);
112  }
113 
114  template<typename Container,
115  concepts::enable_if_t<type_traits::is_range<Container>>* = nullptr>
116  void reset(Container const& container,
117  value_type identity = MultiReduceOp::identity())
118  {
119  for (size_t bin = 0; bin < data.num_bins(); ++bin)
120  {
121  RAJA_UNUSED_VAR(get(bin)); // automatic get() before reset
122  }
123  data.reset(container, identity);
124  }
125 
127 
129  size_t size() const { return data.num_bins(); }
130 
132 
134  BaseMultiReduce const& combine(size_t bin, value_type const& other) const
135  {
136  data.combine(bin, other);
137  return *this;
138  }
139 
141  value_type get(size_t bin) const { return data.get(bin); }
142 
144  template<typename Container,
145  concepts::enable_if_t<type_traits::is_range<Container>>* = nullptr>
146  void get_all(Container& container) const
147  {
148  RAJA_EXTRACT_BED_IT(container);
149  if (size_t(distance_it) != data.num_bins())
150  {
151  RAJA_ABORT_OR_THROW("MultiReduce::get_all container has different size "
152  "than multi reducer");
153  }
154  size_t bin = 0;
155  for (auto& val : container)
156  {
157  val = data.get(bin);
158  ++bin;
159  }
160  }
161 
162 private:
163  MultiReduceData mutable data;
164 };
165 
173 template<typename MultiReduceData>
174 class BaseMultiReduceMin : public BaseMultiReduce<MultiReduceData>
175 {
176 public:
178  using Base::Base;
179  using typename Base::value_type;
180 
190  ~BaseMultiReduceMin() = default;
191 
192  struct reference
193  {
195  reference(BaseMultiReduceMin const& base, size_t bin)
196  : m_base(base),
197  m_bin(bin)
198  {}
199 
202  reference const& min(value_type rhs) const
203  {
204  m_base.combine(m_bin, rhs);
205  return *this;
206  }
207 
208  value_type get() const { return m_base.get(m_bin); }
209 
210  private:
211  BaseMultiReduceMin const& m_base;
212  size_t m_bin;
213  };
214 };
215 
223 template<typename MultiReduceData>
224 class BaseMultiReduceMax : public BaseMultiReduce<MultiReduceData>
225 {
226 public:
228  using typename Base::value_type;
229 
230  using Base::Base;
231 
239  ~BaseMultiReduceMax() = default;
240 
241  struct reference
242  {
244  reference(BaseMultiReduceMax const& base, size_t bin)
245  : m_base(base),
246  m_bin(bin)
247  {}
248 
251  reference const& max(value_type rhs) const
252  {
253  m_base.combine(m_bin, rhs);
254  return *this;
255  }
256 
257  value_type get() const { return m_base.get(m_bin); }
258 
259  private:
260  BaseMultiReduceMax const& m_base;
261  size_t m_bin;
262  };
263 };
264 
272 template<typename MultiReduceData>
273 class BaseMultiReduceSum : public BaseMultiReduce<MultiReduceData>
274 {
275 public:
277  using typename Base::value_type;
278 
279  using Base::Base;
280 
288  ~BaseMultiReduceSum() = default;
289 
290  struct reference
291  {
293  reference(BaseMultiReduceSum const& base, size_t bin)
294  : m_base(base),
295  m_bin(bin)
296  {}
297 
300  reference const& operator+=(value_type rhs) const
301  {
302  m_base.combine(m_bin, rhs);
303  return *this;
304  }
305 
306  value_type get() const { return m_base.get(m_bin); }
307 
308  private:
309  BaseMultiReduceSum const& m_base;
310  size_t m_bin;
311  };
312 };
313 
321 template<typename MultiReduceData>
322 class BaseMultiReduceBitOr : public BaseMultiReduce<MultiReduceData>
323 {
324 public:
326  using typename Base::value_type;
327 
328  using Base::Base;
329 
338 
339  struct reference
340  {
342  reference(BaseMultiReduceBitOr const& base, size_t bin)
343  : m_base(base),
344  m_bin(bin)
345  {}
346 
349  reference const& operator|=(value_type rhs) const
350  {
351  m_base.combine(m_bin, rhs);
352  return *this;
353  }
354 
355  value_type get() const { return m_base.get(m_bin); }
356 
357  private:
358  BaseMultiReduceBitOr const& m_base;
359  size_t m_bin;
360  };
361 };
362 
370 template<typename MultiReduceData>
371 class BaseMultiReduceBitAnd : public BaseMultiReduce<MultiReduceData>
372 {
373 public:
375  using typename Base::value_type;
376 
377  using Base::Base;
378 
387 
388  struct reference
389  {
391  reference(BaseMultiReduceBitAnd const& base, size_t bin)
392  : m_base(base),
393  m_bin(bin)
394  {}
395 
398  reference const& operator&=(value_type rhs) const
399  {
400  m_base.combine(m_bin, rhs);
401  return *this;
402  }
403 
404  value_type get() const { return m_base.get(m_bin); }
405 
406  private:
407  BaseMultiReduceBitAnd const& m_base;
408  size_t m_bin;
409  };
410 };
411 
412 } // namespace detail
413 
414 } // namespace reduce
415 
416 } // namespace RAJA
417 
418 #endif /* RAJA_PATTERN_DETAIL_MULTI_REDUCE_HPP */
Header file for RAJA operator definitions.
Header file for RAJA RepeatView constructs.
Bitwise AND reducer class template.
Definition: multi_reduce.hpp:372
BaseMultiReduceBitAnd & operator=(BaseMultiReduceBitAnd const &)=delete
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduceBitAnd()=default
BaseMultiReduceBitAnd & operator=(BaseMultiReduceBitAnd &&)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceBitAnd(BaseMultiReduceBitAnd const &)=default
RAJA_SUPPRESS_HD_WARN BaseMultiReduceBitAnd(BaseMultiReduceBitAnd &&)=default
Bitwise OR reducer class template.
Definition: multi_reduce.hpp:323
BaseMultiReduceBitOr & operator=(BaseMultiReduceBitOr const &)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceBitOr(BaseMultiReduceBitOr &&)=default
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduceBitOr()=default
BaseMultiReduceBitOr & operator=(BaseMultiReduceBitOr &&)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceBitOr(BaseMultiReduceBitOr const &)=default
Max reducer class template.
Definition: multi_reduce.hpp:225
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMax(BaseMultiReduceMax const &)=default
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduceMax()=default
BaseMultiReduceMax & operator=(BaseMultiReduceMax const &)=delete
BaseMultiReduceMax & operator=(BaseMultiReduceMax &&)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMax(BaseMultiReduceMax &&)=default
Min reducer class template.
Definition: multi_reduce.hpp:175
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMin(BaseMultiReduceMin &&)=default
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduceMin()=default
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMin & operator=(BaseMultiReduceMin &&)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMin(BaseMultiReduceMin const &)=default
RAJA_SUPPRESS_HD_WARN BaseMultiReduceMin & operator=(BaseMultiReduceMin const &)=delete
Sum reducer class template.
Definition: multi_reduce.hpp:274
RAJA_SUPPRESS_HD_WARN BaseMultiReduceSum(BaseMultiReduceSum &&)=default
BaseMultiReduceSum & operator=(BaseMultiReduceSum &&)=delete
BaseMultiReduceSum & operator=(BaseMultiReduceSum const &)=delete
RAJA_SUPPRESS_HD_WARN BaseMultiReduceSum(BaseMultiReduceSum const &)=default
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduceSum()=default
Header file for common RAJA internal macro definitions.
RAJA_HOST_DEVICE RAJA_INLINE void RAJA_UNUSED_VAR(T &&...) noexcept
Definition: macros.hpp:120
RAJA_HOST_DEVICE void RAJA_ABORT_OR_THROW(const char *str)
Definition: macros.hpp:143
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
#define RAJA_SUPPRESS_HD_WARN
Definition: macros.hpp:68
Definition: AlignedRangeIndexSetBuilders.cpp:35
Internal header for RAJA forall "BED" macros (i.e., loop bounds 'BED' --> begin, end,...
#define RAJA_EXTRACT_BED_IT(CONTAINER)
Definition: forall.hpp:32
A view of a single object repeated a certain number of times.
Definition: RepeatView.hpp:57
RAJA_HOST_DEVICE reference const & operator&=(value_type rhs) const
reducer function; updates the current instance's state
Definition: multi_reduce.hpp:398
value_type get() const
Definition: multi_reduce.hpp:404
RAJA_HOST_DEVICE reference(BaseMultiReduceBitAnd const &base, size_t bin)
Definition: multi_reduce.hpp:391
RAJA_HOST_DEVICE reference(BaseMultiReduceBitOr const &base, size_t bin)
Definition: multi_reduce.hpp:342
value_type get() const
Definition: multi_reduce.hpp:355
RAJA_HOST_DEVICE reference const & operator|=(value_type rhs) const
reducer function; updates the current instance's state
Definition: multi_reduce.hpp:349
RAJA_HOST_DEVICE reference const & max(value_type rhs) const
reducer function; updates the current instance's state
Definition: multi_reduce.hpp:251
value_type get() const
Definition: multi_reduce.hpp:257
RAJA_HOST_DEVICE reference(BaseMultiReduceMax const &base, size_t bin)
Definition: multi_reduce.hpp:244
RAJA_HOST_DEVICE reference const & min(value_type rhs) const
reducer function; updates the current instance's state
Definition: multi_reduce.hpp:202
value_type get() const
Definition: multi_reduce.hpp:208
RAJA_HOST_DEVICE reference(BaseMultiReduceMin const &base, size_t bin)
Definition: multi_reduce.hpp:195
RAJA_HOST_DEVICE reference(BaseMultiReduceSum const &base, size_t bin)
Definition: multi_reduce.hpp:293
value_type get() const
Definition: multi_reduce.hpp:306
RAJA_HOST_DEVICE reference const & operator+=(value_type rhs) const
reducer function; updates the current instance's state
Definition: multi_reduce.hpp:300
Definition: multi_reduce.hpp:67
RAJA_SUPPRESS_HD_WARN BaseMultiReduce(BaseMultiReduce &&)=default
void get_all(Container &container) const
Get the calculated reduced value for each bin and store it in container.
Definition: multi_reduce.hpp:146
void reset(Container const &container, value_type identity=MultiReduceOp::identity())
Definition: multi_reduce.hpp:116
void reset()
Definition: multi_reduce.hpp:102
BaseMultiReduce(Container const &container, value_type identity=MultiReduceOp::identity())
Definition: multi_reduce.hpp:88
t_MultiReduceData MultiReduceData
Definition: multi_reduce.hpp:68
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE BaseMultiReduce const & combine(size_t bin, value_type const &other) const
Definition: multi_reduce.hpp:134
value_type get(size_t bin) const
Get the calculated reduced value for a bin.
Definition: multi_reduce.hpp:141
void reset(size_t num_bins, value_type init_val=MultiReduceOp::identity(), value_type identity=MultiReduceOp::identity())
Definition: multi_reduce.hpp:107
typename t_MultiReduceData::value_type value_type
Definition: multi_reduce.hpp:70
BaseMultiReduce()
Definition: multi_reduce.hpp:72
BaseMultiReduce & operator=(BaseMultiReduce const &)=delete
BaseMultiReduce(size_t num_bins, value_type init_val=MultiReduceOp::identity(), value_type identity=MultiReduceOp::identity())
Definition: multi_reduce.hpp:76
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE size_t size() const
Definition: multi_reduce.hpp:129
RAJA_SUPPRESS_HD_WARN BaseMultiReduce(BaseMultiReduce const &)=default
RAJA_SUPPRESS_HD_WARN ~BaseMultiReduce()=default
typename t_MultiReduceData::MultiReduceOp MultiReduceOp
Definition: multi_reduce.hpp:69
BaseMultiReduce & operator=(BaseMultiReduce &&)=delete
Header file for RAJA type definitions.