DDC 0.7.0
Loading...
Searching...
No Matches
transform_reduce.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <utility>
8
9#include "detail/macros.hpp"
10
11#include "discrete_domain.hpp"
12#include "discrete_element.hpp"
13
14namespace ddc {
15
16namespace detail {
17
18/** A serial reduction over a nD domain
19 * @param[in] domain the range over which to apply the algorithm
20 * @param[in] neutral the neutral element of the reduction operation
21 * @param[in] reduce a binary FunctionObject that will be applied in unspecified order to the
22 * results of transform, the results of other reduce and neutral.
23 * @param[in] transform a unary FunctionObject that will be applied to each element of the input
24 * range. The return type must be acceptable as input to reduce
25 * @param[in] dcoords discrete elements from dimensions already in a loop
26 */
27template <class Support, class T, class BinaryReductionOp, class UnaryTransformOp, class... DCoords>
28T transform_reduce_serial(
29 Support const& domain,
30 [[maybe_unused]] T const neutral,
31 BinaryReductionOp const& reduce,
32 UnaryTransformOp const& transform,
33 DCoords const&... dcoords) noexcept
34{
35 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
36 if constexpr (sizeof...(DCoords) == Support::rank()) {
37 return transform(typename Support::discrete_element_type(dcoords...));
38 } else {
39 using CurrentDDim = type_seq_element_t<sizeof...(DCoords), to_type_seq_t<Support>>;
40 T result = neutral;
41 for (DiscreteElement<CurrentDDim> const ii : DiscreteDomain<CurrentDDim>(domain)) {
42 result = reduce(
43 result,
44 transform_reduce_serial(domain, neutral, reduce, transform, dcoords..., ii));
45 }
46 return result;
47 }
48 DDC_IF_NVCC_THEN_POP
49}
50
51} // namespace detail
52
53/** A reduction over a nD domain in serial
54 * @param[in] domain the range over which to apply the algorithm
55 * @param[in] neutral the neutral element of the reduction operation
56 * @param[in] reduce a binary FunctionObject that will be applied in unspecified order to the
57 * results of transform, the results of other reduce and neutral.
58 * @param[in] transform a unary FunctionObject that will be applied to each element of the input
59 * range. The return type must be acceptable as input to reduce
60 */
61template <class Support, class T, class BinaryReductionOp, class UnaryTransformOp>
63 Support const& domain,
64 T neutral,
65 BinaryReductionOp&& reduce,
66 UnaryTransformOp&& transform) noexcept
67{
68 return detail::transform_reduce_serial(
69 domain,
70 neutral,
71 std::forward<BinaryReductionOp>(reduce),
72 std::forward<UnaryTransformOp>(transform));
73}
74
75} // namespace ddc
friend class DiscreteDomain
The top-level namespace of DDC.
T transform_reduce(Support const &domain, T neutral, BinaryReductionOp &&reduce, UnaryTransformOp &&transform) noexcept
A reduction over a nD domain in serial.