20 #ifndef RAJA_util_reduce_HPP
21 #define RAJA_util_reduce_HPP
23 #include "RAJA/config.hpp"
28 #include <type_traits>
43 template<
typename T,
typename BinaryOp>
47 T init = BinaryOp::identity(),
48 BinaryOp op = BinaryOp {}) noexcept
49 : m_storage(std::move(op), std::move(init))
56 T init = BinaryOp::identity()) noexcept
58 m_storage.m_accumulated_value = std::move(init);
65 T init = BinaryOp::identity())
69 reset(std::move(init));
79 return m_storage.m_accumulated_value;
87 m_storage.m_accumulated_value = m_storage.get_op()(
88 std::move(m_storage.m_accumulated_value), std::move(value));
102 struct Storage : BinaryOp
104 T m_accumulated_value;
107 : BinaryOp(
std::move(op)),
108 m_accumulated_value(
std::move(init))
131 typename SizeType = size_t,
132 SizeType t_num_levels = CHAR_BIT *
sizeof(SizeType)>
135 static_assert(std::is_unsigned<SizeType>::value,
"SizeType must be unsigned");
137 t_num_levels <= CHAR_BIT *
sizeof(SizeType),
138 "SizeType must be large enough to act at a bitset for num_levels");
140 static constexpr SizeType num_levels = t_num_levels;
143 T init = BinaryOp::identity(),
144 BinaryOp op = BinaryOp {}) noexcept
145 : m_storage(std::move(op))
147 combine(std::move(init));
154 T init = BinaryOp::identity()) noexcept
156 m_storage.m_count = 0;
158 combine(std::move(init));
165 T init = BinaryOp::identity())
169 reset(std::move(init));
180 T value = BinaryOp::identity();
182 for (SizeType count = m_storage.m_count, level = 0, mask = 1; count;
188 m_storage.get_op()(std::move(value), m_storage.m_tree_stack[level]);
205 for (SizeType mask = 1; m_storage.m_count & mask; ++level, mask <<= 1)
207 value = m_storage.get_op()(std::move(m_storage.m_tree_stack[level]),
211 m_storage.m_tree_stack[level] = std::move(value);
221 combine(std::move(value));
227 struct Storage : BinaryOp
231 SizeType m_count = 0;
235 T m_tree_stack[num_levels];
238 : BinaryOp(
std::move(op))
276 static_assert(std::is_floating_point_v<T>,
"T must be a floating point type");
279 T init = T()) noexcept
280 : m_accumulated_value(
std::move(init)),
281 m_accumulated_carry(T())
289 m_accumulated_value = std::move(init);
290 m_accumulated_carry = T();
300 reset(std::move(init));
310 return m_accumulated_value;
321 T
y = val - m_accumulated_carry;
322 T t = m_accumulated_value +
y;
323 T
z = t - m_accumulated_value;
324 m_accumulated_carry =
z -
y;
325 m_accumulated_value = t;
332 T
y = val - m_accumulated_carry;
333 volatile T t = m_accumulated_value +
y;
334 volatile T
z = t - m_accumulated_value;
335 m_accumulated_carry =
z -
y;
336 m_accumulated_value = t;
349 T m_accumulated_value;
350 T m_accumulated_carry;
353 template<
typename T,
typename BinaryOp>
355 std::conditional_t<RAJA::operators::is_fp_associative<T>::value,
364 template<
typename Container,
368 enable_if_t<T, type_traits::is_range<Container>>
370 T init = BinaryOp::identity(),
371 BinaryOp op = BinaryOp {})
375 static_assert(type_traits::is_binary_function<BinaryOp, T, T, T>::value,
376 "BinaryOp must model BinaryFunction");
378 auto begin_it = begin(c);
379 auto end_it = end(c);
381 LeftFoldReduce<T, BinaryOp> reducer(std::move(init), std::move(op));
383 for (; begin_it != end_it; ++begin_it)
385 reducer.combine(*begin_it);
388 return reducer.get_and_reset();
396 template<
typename Container,
397 typename T = detail::ContainerVal<Container>,
398 typename BinaryOp = operators::plus<T>>
400 enable_if_t<T, type_traits::is_range<Container>>
402 T init = BinaryOp::identity(),
403 BinaryOp op = BinaryOp {})
408 static_assert(type_traits::is_binary_function<BinaryOp, T, T, T>::value,
409 "BinaryOp must model BinaryFunction");
411 auto begin_it = begin(c);
412 auto end_it = end(c);
413 using SizeType = std::make_unsigned_t<decltype(distance(begin_it, end_it))>;
415 BinaryTreeReduce<T, BinaryOp, SizeType> reducer(std::move(init),
418 for (; begin_it != end_it; ++begin_it)
420 reducer.combine(*begin_it);
423 return reducer.get_and_reset();
431 template<
typename Container,
typename T = detail::ContainerVal<Container>>
433 enable_if_t<T, type_traits::is_range<Container>, std::is_floating_point<T>>
439 auto begin_it = begin(c);
440 auto end_it = end(c);
444 for (; begin_it != end_it; ++begin_it)
459 template<
typename Container,
typename T = detail::ContainerVal<Container>>
461 enable_if_t<T, type_traits::is_range<Container>, std::is_floating_point<T>>
467 auto begin_it = begin(c);
468 auto end_it = end(c);
472 for (; begin_it != end_it; ++begin_it)
486 template<
typename Container,
487 typename T = detail::ContainerVal<Container>,
488 typename BinaryOp = operators::plus<T>>
490 enable_if_t<T, type_traits::is_range<Container>>
492 T init = BinaryOp::identity(),
493 BinaryOp op = BinaryOp {})
497 static_assert(type_traits::is_binary_function<BinaryOp, T, T, T>::value,
498 "BinaryOp must model BinaryFunction");
500 auto begin_it = begin(c);
501 auto end_it = end(c);
503 HighAccuracyReduce<T, BinaryOp> reducer(std::move(init), std::move(op));
505 for (; begin_it != end_it; ++begin_it)
507 reducer.combine(*begin_it);
510 return reducer.get_and_reset();
518 template<
typename Container,
519 typename T = detail::ContainerVal<Container>,
520 typename BinaryOp = operators::plus<T>>
522 enable_if_t<T, type_traits::is_range<Container>>
524 T init = BinaryOp::identity(),
525 BinaryOp op = BinaryOp {})
529 static_assert(type_traits::is_binary_function<BinaryOp, T, T, T>::value,
530 "BinaryOp must model BinaryFunction");
532 auto begin_it = begin(c);
533 auto end_it = end(c);
535 LeftFoldReduce<T, BinaryOp> reducer(std::move(init), std::move(op));
537 for (; begin_it != end_it; ++begin_it)
539 reducer.combine(*begin_it);
542 return reducer.get_and_reset();
Header file for RAJA operator definitions.
Header file for RAJA algorithm definitions.
Header file for RAJA concept definitions.
Header file for common RAJA internal macro definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
Header file providing RAJA math templates.
camp::decay< decltype(*camp::val< camp::iterator_from< Container > >())> ContainerVal
Definition: algorithm.hpp:51
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container > > high_accuracy_reduce(Container &&c, T init=BinaryOp::identity(), BinaryOp op=BinaryOp {})
Reduce given range to a single value using an algorithm with high accuracy when floating point round ...
Definition: reduce.hpp:491
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container > > left_fold_reduce(Container &&c, T init=BinaryOp::identity(), BinaryOp op=BinaryOp {})
Accumulate given range to a single value using a left fold algorithm in O(N) operations and O(1) extr...
Definition: reduce.hpp:369
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container > > accumulate(Container &&c, T init=BinaryOp::identity(), BinaryOp op=BinaryOp {})
Accumulate given range to a single value using a left fold algorithm in O(N) operations and O(1) extr...
Definition: reduce.hpp:523
KahanSumImplementation
Definition: reduce.hpp:257
RAJA_HOST_DEVICE constexpr RAJA_INLINE RAJA::zip_tuple_element_t< I, zip_tuple< is_val, Ts... > > & get(zip_tuple< is_val, Ts... > &z) noexcept
Definition: zip_tuple.hpp:56
std::conditional_t< RAJA::operators::is_fp_associative< T >::value, BinaryTreeReduce< T, BinaryOp >, LeftFoldReduce< T, BinaryOp > > HighAccuracyReduce
Definition: reduce.hpp:357
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container > > binary_tree_reduce(Container &&c, T init=BinaryOp::identity(), BinaryOp op=BinaryOp {})
Reduce given range to a single value using a binary tree algorithm in O(N) operations and O(lg(N)) ex...
Definition: reduce.hpp:401
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container >, std::is_floating_point< T > > kahan_sum_volatile(Container &&c, T init=T())
Accumulate given range to a single value using a kahan summation algorithm in O(N) operations and O(1...
Definition: reduce.hpp:462
RAJA_HOST_DEVICE constexpr RAJA_INLINE concepts::enable_if_t< T, type_traits::is_range< Container >, std::is_floating_point< T > > kahan_sum(Container &&c, T init=T())
Accumulate given range to a single value using a kahan summation algorithm in O(N) operations and O(1...
Definition: reduce.hpp:434
Definition: ListSegment.hpp:416
Reduce class that does a reduction with a binary tree.
Definition: reduce.hpp:134
RAJA_HOST_DEVICE constexpr RAJA_INLINE void operator+=(T value)
combine a value into the reducer
Definition: reduce.hpp:219
RAJA_HOST_DEVICE constexpr RAJA_INLINE BinaryTreeReduce(T init=BinaryOp::identity(), BinaryOp op=BinaryOp {}) noexcept
Definition: reduce.hpp:142
RAJA_HOST_DEVICE constexpr RAJA_INLINE void reset(T init=BinaryOp::identity()) noexcept
reset the combined value of the reducer to the identity
Definition: reduce.hpp:153
RAJA_HOST_DEVICE constexpr RAJA_INLINE void combine(T value)
combine a value into the reducer
Definition: reduce.hpp:200
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get_and_reset(T init=BinaryOp::identity())
return the combined value and reset the reducer
Definition: reduce.hpp:164
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get() const
return the combined value
Definition: reduce.hpp:177
Reduce class that does a reduction with a left fold.
Definition: reduce.hpp:275
RAJA_HOST_DEVICE constexpr RAJA_INLINE KahanSum(T init=T()) noexcept
Definition: reduce.hpp:278
RAJA_HOST_DEVICE constexpr RAJA_INLINE void reset(T init=T()) noexcept
reset the combined value of the reducer to the identity
Definition: reduce.hpp:287
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get_and_reset(T init=T())
return the combined value and reset the reducer
Definition: reduce.hpp:296
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get() const
return the combined value
Definition: reduce.hpp:308
RAJA_HOST_DEVICE constexpr RAJA_INLINE void combine(T val)
combine a value into the reducer
Definition: reduce.hpp:316
RAJA_HOST_DEVICE constexpr RAJA_INLINE void operator+=(T val)
combine a value into the reducer
Definition: reduce.hpp:343
Reduce class that does a reduction with a left fold.
Definition: reduce.hpp:45
RAJA_HOST_DEVICE constexpr RAJA_INLINE LeftFoldReduce(T init=BinaryOp::identity(), BinaryOp op=BinaryOp {}) noexcept
Definition: reduce.hpp:46
RAJA_HOST_DEVICE constexpr RAJA_INLINE void reset(T init=BinaryOp::identity()) noexcept
reset the combined value of the reducer to the identity
Definition: reduce.hpp:55
RAJA_HOST_DEVICE constexpr RAJA_INLINE void combine(T value)
combine a value into the reducer
Definition: reduce.hpp:85
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get() const
return the combined value
Definition: reduce.hpp:77
RAJA_HOST_DEVICE constexpr RAJA_INLINE void operator+=(T value)
combine a value into the reducer
Definition: reduce.hpp:94
RAJA_HOST_DEVICE constexpr RAJA_INLINE T get_and_reset(T init=BinaryOp::identity())
return the combined value and reset the reducer
Definition: reduce.hpp:64
Definition: Operators.hpp:367