kokkos-execution 0.0.1
Loading...
Searching...
No Matches
test_parallel_reduce.cpp
Go to the documentation of this file.
4
7
20
31
32namespace Tests::GraphImpl {
33
34using namespace Kokkos::utils::callbacks;
35
53
58template <
59 template <typename...> class SndrAdptr,
60 bool ExptIsDispatchingSender,
61 template <typename> typename ExptTransformSenderType
62>
63consteval bool test_sndr_traits() {
65 using schd_sndr_t = typename TEST_CATEGORY(ParallelReduceTest)::schedule_sender_t;
66
68 using label_t = std::string;
70 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
71 using reducer_t = typename TEST_CATEGORY(ParallelReduceTest)::view_s_t;
72 using pred_sndr_t = SndrAdptr<schd_sndr_t, TEST_EXECUTION_SPACE, label_t, functor_t, policy_t, reducer_t>;
73
76
78 static_assert(Kokkos::Execution::Impl::dispatching_sender<pred_sndr_t> == ExptIsDispatchingSender);
79
81 static_assert(!stdexec::dependent_sender<pred_sndr_t>);
82 static_assert(
83 stdexec::get_completion_signatures<pred_sndr_t>()
84 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
85
87 static_assert(std::same_as<
88 stdexec::__completion_domain_of_t<stdexec::set_value_t, pred_sndr_t, stdexec::env<>>,
90 >);
91
93 static_assert(std::same_as<
96 >);
97
99 static_assert(stdexec::sender_to<pred_sndr_t, Tests::Utils::SinkReceiver>);
100
101 static_assert(std::same_as<
102 stdexec::transform_sender_result_t<pred_sndr_t, stdexec::env_of_t<Tests::Utils::SinkReceiver>>,
103 typename ExptTransformSenderType<Kokkos::Execution::GraphImpl::ParallelReduceSender< // NOLINT(modernize-type-traits)
104 schd_sndr_t,
106 functor_t,
107 policy_t,
108 reducer_t
109 >>::type
110 >);
111
113 static_assert(!stdexec::__nothrow_connectable<pred_sndr_t, Tests::Utils::SinkReceiver>);
114
115 return true;
116}
117
118template <typename Sndr, typename Exec, typename Label, typename Functor, typename Policy, typename Reducer>
120 Sndr,
122>;
123
124template <typename Sndr, typename Exec, typename Label, typename Functor, typename Policy, typename Reducer>
126 Sndr,
128 Functor,
129 Policy,
130 Reducer
131>;
132
135
137template <typename ViewType>
138consteval bool test_closure_traits() {
140 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
141 using iter_space_t = Kokkos::dims<1, int>;
142 using reducer_t = ViewType;
145 functor_t,
146 policy_t,
147 reducer_t
148 >;
149 using closure_iter_space_t = Kokkos::Execution::GraphImpl::ParallelReduceClosure<
151 functor_t,
152 iter_space_t,
153 reducer_t
154 >;
155
159
160 static_assert(std::is_nothrow_move_constructible_v<closure_policy_t>);
161 static_assert(std::is_nothrow_move_constructible_v<closure_iter_space_t>);
162
163 return true;
164}
165
166static_assert(test_closure_traits<typename TEST_CATEGORY(ParallelReduceTest)::view_s_t>());
167static_assert(test_closure_traits<std::span<int>>());
168
171 typename TEST_CATEGORY(ParallelReduceTest)::scheduler_t,
172 Kokkos::Execution::parallel_reduce_t,
173 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>,
174 Tests::Utils::Functors::NoOp<false, false, false>,
175 typename TEST_CATEGORY(ParallelReduceTest)::view_s_t
176>());
177
179TEST_F(TEST_CATEGORY(ParallelReduceTest), range_policy_into_rank_0_view) {
180 const view_s_t target(Kokkos::view_alloc(exec, "data - shared space"));
181
182 const context_t gctx{exec};
183
184 constexpr size_t size = 10;
185
186 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
187 stdexec::schedule(gctx.get_scheduler())
189 "hello from pred",
190 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
192 target));
193
194 ASSERT_THAT(
195 recorded_events,
196 testing::ElementsAre(
199 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
200 MATCHER_FOR_GRAPH_SUBMIT(exec, recorded_events.at(0)),
202
203 ASSERT_EQ(target(), size / 2 * (size - 1));
204}
205
207TEST_F(TEST_CATEGORY(ParallelReduceTest), range_policy_maxloc_reducer) {
208 constexpr size_t size = 5;
209
210 using data_view_t = Kokkos::View<value_t[size], TEST_EXECUTION_SPACE>;
211 using max_loc_t = Kokkos::MaxLoc<value_t, typename TEST_EXECUTION_SPACE::index_type, Kokkos::SharedSpace>;
212 using max_loc_functor_t = Tests::Utils::Functors::MaxLoc<data_view_t>;
213
214 const data_view_t data(Kokkos::view_alloc(Kokkos::WithoutInitializing, exec));
215
216 const context_t gctx{exec};
217
218 const typename max_loc_t::result_view_type target(Kokkos::view_alloc(exec));
219
220 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
221 stdexec::schedule(gctx.get_scheduler())
223 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, 1),
224 KOKKOS_LAMBDA<std::integral T>(const T) {
225 data(0) = 42;
226 data(1) = -5;
227 data(2) = 6;
228 data(3) = 56;
229 data(4) = -6;
230 })
232 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size), max_loc_functor_t{.data = data}, max_loc_t{target}));
233
234 ASSERT_THAT(
235 recorded_events,
236 testing::ElementsAre(
239 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
241 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(1))),
242 MATCHER_FOR_GRAPH_SUBMIT(exec, recorded_events.at(0)),
244
245 ASSERT_EQ(target().val, 56);
246 ASSERT_EQ(target().loc, 3);
247}
248
250TEST_F(TEST_CATEGORY(ParallelReduceTest), starts_on_parallel_region) {
251 constexpr size_t size = 10;
252
253 const view_s_t target(Kokkos::view_alloc(exec, "data - shared space"));
254
255 auto chain =
256 stdexec::just()
258 std::format("{}: hello from pred", Kokkos::Execution::Impl::display_string_of<TEST_EXECUTION_SPACE>()),
259 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
261 target);
262
263 using chain_t = decltype(chain);
264
265 static_assert(
266 stdexec::get_completion_signatures<chain_t>()
267 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
269 static_assert(
270 std::same_as<stdexec::__completion_domain_of_t<stdexec::set_value_t, chain_t>, stdexec::indeterminate_domain<>>);
271
272 const context_t gctx{exec};
273 auto starts_on = stdexec::starts_on(gctx.get_scheduler(), std::move(chain));
274
275 using starts_on_t = decltype(starts_on);
276
277 static_assert(stdexec::__has_eptr_completion<chain_t>);
278 static_assert(!stdexec::dependent_sender<starts_on_t>);
279 static_assert(
280 stdexec::get_completion_signatures<starts_on_t>()
281 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
282
283 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(starts_on));
284
285 ASSERT_THAT(
286 recorded_events,
287 testing::ElementsAre(
290 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
291 MATCHER_FOR_GRAPH_SUBMIT(exec, recorded_events.at(0)),
292 MATCHER_FOR_BEGIN_FENCE(exec, dispatch_label(exec, "after dispatch"))));
293
294 ASSERT_EQ(target(), size / 2 * (size - 1));
295}
296
297} // namespace Tests::GraphImpl
constexpr std::string dispatch_label(const Exec &, const std::string_view label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
#define TEST_CATEGORY(_name_)
Definition category.hpp:10
RecorderListener< ConjunctionMatcher< EventDiscardMatcher< TEST_EXECUTION_SPACE >, GraphEventDiscardMatcher< TEST_EXECUTION_SPACE > >, BeginFenceEvent, BeginParallelForEvent, BeginParallelReduceEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent, Kokkos::Execution::GraphImpl::GraphAddNodeEvent, Kokkos::Execution::GraphImpl::GraphCreateEvent, Kokkos::Execution::GraphImpl::GraphInstantiateEvent, Kokkos::Execution::GraphImpl::GraphSubmitEvent > recorder_listener_t
Concept for a sender whose completion scheduler is Kokkos::Execution::GraphImpl::Scheduler.
Concept that constrains the type of a sender that dispatches a functor for execution.
typename Kokkos::Impl::NodeCtorProps< Kokkos::Impl::DeviceHandle< Exec >, Label >::uniform_type node_props_t
std::invoke_result_t< stdexec::get_completion_scheduler_t< Tag >, stdexec::env_of_t< Sndr >, Env... > completion_scheduler_of_t
Retrieve the completion scheduler for a given completion tag.
constexpr auto display_string_of() noexcept -> std::string_view
Definition type_info.hpp:20
constexpr parallel_for_t parallel_for
constexpr parallel_reduce_t parallel_reduce
Kokkos::Execution::Impl::ParallelReduceSender< Sndr, Kokkos::Execution::Impl::ParallelReduceData< Functor, Policy, Reducer, Kokkos::Execution::Impl::Label< Label > > > pred_generic_t
consteval bool test_closure_traits()
consteval bool test_sndr_traits()
Definition test_bulk.cpp:57
Kokkos::Execution::GraphImpl::ParallelReduceSender< Sndr, Kokkos::Execution::GraphImpl::node_props_t< Exec, Label >, Functor, Policy, Reducer > pred_impl_t
auto record_sync_wait(Sndr &&sndr)
Definition sync_wait.hpp:14
consteval bool check_continues_on_after_just_stopped()
Tests::Utils::Functors::NoOp< false, false, false > NoOp
auto get_scheduler() const noexcept -> GraphImpl::Scheduler< execution_space >
Definition graph.hpp:134
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph node is added.
Definition events.hpp:49
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is created.
Definition events.hpp:28
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is instantiated.
Definition events.hpp:85
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is submitted.
Definition events.hpp:98
Scheduler for a Kokkos::Experimental::Graph.
Definition graph.hpp:30
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Definition event.hpp:59
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Definition event.hpp:80
Similar to EventDiscardMatcher, for graph-related events.
Definition events.hpp:83
Kokkos::View< value_t, Kokkos::SharedSpace > view_s_t
Definition context.hpp:38
Can be used in a parallel_reduce to find the greater of the values in data alongside its index.
Definition maxloc.hpp:15
#define MATCHER_FOR_GRAPH_CREATE(_device_handle_)
Definition events.hpp:17
#define MATCHER_FOR_GRAPH_ADDNODE(_graph_create_event_variant_, _device_handle_, _predecessor_,...)
Definition events.hpp:24
#define MATCHER_FOR_GRAPH_SUBMIT(_exec_, _graph_create_event_variant_)
Definition events.hpp:71
#define MATCHER_FOR_GRAPH_ROOT_NODE_OF(_graph_create_event_)
Definition events.hpp:51
#define MATCHER_FOR_GRAPH_NODE_OF(_graph_add_node_event_)
Definition events.hpp:55