kokkos-execution 0.0.1
Loading...
Searching...
No Matches
parallel_reduce.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_EXECUTION_PARALLEL_REDUCE_HPP
2#define KOKKOS_EXECUTION_PARALLEL_REDUCE_HPP
3
4#include "Kokkos_Macros.hpp"
5#ifdef KOKKOS_ENABLE_EXPERIMENTAL_CXX20_MODULES
6import kokkos.core_impl;
7#endif
8
16
17namespace Kokkos::Execution {
18
19namespace Impl {
20
21template <typename Data>
22concept parallel_reduce_data = requires {
23 typename Data::functor_t;
24 typename Data::policy_or_iter_space_t;
25 typename Data::reducer_t;
26 typename Data::properties_t;
27
29 requires stdexec::__is_instance_of<typename Data::properties_t, properties>;
30 requires requires(const Data& data) {
31 { data.functor } -> std::same_as<const typename Data::functor_t&>;
32 { data.policy_or_iter_space } -> std::same_as<const typename Data::policy_or_iter_space_t&>;
33 { data.reducer } -> std::same_as<const typename Data::reducer_t&>;
34 };
35};
36
37template <
38 typename Functor,
39 execution_policy_or_iteration_space ExecPolicyOrIterSpace,
40 typename Reducer,
41 typename... Properties
42>
44
45template <stdexec::sender Sndr, parallel_reduce_data Data>
47
48} // namespace Impl
49
52 template <typename Label, typename Functor, typename ExecPolicy, typename Reducer>
53 requires(Impl::label<std::remove_cvref_t<Label>> && Kokkos::ExecutionPolicy<std::remove_cvref_t<ExecPolicy>>)
54 constexpr auto
55 operator()(Label&& label, ExecPolicy&& policy, Functor&& functor, Reducer&& reducer) const STDEXEC_AUTO_RETURN(
56 stdexec::__closure(
57 *this,
58 std::forward<ExecPolicy>(policy),
59 std::forward<Functor>(functor),
60 std::forward<Reducer>(reducer),
61 Impl::Label{std::forward<Label>(label)}))
62
63 template <typename ExecPolicyOrIterSpace, typename Functor, typename Reducer>
64 requires Impl::execution_policy_or_iteration_space<std::remove_cvref_t<ExecPolicyOrIterSpace>>
65 constexpr auto operator()(ExecPolicyOrIterSpace&& policy_or_iter_space, Functor&& functor, Reducer&& reducer) const
66 STDEXEC_AUTO_RETURN(
67 stdexec::__closure(
68 *this,
69 std::forward<ExecPolicyOrIterSpace>(policy_or_iter_space),
70 std::forward<Functor>(functor),
71 std::forward<Reducer>(reducer)))
72
73 template <typename Label, typename Functor, std::integral T, typename Reducer>
75 constexpr auto
76 operator()(Label&& label, const T work_count, Functor&& functor, Reducer&& reducer) const STDEXEC_AUTO_RETURN(
77 stdexec::__closure(
78 *this,
79 Impl::make_iter_space(work_count),
80 std::forward<Functor>(functor),
81 std::forward<Reducer>(reducer),
82 Impl::Label{std::forward<Label>(label)}))
83
84 template <typename Functor, std::integral T, typename Reducer>
85 constexpr auto operator()(const T work_count, Functor&& functor, Reducer&& reducer) const STDEXEC_AUTO_RETURN(
86 stdexec::__closure(
87 *this,
88 Impl::make_iter_space(work_count),
89 std::forward<Functor>(functor),
90 std::forward<Reducer>(reducer)))
91
92 template <typename Functor, typename ExecPolicyOrIterSpace, typename Reducer, typename... Properties>
94 std::remove_cvref_t<Functor>,
95 std::remove_cvref_t<ExecPolicyOrIterSpace>,
96 std::remove_cvref_t<Reducer>,
97 std::remove_cvref_t<Properties>...
98 >;
99
100 template <
101 stdexec::sender Sndr,
102 typename Functor,
103 typename ExecPolicyOrIterSpace,
104 typename Reducer,
105 typename... Properties
106 >
108 constexpr auto operator()(
109 Sndr&& sndr,
110 ExecPolicyOrIterSpace&& policy_or_iter_space,
111 Functor&& functor,
112 Reducer&& reducer,
113 Properties&&... properties) const
116 Sndr,
118 >),
119 {
121 parallel_reduce_data_t<Functor, ExecPolicyOrIterSpace, Reducer, Properties...>{
122 std::forward<Properties>(properties)...,
123 std::forward<Functor>(functor),
124 std::forward<ExecPolicyOrIterSpace>(policy_or_iter_space),
125 std::forward<Reducer>(reducer)},
126 std::forward<Sndr>(sndr)
127 })
128};
129
130namespace Impl {
131
132template <
133 typename Functor,
134 execution_policy_or_iteration_space ExecPolicyOrIterSpace,
135 typename Reducer,
136 typename... Properties
137>
138struct ParallelReduceData : Properties... {
139 using functor_t = Functor;
140 using policy_or_iter_space_t = ExecPolicyOrIterSpace;
141 using reducer_t = Reducer;
142 using properties_t = properties<Properties...>;
143
147
149 template <typename Self, typename UnaryOp>
150 constexpr STDEXEC_EXPLICIT_THIS_BEGIN(auto transform_policy_or_iter_space)(
151 this Self&& self, // NOLINT(cppcoreguidelines-missing-std-forward)
152 UnaryOp&& unary_op)
153 STDEXEC_AUTO_RETURN(
155 functor_t,
156 std::remove_cvref_t<
157 std::invoke_result_t<UnaryOp, decltype(stdexec::__forward_like<Self>(self.policy_or_iter_space))>
158 >,
159 reducer_t,
160 Properties...
161 >{stdexec::__forward_like<Self>(detail::as_base<Properties>(self))...,
162 stdexec::__forward_like<Self>(self.functor),
163 std::forward<UnaryOp>(unary_op)(stdexec::__forward_like<Self>(self.policy_or_iter_space)),
164 stdexec::__forward_like<Self>(self.reducer)})
165 STDEXEC_EXPLICIT_THIS_END(transform_policy_or_iter_space)
166};
167
168template <stdexec::sender Sndr, Impl::parallel_reduce_data Data>
169struct ParallelReduceSender : stdexec::__tuple<parallel_reduce_t, Data, Sndr> {
170 using sender_concept = stdexec::sender_tag;
171
174 using __data_t = Data; // NOLINT(bugprone-reserved-identifier)
175 using __children_t = stdexec::__mlist<Sndr>; // NOLINT(bugprone-reserved-identifier)
177
178 using base_t = stdexec::__tuple<parallel_reduce_t, __data_t, Sndr>;
179
180 KOKKOS_EXECUTION_COMPL_SIGS_ADD(ParallelReduceSender, Sndr, stdexec::set_error_t(std::exception_ptr))
181
182 template <stdexec::receiver Rcvr>
183 constexpr auto connect(Rcvr) && = delete;
184
185 template <stdexec::receiver Rcvr>
186 constexpr auto connect(Rcvr) const & = delete;
187
188 static constexpr size_t idx_sndr = 2;
190 Sndr,
191 stdexec::__get<idx_sndr>(static_cast<const base_t&>(*this)))
192};
193
194} // namespace Impl
195
197
198} // namespace Kokkos::Execution
199
200#endif // KOKKOS_EXECUTION_PARALLEL_REDUCE_HPP
#define KOKKOS_EXECUTION_COMPL_SIGS_ADD(_decayed_self_type_, _sndr_type_,...)
Constrain the accepted label types.
Definition label.hpp:40
#define KOKKOS_EXECUTION_IMPL_FORWARDING_ATTRIBUTES_GET_ENV(_type_, _obj_)
#define KOKKOS_EXECUTION_RETURNS_BRACED(_type_,...)
Define a function by returning a list-initialized object of an explicit type.
Definition macros.hpp:23
constexpr auto make_iter_space(const T work_count) noexcept -> Kokkos::dims< 1, T >
Make a valid iteration space from a work count.
consteval Impl::Label< std::string_view > label(std::string_view str) noexcept
Definition label.hpp:91
constexpr parallel_reduce_t parallel_reduce
constexpr auto transform_policy_or_iter_space(this Self &&self, UnaryOp &&unary_op) noexcept(noexcept(ParallelReduceData< functor_t, std::remove_cvref_t< std::invoke_result_t< UnaryOp, decltype(stdexec::__forward_like< Self >(self.policy_or_iter_space))> >, reducer_t, Properties... >{stdexec::__forward_like< Self >(detail::as_base< Properties >(self))..., stdexec::__forward_like< Self >(self.functor), std::forward< UnaryOp >(unary_op)(stdexec::__forward_like< Self >(self.policy_or_iter_space)), stdexec::__forward_like< Self >(self.reducer)})) -> decltype(ParallelReduceData< functor_t, std::remove_cvref_t< std::invoke_result_t< UnaryOp, decltype(stdexec::__forward_like< Self >(self.policy_or_iter_space))> >, reducer_t, Properties... >{stdexec::__forward_like< Self >(detail::as_base< Properties >(self))..., stdexec::__forward_like< Self >(self.functor), std::forward< UnaryOp >(unary_op)(stdexec::__forward_like< Self >(self.policy_or_iter_space)), stdexec::__forward_like< Self >(self.reducer)})
stdexec::__tuple< parallel_reduce_t, __data_t, Sndr > base_t
constexpr auto connect(Rcvr) const &=delete
constexpr auto connect(Rcvr) &&=delete
Type list of properties.
Custom algorithm for the Kokkos::parallel_reduce construct.
constexpr auto operator()(Label &&label, const T work_count, Functor &&functor, Reducer &&reducer) const noexcept(noexcept(stdexec::__closure(*this, Impl::make_iter_space(work_count), std::forward< Functor >(functor), std::forward< Reducer >(reducer), Impl::Label{std::forward< Label >(label)}))) -> decltype(stdexec::__closure(*this, Impl::make_iter_space(work_count), std::forward< Functor >(functor), std::forward< Reducer >(reducer), Impl::Label{std::forward< Label >(label)}))
constexpr auto operator()(Sndr &&sndr, ExecPolicyOrIterSpace &&policy_or_iter_space, Functor &&functor, Reducer &&reducer, Properties &&... properties) const noexcept(noexcept(Impl::ParallelReduceSender< Sndr, parallel_reduce_data_t< Functor, ExecPolicyOrIterSpace, Reducer, Properties... > >{{ parallel_reduce_t{}, parallel_reduce_data_t< Functor, ExecPolicyOrIterSpace, Reducer, Properties... >{ std::forward< Properties >(properties)..., std::forward< Functor >(functor), std::forward< ExecPolicyOrIterSpace >(policy_or_iter_space), std::forward< Reducer >(reducer)}, std::forward< Sndr >(sndr) }})) -> Impl::ParallelReduceSender< Sndr, parallel_reduce_data_t< Functor, ExecPolicyOrIterSpace, Reducer, Properties... > >
Impl::ParallelReduceData< std::remove_cvref_t< Functor >, std::remove_cvref_t< ExecPolicyOrIterSpace >, std::remove_cvref_t< Reducer >, std::remove_cvref_t< Properties >... > parallel_reduce_data_t