RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
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_REDUCE_HPP
21 #define RAJA_PATTERN_DETAIL_REDUCE_HPP
22 
23 #include "RAJA/util/Operators.hpp"
24 #include "RAJA/util/types.hpp"
25 
26 #define RAJA_DECLARE_REDUCER(OP, POL, COMBINER) \
27  template<typename T> \
28  class Reduce##OP<POL, T> \
29  : public reduce::detail::BaseReduce##OP<T, COMBINER> \
30  { \
31  public: \
32  using Base = reduce::detail::BaseReduce##OP<T, COMBINER>; \
33  using Base::Base; \
34  };
35 
36 #define RAJA_DECLARE_INDEX_REDUCER(OP, POL, COMBINER) \
37  template<typename T, typename IndexType> \
38  class Reduce##OP<POL, T, IndexType> \
39  : public reduce::detail::BaseReduce##OP<T, IndexType, COMBINER> \
40  { \
41  public: \
42  using Base = reduce::detail::BaseReduce##OP<T, IndexType, COMBINER>; \
43  using Base::Base; \
44  };
45 
46 #define RAJA_DECLARE_ALL_REDUCERS(POL, COMBINER) \
47  RAJA_DECLARE_REDUCER(Sum, POL, COMBINER) \
48  RAJA_DECLARE_REDUCER(Min, POL, COMBINER) \
49  RAJA_DECLARE_REDUCER(Max, POL, COMBINER) \
50  RAJA_DECLARE_INDEX_REDUCER(MinLoc, POL, COMBINER) \
51  RAJA_DECLARE_INDEX_REDUCER(MaxLoc, POL, COMBINER) \
52  RAJA_DECLARE_REDUCER(BitOr, POL, COMBINER) \
53  RAJA_DECLARE_REDUCER(BitAnd, POL, COMBINER)
54 
55 namespace RAJA
56 {
57 
58 namespace reduce
59 {
60 
61 #if defined(RAJA_ENABLE_TARGET_OPENMP)
62 #pragma omp declare target
63 #endif
64 
65 namespace detail
66 {
67 
68 template<typename T, template<typename...> class Op>
69 struct op_adapter : private Op<T, T, T>
70 {
71  using operator_type = Op<T, T, T>;
72 
73  RAJA_HOST_DEVICE static constexpr T identity()
74  {
75  return operator_type::identity();
76  }
77 
78  RAJA_HOST_DEVICE RAJA_INLINE void operator()(T& val, const T v) const
79  {
80  val = operator_type::operator()(val, v);
81  }
82 };
83 } // namespace detail
84 
85 template<typename T>
86 struct sum : detail::op_adapter<T, RAJA::operators::plus>
87 {};
88 
89 template<typename T>
90 struct min : detail::op_adapter<T, RAJA::operators::minimum>
91 {};
92 
93 template<typename T>
94 struct max : detail::op_adapter<T, RAJA::operators::maximum>
95 {};
96 
97 template<typename T>
98 struct or_bit : detail::op_adapter<T, RAJA::operators::bit_or>
99 {};
100 
101 template<typename T>
102 struct and_bit : detail::op_adapter<T, RAJA::operators::bit_and>
103 {};
104 
105 
106 #if defined(RAJA_ENABLE_TARGET_OPENMP)
107 #pragma omp end declare target
108 #endif
109 
110 namespace detail
111 {
112 
113 template<typename T, bool = std::is_integral<T>::value>
115 {};
116 
117 template<typename T>
118 struct DefaultLoc<T, false> // any non-integral type
119 {
120  RAJA_HOST_DEVICE constexpr T value() const { return T(); }
121 };
122 
123 template<typename T>
124 struct DefaultLoc<T, true>
125 {
126  RAJA_HOST_DEVICE constexpr T value() const { return -1; }
127 };
128 
129 template<typename T, typename IndexType, bool doing_min = true>
130 class ValueLoc
131 {
132 public:
133  T val = doing_min ? operators::limits<T>::max() : operators::limits<T>::min();
134  IndexType loc = DefaultLoc<IndexType>().value();
135 
136 #if __NVCC__ && defined(CUDART_VERSION) && CUDART_VERSION < 9020 || \
137  defined(__HIPCC__)
138  RAJA_HOST_DEVICE constexpr ValueLoc() {}
139 
140  RAJA_HOST_DEVICE constexpr ValueLoc(ValueLoc const& other)
141  : val {other.val},
142  loc {other.loc}
143  {}
144 
146  ValueLoc& operator=(ValueLoc const& other)
147  {
148  val = other.val;
149  loc = other.loc;
150  return *this;
151  }
152 #else
153  constexpr ValueLoc() = default;
154  constexpr ValueLoc(ValueLoc const&) = default;
155  ValueLoc& operator=(ValueLoc const&) = default;
156 #endif
157 
158  RAJA_HOST_DEVICE constexpr ValueLoc(T const& val_)
159  : val {val_},
160  loc {DefaultLoc<IndexType>().value()}
161  {}
162 
163  RAJA_HOST_DEVICE constexpr ValueLoc(T const& val_, IndexType const& loc_)
164  : val {val_},
165  loc {loc_}
166  {}
167 
168  RAJA_HOST_DEVICE operator T() const { return val; }
169 
170  RAJA_HOST_DEVICE IndexType getLoc() { return loc; }
171 
172  RAJA_HOST_DEVICE bool operator<(ValueLoc const& rhs) const
173  {
174  return val < rhs.val;
175  }
176 
177  RAJA_HOST_DEVICE bool operator>(ValueLoc const& rhs) const
178  {
179  return val > rhs.val;
180  }
181 };
182 
183 } // namespace detail
184 
185 } // namespace reduce
186 
187 namespace operators
188 {
189 template<typename T, typename IndexType, bool B>
190 struct limits<::RAJA::reduce::detail::ValueLoc<T, IndexType, B>>
191 {
192  RAJA_INLINE RAJA_HOST_DEVICE static constexpr ::RAJA::reduce::detail::
193  ValueLoc<T, IndexType, B>
194  min()
195  {
196  return ::RAJA::reduce::detail::ValueLoc<T, IndexType, B>(limits<T>::min());
197  }
198 
199  RAJA_INLINE RAJA_HOST_DEVICE static constexpr ::RAJA::reduce::detail::
200  ValueLoc<T, IndexType, B>
201  max()
202  {
203  return ::RAJA::reduce::detail::ValueLoc<T, IndexType, B>(limits<T>::max());
204  }
205 };
206 } // namespace operators
207 
208 namespace reduce
209 {
210 
211 namespace detail
212 {
213 
214 template<typename T,
215  template<typename> class Reduce_,
216  template<typename, typename> class Combiner_>
218 {
219  using Reduce = Reduce_<T>;
220  // NOTE: the _t here is to appease MSVC
221  using Combiner_t = Combiner_<T, Reduce>;
222  Combiner_t mutable c;
223 
224 public:
225  using value_type = T;
226  using reduce_type = Reduce;
227 
229 
231  BaseReduce() : c {T(), Reduce::identity()} {}
232 
234 
236  BaseReduce(T init_val, T identity_ = Reduce::identity())
237  : c {init_val, identity_}
238  {}
239 
241 
243  void reset(T val, T identity_ = Reduce::identity())
244  {
245  operator T(); // automatic get() before reset
246  c.reset(val, identity_);
247  }
248 
250  BaseReduce& operator=(const BaseReduce&) = delete;
251 
254 
256  BaseReduce(const BaseReduce& copy) : c(copy.c) {}
257 
261 
262  RAJA_INLINE
263  BaseReduce(BaseReduce&& copy) : c(std::move(copy.c)) {}
264 
267 
269 
271  void combine(T const& other) const { c.combine(other); }
272 
273  T& local() const { return c.local(); }
274 
276  operator T() const { return c.get(); }
277 
279  T get() const { return c.get(); }
280 };
281 
282 template<typename T, typename Reduce, typename Derived>
284 {
285 protected:
286  BaseCombinable const* parent = nullptr;
288  T mutable my_data;
289 
290 public:
292 
294  constexpr BaseCombinable() : identity {T()}, my_data {T()} {}
295 
297 
299  constexpr BaseCombinable(T init_val, T identity_ = T())
300  : identity {identity_},
301  my_data {init_val}
302  {}
303 
305 
307  void reset(T init_val, T identity_)
308  {
309  my_data = init_val;
310  identity = identity_;
311  }
312 
314 
316  constexpr BaseCombinable(BaseCombinable const& other)
317  : parent {other.parent ? other.parent : &other},
318  identity {other.identity},
319  my_data {identity}
320  {}
321 
323 
326  {
327  if (parent && my_data != identity)
328  {
330  }
331  }
332 
334 
336  void combine(T const& other) { Reduce {}(my_data, other); }
337 
341  T get() const { return derived().get_combined(); }
342 
346  T& local() const { return my_data; }
347 
348  T get_combined() const { return my_data; }
349 
350 private:
351  // Convenience method for CRTP
352  const Derived& derived() const
353  {
354  return *(static_cast<const Derived*>(this));
355  }
356 
357  Derived& derived() { return *(static_cast<Derived*>(this)); }
358 };
359 
367 template<typename T, template<typename, typename> class Combiner>
368 class BaseReduceMin : public BaseReduce<T, RAJA::reduce::min, Combiner>
369 {
370 public:
372  using Base::Base;
373 
376  const BaseReduceMin& min(T rhs) const
377  {
378  this->combine(rhs);
379  return *this;
380  }
381 };
382 
390 template<typename T,
391  typename IndexType,
392  template<typename, typename> class Combiner>
394  : public BaseReduce<ValueLoc<T, IndexType>, RAJA::reduce::min, Combiner>
395 {
396 public:
398  using value_type = typename Base::value_type;
399  using reduce_type = typename Base::reduce_type;
400  using Base::Base;
401 
402  constexpr BaseReduceMinLoc() : Base(value_type(T(), IndexType())) {}
403 
404  constexpr BaseReduceMinLoc(
405  T init_val,
406  IndexType init_idx,
407  T identity_val_ = reduce_type::identity(),
408  IndexType identity_loc_ = DefaultLoc<IndexType>().value())
409  : Base(value_type(init_val, init_idx),
410  value_type(identity_val_, identity_loc_))
411  {}
412 
413  void reset(T init_val,
414  IndexType init_idx,
415  T identity_val_ = reduce_type::identity(),
416  IndexType identity_loc_ = DefaultLoc<IndexType>().value())
417  {
418  operator T(); // automatic get() before reset
419  Base::reset(value_type(init_val, init_idx),
420  value_type(identity_val_, identity_loc_));
421  }
422 
425  const BaseReduceMinLoc& minloc(T rhs, IndexType loc) const
426  {
427  this->combine(value_type(rhs, loc));
428  return *this;
429  }
430 
432  IndexType getLoc() const { return Base::get().getLoc(); }
433 
435  operator T() const { return Base::get(); }
436 };
437 
445 template<typename T, template<typename, typename> class Combiner>
446 class BaseReduceMax : public BaseReduce<T, RAJA::reduce::max, Combiner>
447 {
448 public:
450  using Base::Base;
451 
454  const BaseReduceMax& max(T rhs) const
455  {
456  this->combine(rhs);
457  return *this;
458  }
459 };
460 
468 template<typename T, template<typename, typename> class Combiner>
469 class BaseReduceSum : public BaseReduce<T, RAJA::reduce::sum, Combiner>
470 {
471 public:
473  using Base::Base;
474 
477 
479  const BaseReduceSum& operator+=(T rhs) const
480  {
481  this->combine(rhs);
482  return *this;
483  }
484 };
485 
493 template<typename T, template<typename, typename> class Combiner>
494 class BaseReduceBitOr : public BaseReduce<T, RAJA::reduce::or_bit, Combiner>
495 {
496 public:
498  using Base::Base;
499 
502 
504  const BaseReduceBitOr& operator|=(T rhs) const
505  {
506  this->combine(rhs);
507  return *this;
508  }
509 };
510 
518 template<typename T, template<typename, typename> class Combiner>
519 class BaseReduceBitAnd : public BaseReduce<T, RAJA::reduce::and_bit, Combiner>
520 {
521 public:
523  using Base::Base;
524 
527 
529  const BaseReduceBitAnd& operator&=(T rhs) const
530  {
531  this->combine(rhs);
532  return *this;
533  }
534 };
535 
543 template<typename T,
544  typename IndexType,
545  template<typename, typename> class Combiner>
546 class BaseReduceMaxLoc : public BaseReduce<ValueLoc<T, IndexType, false>,
547  RAJA::reduce::max,
548  Combiner>
549 {
550 public:
551  using Base =
553  using value_type = typename Base::value_type;
554  using reduce_type = typename Base::reduce_type;
555  using Base::Base;
556 
557  constexpr BaseReduceMaxLoc() : Base(value_type(T(), IndexType())) {}
558 
559  constexpr BaseReduceMaxLoc(
560  T init_val,
561  IndexType init_idx,
562  T identity_val_ = reduce_type::identity(),
563  IndexType identity_loc_ = DefaultLoc<IndexType>().value())
564  : Base(value_type(init_val, init_idx),
565  value_type(identity_val_, identity_loc_))
566  {}
567 
568  void reset(T init_val,
569  IndexType init_idx,
570  T identity_val_ = reduce_type::identity(),
571  IndexType identity_loc_ = DefaultLoc<IndexType>().value())
572  {
573  operator T(); // automatic get() before reset
574  Base::reset(value_type(init_val, init_idx),
575  value_type(identity_val_, identity_loc_));
576  }
577 
580  const BaseReduceMaxLoc& maxloc(T rhs, IndexType loc) const
581  {
582  this->combine(value_type(rhs, loc));
583  return *this;
584  }
585 
587  IndexType getLoc() const { return Base::get().getLoc(); }
588 
590  operator T() const { return Base::get(); }
591 };
592 
593 } // namespace detail
594 
595 } // namespace reduce
596 
597 } // namespace RAJA
598 
599 #endif /* RAJA_PATTERN_DETAIL_REDUCE_HPP */
Header file for RAJA operator definitions.
Definition: reduce.hpp:284
RAJA_SUPPRESS_HD_WARN constexpr RAJA_HOST_DEVICE BaseCombinable()
Definition: reduce.hpp:294
RAJA_SUPPRESS_HD_WARN constexpr RAJA_HOST_DEVICE BaseCombinable(BaseCombinable const &other)
Definition: reduce.hpp:316
T get() const
Definition: reduce.hpp:341
T identity
Definition: reduce.hpp:287
RAJA_SUPPRESS_HD_WARN constexpr RAJA_HOST_DEVICE BaseCombinable(T init_val, T identity_=T())
Definition: reduce.hpp:299
T my_data
Definition: reduce.hpp:288
T get_combined() const
Definition: reduce.hpp:348
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE ~BaseCombinable()
Definition: reduce.hpp:325
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE void reset(T init_val, T identity_)
Definition: reduce.hpp:307
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE void combine(T const &other)
Definition: reduce.hpp:336
BaseCombinable const * parent
Definition: reduce.hpp:286
T & local() const
Definition: reduce.hpp:346
Bitwise AND reducer class template.
Definition: reduce.hpp:520
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE const BaseReduceBitAnd & operator&=(T rhs) const
reducer function; updates the current instance's state
Definition: reduce.hpp:529
Bitwise OR reducer class template.
Definition: reduce.hpp:495
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE const BaseReduceBitOr & operator|=(T rhs) const
reducer function; updates the current instance's state
Definition: reduce.hpp:504
MaxLoc reducer class template.
Definition: reduce.hpp:549
void reset(T init_val, IndexType init_idx, T identity_val_=reduce_type::identity(), IndexType identity_loc_=DefaultLoc< IndexType >().value())
Definition: reduce.hpp:568
constexpr BaseReduceMaxLoc()
Definition: reduce.hpp:557
typename Base::value_type value_type
Definition: reduce.hpp:553
constexpr BaseReduceMaxLoc(T init_val, IndexType init_idx, T identity_val_=reduce_type::identity(), IndexType identity_loc_=DefaultLoc< IndexType >().value())
Definition: reduce.hpp:559
typename Base::reduce_type reduce_type
Definition: reduce.hpp:554
RAJA_HOST_DEVICE const BaseReduceMaxLoc & maxloc(T rhs, IndexType loc) const
reducer function; updates the current instance's state
Definition: reduce.hpp:580
IndexType getLoc() const
Get the calculated reduced value.
Definition: reduce.hpp:587
Max reducer class template.
Definition: reduce.hpp:447
RAJA_HOST_DEVICE const BaseReduceMax & max(T rhs) const
reducer function; updates the current instance's state
Definition: reduce.hpp:454
MinLoc reducer class template.
Definition: reduce.hpp:395
IndexType getLoc() const
Get the calculated reduced value.
Definition: reduce.hpp:432
typename Base::value_type value_type
Definition: reduce.hpp:398
typename Base::reduce_type reduce_type
Definition: reduce.hpp:399
void reset(T init_val, IndexType init_idx, T identity_val_=reduce_type::identity(), IndexType identity_loc_=DefaultLoc< IndexType >().value())
Definition: reduce.hpp:413
constexpr BaseReduceMinLoc()
Definition: reduce.hpp:402
constexpr BaseReduceMinLoc(T init_val, IndexType init_idx, T identity_val_=reduce_type::identity(), IndexType identity_loc_=DefaultLoc< IndexType >().value())
Definition: reduce.hpp:404
RAJA_HOST_DEVICE const BaseReduceMinLoc & minloc(T rhs, IndexType loc) const
reducer function; updates the current instance's state
Definition: reduce.hpp:425
Min reducer class template.
Definition: reduce.hpp:369
RAJA_HOST_DEVICE const BaseReduceMin & min(T rhs) const
reducer function; updates the current instance's state
Definition: reduce.hpp:376
Sum reducer class template.
Definition: reduce.hpp:470
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE const BaseReduceSum & operator+=(T rhs) const
reducer function; updates the current instance's state
Definition: reduce.hpp:479
Definition: reduce.hpp:218
BaseReduce & operator=(BaseReduce &&)=default
compiler-generated move assignment
T value_type
Definition: reduce.hpp:225
BaseReduce & operator=(const BaseReduce &)=delete
prohibit compiler-generated copy assignment
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE BaseReduce(T init_val, T identity_=Reduce::identity())
Definition: reduce.hpp:236
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE BaseReduce()
Definition: reduce.hpp:231
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE BaseReduce(const BaseReduce &copy)
compiler-generated copy constructor
Definition: reduce.hpp:256
T & local() const
Definition: reduce.hpp:273
T get() const
Get the calculated reduced value.
Definition: reduce.hpp:279
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE void reset(T val, T identity_=Reduce::identity())
Definition: reduce.hpp:243
Reduce reduce_type
Definition: reduce.hpp:226
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE RAJA_INLINE BaseReduce(BaseReduce &&copy)
compiler-generated move constructor
Definition: reduce.hpp:263
RAJA_SUPPRESS_HD_WARN RAJA_HOST_DEVICE void combine(T const &other) const
Definition: reduce.hpp:271
Definition: reduce.hpp:131
constexpr ValueLoc()=default
constexpr RAJA_HOST_DEVICE ValueLoc(T const &val_, IndexType const &loc_)
Definition: reduce.hpp:163
T val
Definition: reduce.hpp:133
constexpr ValueLoc(ValueLoc const &)=default
RAJA_HOST_DEVICE bool operator>(ValueLoc const &rhs) const
Definition: reduce.hpp:177
IndexType loc
Definition: reduce.hpp:134
constexpr RAJA_HOST_DEVICE ValueLoc(T const &val_)
Definition: reduce.hpp:158
RAJA_HOST_DEVICE bool operator<(ValueLoc const &rhs) const
Definition: reduce.hpp:172
ValueLoc & operator=(ValueLoc const &)=default
RAJA_HOST_DEVICE IndexType getLoc()
Definition: reduce.hpp:170
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
#define RAJA_SUPPRESS_HD_WARN
Definition: macros.hpp:68
constexpr auto Reduce(T *target)
Definition: reducer.hpp:231
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result min(Args... args)
Definition: foldl.hpp:161
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result max(Args... args)
Definition: foldl.hpp:155
Definition: ListSegment.hpp:416
RAJA_INLINE static RAJA_HOST_DEVICE constexpr ::RAJA::reduce::detail::ValueLoc< T, IndexType, B > max()
Definition: reduce.hpp:201
RAJA_INLINE static RAJA_HOST_DEVICE constexpr ::RAJA::reduce::detail::ValueLoc< T, IndexType, B > min()
Definition: reduce.hpp:194
Definition: Operators.hpp:250
Definition: reduce.hpp:103
constexpr RAJA_HOST_DEVICE T value() const
Definition: reduce.hpp:120
constexpr RAJA_HOST_DEVICE T value() const
Definition: reduce.hpp:126
Definition: reduce.hpp:115
Definition: reduce.hpp:70
RAJA_HOST_DEVICE RAJA_INLINE void operator()(T &val, const T v) const
Definition: reduce.hpp:78
Op< T, T, T > operator_type
Definition: reduce.hpp:71
static constexpr RAJA_HOST_DEVICE T identity()
Definition: reduce.hpp:73
Definition: reduce.hpp:95
Definition: reduce.hpp:91
Definition: reduce.hpp:99
Definition: reduce.hpp:87
Header file for RAJA type definitions.