DDC 0.1.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 "ddc/detail/macros.hpp"
10#include "ddc/discrete_domain.hpp"
11#include "ddc/discrete_element.hpp"
12
13namespace ddc {
14
15namespace detail {
16
17/** A serial reduction over a nD domain
18 * @param[in] domain the range over which to apply the algorithm
19 * @param[in] neutral the neutral element of the reduction operation
20 * @param[in] reduce a binary FunctionObject that will be applied in unspecified order to the
21 * results of transform, the results of other reduce and neutral.
22 * @param[in] transform a unary FunctionObject that will be applied to each element of the input
23 * range. The return type must be acceptable as input to reduce
24 * @param[in] dcoords discrete elements from dimensions already in a loop
25 */
26template <
27 class... DDims,
28 class T,
29 class BinaryReductionOp,
30 class UnaryTransformOp,
31 class... DCoords>
32T transform_reduce_serial(
33 DiscreteDomain<DDims...> const& domain,
34 [[maybe_unused]] T const neutral,
35 BinaryReductionOp const& reduce,
36 UnaryTransformOp const& transform,
37 DCoords const&... dcoords) noexcept
38{
39 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
40 if constexpr (sizeof...(DCoords) == sizeof...(DDims)) {
41 return transform(DiscreteElement<DDims...>(dcoords...));
42 } else {
43 using CurrentDDim = type_seq_element_t<sizeof...(DCoords), detail::TypeSeq<DDims...>>;
44 T result = neutral;
45 for (DiscreteElement<CurrentDDim> const ii : select<CurrentDDim>(domain)) {
46 result = reduce(
47 result,
48 transform_reduce_serial(domain, neutral, reduce, transform, dcoords..., ii));
49 }
50 return result;
51 }
52 DDC_IF_NVCC_THEN_POP
53}
54
55} // namespace detail
56
57/** A reduction over a nD domain in serial
58 * @param[in] domain the range over which to apply the algorithm
59 * @param[in] neutral the neutral element of the reduction operation
60 * @param[in] reduce a binary FunctionObject that will be applied in unspecified order to the
61 * results of transform, the results of other reduce and neutral.
62 * @param[in] transform a unary FunctionObject that will be applied to each element of the input
63 * range. The return type must be acceptable as input to reduce
64 */
65template <class... DDims, class T, class BinaryReductionOp, class UnaryTransformOp>
67 DiscreteDomain<DDims...> const& domain,
68 T neutral,
69 BinaryReductionOp&& reduce,
70 UnaryTransformOp&& transform) noexcept
71{
72 return detail::transform_reduce_serial(
73 domain,
74 neutral,
75 std::forward<BinaryReductionOp>(reduce),
76 std::forward<UnaryTransformOp>(transform));
77}
78
79} // namespace ddc
friend class DiscreteDomain
The top-level namespace of DDC.
T transform_reduce(DiscreteDomain< DDims... > const &domain, T neutral, BinaryReductionOp &&reduce, UnaryTransformOp &&transform) noexcept
A reduction over a nD domain in serial.