DDC 0.5.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 <class Support, class T, class BinaryReductionOp, class UnaryTransformOp, class... DCoords>
27T transform_reduce_serial(
28 Support const& domain,
29 [[maybe_unused]] T const neutral,
30 BinaryReductionOp const& reduce,
31 UnaryTransformOp const& transform,
32 DCoords const&... dcoords) noexcept
33{
34 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
35 if constexpr (sizeof...(DCoords) == Support::rank()) {
36 return transform(typename Support::discrete_element_type(dcoords...));
37 } else {
38 using CurrentDDim = type_seq_element_t<sizeof...(DCoords), to_type_seq_t<Support>>;
39 T result = neutral;
40 for (DiscreteElement<CurrentDDim> const ii : DiscreteDomain<CurrentDDim>(domain)) {
41 result = reduce(
42 result,
43 transform_reduce_serial(domain, neutral, reduce, transform, dcoords..., ii));
44 }
45 return result;
46 }
47 DDC_IF_NVCC_THEN_POP
48}
49
50} // namespace detail
51
52/** A reduction over a nD domain in serial
53 * @param[in] domain the range over which to apply the algorithm
54 * @param[in] neutral the neutral element of the reduction operation
55 * @param[in] reduce a binary FunctionObject that will be applied in unspecified order to the
56 * results of transform, the results of other reduce and neutral.
57 * @param[in] transform a unary FunctionObject that will be applied to each element of the input
58 * range. The return type must be acceptable as input to reduce
59 */
60template <class Support, class T, class BinaryReductionOp, class UnaryTransformOp>
62 Support const& domain,
63 T neutral,
64 BinaryReductionOp&& reduce,
65 UnaryTransformOp&& transform) noexcept
66{
67 return detail::transform_reduce_serial(
68 domain,
69 neutral,
70 std::forward<BinaryReductionOp>(reduce),
71 std::forward<UnaryTransformOp>(transform));
72}
73
74} // 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.