kokkos-execution 0.0.1
Loading...
Searching...
No Matches
test_when_all.cpp
Go to the documentation of this file.
2PRAGMA_DIAGNOSTIC_PUSH
4#include "exec/single_thread_context.hpp"
5PRAGMA_DIAGNOSTIC_POP
6
10
13
27
39
40namespace Tests::GraphImpl {
41
42using namespace Kokkos::utils::callbacks;
43
69
71consteval bool test_sndr_traits() {
73 using schd_sndr_t = typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t;
74
76 using functor_t = Tests::Utils::Functors::Increment<TEST_CATEGORY(WhenAllTest)::view_s_t, true>;
77 using then_sndr_t = decltype(stdexec::then(std::declval<schd_sndr_t>(), std::declval<functor_t>()));
78
80 using when_all_sndr_t = stdexec::transform_sender_result_t<
81 decltype(stdexec::when_all(std::declval<then_sndr_t>(), std::declval<then_sndr_t>())),
82 stdexec::env<>
83 >;
84
87
90
91 return true;
92}
93
94static_assert(test_sndr_traits());
95
97consteval bool test_sndr_nothrow_transformable() {
98 using when_all_sndr_t = decltype(stdexec::when_all(
99 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>()),
100 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
102
103 static_assert(std::same_as<
104 when_all_sndr_t,
105 stdexec::__sexpr<
106 stdexec::when_all_t,
107 stdexec::__,
108 typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t,
109 stdexec::then_t::__sender<
110 Tests::Utils::Functors::NoOp<false, false, false>,
111 typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t
112 >
113 >
114 >);
115
116 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
118 stdexec::set_value_t,
119 when_all_sndr_t&&,
120 stdexec::env<>
121 >);
122
123 using when_all_maythrow_on_move_sndr_t = decltype(stdexec::when_all(
124 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>()),
125 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
127
128 static_assert(!stdexec::__detail::__has_nothrow_transform_sender<
129 Kokkos::Execution::GraphImpl::Domain,
130 stdexec::set_value_t,
131 when_all_maythrow_on_move_sndr_t&&,
132 stdexec::env<>
133 >);
134
135 return true;
136}
137
138static_assert(test_sndr_nothrow_transformable());
139
141consteval bool test_sndr_nothrow_connectable() {
143 static_assert(!std::is_nothrow_constructible_v<Kokkos::Experimental::Graph<TEST_EXECUTION_SPACE>>);
144
145 using when_all_sndr_t = decltype(stdexec::when_all(
146 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>()),
147 stdexec::schedule(std::declval<typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
148 | stdexec::then(Tests::Utils::Functors::NoOp<false, false, false>{})));
149
150 static_assert(!stdexec::__nothrow_connectable<when_all_sndr_t, Tests::Utils::SinkReceiver>);
151
152 return true;
153}
154
155static_assert(test_sndr_nothrow_connectable());
156
161template <typename ExecA, typename ExecB>
163 if constexpr (std::same_as<ExecA, ExecB>)
164 return true;
165 else {
166 using sndr_t = stdexec::transform_sender_result_t<
167 decltype(stdexec::when_all(
168 stdexec::schedule(Kokkos::Execution::GraphContext{std::declval<ExecA>()}.get_scheduler()),
169 stdexec::schedule(Kokkos::Execution::GraphContext{std::declval<ExecB>()}.get_scheduler()))),
171 >;
172
173 static_assert(
174 std::same_as<
175 sndr_t,
176 stdexec::__not_a_sender<
177 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::CANNOT_DISPATCH_THIS_ALGORITHM_TO_THE_GRAPH_SCHEDULER),
178 stdexec::_WHY_(Kokkos::Execution::GraphImpl::BECAUSE_THE_EXECUTION_SPACE_TYPE_IS_NOT_HOMOGENEOUS),
179 stdexec::_WHERE_(stdexec::_IN_ALGORITHM_, stdexec::when_all_t),
181 1,
183 >,
184 stdexec::_WITH_SENDERS_<
187 >,
188 stdexec::_WITH_ENVIRONMENT_(Tests::Utils::SinkReceiver)
189 >
190 >);
191
192 return true;
193 }
194}
195
196static_assert(test_sndr_cannot_mix_execution_space_type<TEST_EXECUTION_SPACE, Kokkos::DefaultHostExecutionSpace>());
197
200 using scheduler_t = typename TEST_CATEGORY(WhenAllTest)::scheduler_t;
201
202 using when_all_t = decltype(stdexec::when_all(
203 stdexec::schedule(std::declval<scheduler_t>()), stdexec::schedule(std::declval<scheduler_t>())));
205
206 using op_state_t = stdexec::connect_result_t<when_all_t, rcvr_t>;
207
208 static_assert(std::is_empty_v<decltype(std::declval<op_state_t>().count)>);
209
210 return true;
211}
212
213static_assert(test_count_is_empty_when_as_one());
214
221TEST_F(TEST_CATEGORY(WhenAllTest), two_branches_with_schedule_senders_only) {
222 const context_t gctx{exec};
223
224 auto sndr = stdexec::when_all(stdexec::schedule(gctx.get_scheduler()), stdexec::schedule(gctx.get_scheduler()));
225
226 static_assert(std::same_as<stdexec::tag_of_t<decltype(sndr)>, stdexec::when_all_t>);
227 static_assert(std::same_as<
228 stdexec::__completion_domain_of_t<stdexec::set_value_t, decltype(sndr)>,
230 >);
231
232 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
233 std::move(sndr)); // NOLINT(performance-move-const-arg)
234
235 ASSERT_THAT(recorded_events, testing::IsEmpty());
236}
237
249TEST_F(TEST_CATEGORY(WhenAllTest), schedule_sender) {
250 experimental::execution::single_thread_context stc{};
251 const context_t gctx{exec};
252
253 auto sndr = stdexec::when_all(
254 stdexec::schedule(gctx.get_scheduler()),
255 stdexec::schedule(stc.get_scheduler()) | stdexec::continues_on(gctx.get_scheduler()) | stdexec::then([]() { }));
256
258
259 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
260 std::move(sndr)); // NOLINT(performance-move-const-arg)
261
262 ASSERT_THAT(
263 recorded_events,
264 testing::ElementsAre(
267 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
268 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
269 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
270}
271
284TEST_F(TEST_CATEGORY(WhenAllTest), single_branch) {
285 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
286
287 const context_t gctx{exec};
288
289 auto sndr = stdexec::when_all(stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT(data));
290
291 static_assert(std::same_as<
292 decltype(stdexec::get_completion_domain<stdexec::set_value_t>(stdexec::get_env(sndr))),
294 >);
295
296 static_assert(std::same_as<stdexec::tag_of_t<decltype(sndr)>, stdexec::then_t>);
297
299 static_assert(Kokkos::Execution::GraphImpl::graph_completing_sender<decltype(sndr)>);
300
301 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
302
303 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
304
305 ASSERT_THAT(
306 recorded_events,
307 testing::ElementsAre(
310 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
311 MATCHER_FOR_GRAPH_SUBMIT(exec, recorded_events.at(0)),
313
314 ASSERT_EQ(data(), 1);
315}
316
327TEST_F(TEST_CATEGORY(WhenAllTest), schedule_sender_and_single_branch) {
328 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
329
330 const context_t gctx{exec};
331
332 auto sndr = stdexec::when_all(
333 stdexec::schedule(gctx.get_scheduler()), stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT(data));
334
335 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
336
338
339 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
340
341 ASSERT_THAT(
342 recorded_events,
343 testing::ElementsAre(
346 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
347 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
348 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
349
350 ASSERT_EQ(data(), 1);
351}
352
363TEST_F(TEST_CATEGORY(WhenAllTest), two_branches) {
364 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
365
366 const context_t gctx{exec};
367
368 auto branch_a = stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
369 auto branch_b = stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
370
371 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b));
372
373 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
374
376
377 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
378
379 ASSERT_THAT(
380 recorded_events,
381 testing::ElementsAre(
384 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
386 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
388 recorded_events.at(0),
389 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(1)),
390 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(2))),
391 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
392 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
393
394 ASSERT_EQ(data(), 2);
395}
396
409TEST_F(TEST_CATEGORY(WhenAllTest), three_branches) {
410 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
411
412 const context_t gctx{exec};
413
414 auto branch_a = stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
415 auto branch_b = stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
416 auto branch_c = stdexec::schedule(gctx.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
417
418 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b), std::move(branch_c));
419
420 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
421
423
424 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
425
426 ASSERT_THAT(
427 recorded_events,
428 testing::ElementsAre(
431 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
433 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
435 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
437 recorded_events.at(0),
438 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(1)),
439 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(2)),
440 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(3))),
441 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
442 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
443
444 ASSERT_EQ(data(), 3);
445}
446
463TEST_F(TEST_CATEGORY(WhenAllTest), three_branches_starting_on_single_thread_context) {
464 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc("data - shared space"));
465
466 experimental::execution::single_thread_context stc_a{}, stc_b{}, stc_c{};
467
468 const context_t gctx{exec};
469
472
473 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
474 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
475 | stdexec::continues_on(gctx.get_scheduler())
476 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
477 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
478 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
479 | stdexec::continues_on(gctx.get_scheduler())
480 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
481 auto branch_c = stdexec::schedule(stc_c.get_scheduler())
482 | stdexec::then(functor_h_t{.prev = 0, .value = 4, .data = &data_per_branch(2)})
483 | stdexec::continues_on(gctx.get_scheduler())
484 | stdexec::then(functor_d_t{.prev = 4, .value = 5, .data = &data_per_branch(2)});
485
486 auto sndr = stdexec::when_all(
487 std::move(branch_a), std::move(branch_b), std::move(branch_c)); // NOLINT(performance-move-const-arg)
488
489 ASSERT_THAT(Tests::Utils::span_from(data_per_branch), testing::Each(testing::Eq(0)))
490 << "Eager execution is not " "allowed.";
491
493
494 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
495 std::move(sndr)); // NOLINT(performance-move-const-arg)
496
497 ASSERT_THAT(
498 recorded_events,
499 testing::ElementsAre(
502 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
504 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
506 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
508 recorded_events.at(0),
509 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(1)),
510 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(2)),
511 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(3))),
512 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
513 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
514
515 ASSERT_THAT(Tests::Utils::span_from(data_per_branch), testing::ElementsAre(5, 7, 9));
516}
517
531TEST_F(TEST_CATEGORY(WhenAllTest), three_branches_some_starting_on_single_thread_context) {
532 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc("data - shared space"));
533
534 experimental::execution::single_thread_context stc_a{}, stc_b{};
535
536 const context_t gctx{exec};
537
540
541 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
542 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
543 | stdexec::continues_on(gctx.get_scheduler())
544 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
545 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
546 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
547 | stdexec::continues_on(gctx.get_scheduler())
548 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
549 auto branch_c = stdexec::schedule(gctx.get_scheduler())
550 | stdexec::then(functor_d_t{.prev = 0, .value = 4, .data = &data_per_branch(2)});
551
552 auto sndr = stdexec::when_all(
553 std::move(branch_a), std::move(branch_b), std::move(branch_c)); // NOLINT(performance-move-const-arg)
554
555 ASSERT_THAT(Tests::Utils::span_from(data_per_branch), testing::Each(testing::Eq(0)))
556 << "Eager execution is not " "allowed.";
557
559
560 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(
561 std::move(sndr)); // NOLINT(performance-move-const-arg)
562
563 ASSERT_THAT(
564 recorded_events,
565 testing::ElementsAre(
568 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
570 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
572 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
574 recorded_events.at(0),
575 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(1)),
576 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(2)),
577 MATCHER_FOR_GRAPH_NODE_OF(recorded_events.at(3))),
578 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
579 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
580
581 ASSERT_THAT(Tests::Utils::span_from(data_per_branch), testing::ElementsAre(5, 7, 4));
582}
583
593TEST_F(TEST_CATEGORY(WhenAllTest), forwarding_env) {
594 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
595
596 std::atomic<size_t> count = 0;
597
598 int value;
599
600 const context_t gctx{exec};
601
602 stdexec::sender auto sndr =
603 stdexec::when_all(
604 stdexec::schedule(gctx.get_scheduler()),
605 stdexec::read_env(stdexec::get_allocator)
606 | stdexec::then([&value](auto allocator) { value = Tests::Utils::round_trip_allocate(allocator, 42); })
607 | stdexec::continues_on(gctx.get_scheduler())
609 | stdexec::write_env(stdexec::prop{stdexec::get_allocator, Tests::Utils::TrackingAllocator<int>{&count}});
610
611 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
612
614
615 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
616
617 ASSERT_THAT(
618 recorded_events,
619 testing::ElementsAre(
622 recorded_events.at(0), device_handle, MATCHER_FOR_GRAPH_ROOT_NODE_OF(recorded_events.at(0))),
623 MATCHER_FOR_GRAPH_SUBMIT(TEST_EXECUTION_SPACE{}, recorded_events.at(0)),
624 MATCHER_FOR_BEGIN_FENCE(TEST_EXECUTION_SPACE{}, dispatch_label(TEST_EXECUTION_SPACE{}, "after dispatch"))));
625
626 ASSERT_EQ(data(), 1);
627
628 ASSERT_EQ(value, 42);
629 ASSERT_EQ(count, 1);
630}
631
637 using schd_sndr_t = typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t;
638
641
642 using br_A_t = decltype(std::declval<schd_sndr_t>() | stdexec::then(functor_t{}));
643 using br_B_t = decltype(std::declval<schd_sndr_t>() | stdexec::then(functor_t{}));
644
646 using sndr_t = decltype(stdexec::when_all(std::declval<br_A_t>(), std::declval<br_B_t>()));
647
648 using op_state_t = stdexec::connect_result_t<sndr_t, rcvr_t>;
649
651
653
654 static_assert(std::same_as<diagnose_t, stdexec::__msuccess>);
655
657
658 return true;
659}
660
661static_assert(test_when_all_remains_on_graph_for_two_branches());
662
670 using scheduler_t = TEST_CATEGORY(WhenAllTest)::scheduler_t;
671 using schd_sndr_t = typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t;
672
675
677 using br_A_t =
678 decltype(stdexec::schedule(std::declval<exec::single_thread_context&>().get_scheduler()) | stdexec::continues_on(std::declval<scheduler_t>()) | stdexec::then(functor_t{}));
679
681 using br_B_t = decltype(std::declval<schd_sndr_t>() | stdexec::then(functor_t{}));
682
684 using sndr_t = decltype(stdexec::when_all(std::declval<br_A_t>(), std::declval<br_B_t>()));
685
686 using op_state_t = stdexec::connect_result_t<sndr_t, rcvr_t>;
687
688 using op_state_br_A_t = stdexec::connect_result_t<br_A_t, typename op_state_t::WhenAllChildReceiver>;
689
690 using diagnose_t = Kokkos::Execution::Impl::diagnose_t<
692 >;
693
695 static_assert(
696 std::same_as<
697 diagnose_t,
698 stdexec::_ERROR_<
699 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
700 stdexec::_WHY_(Kokkos::Execution::GraphImpl::BECAUSE_AT_LEAST_ONE_CHILD_DOES_NOT_REMAIN_ON_GRAPH),
702 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
703 stdexec::_WHY_(
704 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
705 stdexec::_ERROR_<
706 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
707 stdexec::_WHY_(
708 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
709 stdexec::_ERROR_<
710 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
712 typename op_state_br_A_t::inner_op_state_t::inner_op_state_t
713 >,
715 >,
718 >,
721 >>,
723 >
724 >);
725
726 return true;
727}
728
729static_assert(test_when_all_does_not_remain_on_graph_for_two_branches());
730
738 using scheduler_t = TEST_CATEGORY(WhenAllTest)::scheduler_t;
739 using schd_sndr_t = typename TEST_CATEGORY(WhenAllTest)::schedule_sender_t;
740
743
745 using br_A_t =
746 decltype(stdexec::schedule(std::declval<exec::single_thread_context&>().get_scheduler()) | stdexec::continues_on(std::declval<scheduler_t>()) | stdexec::then(functor_t{}));
747
749 using br_B_t = decltype(std::declval<schd_sndr_t>() | stdexec::then(functor_t{}));
750
752 using br_C_t =
753 decltype(stdexec::schedule(std::declval<exec::single_thread_context&>().get_scheduler()) | stdexec::continues_on(std::declval<scheduler_t>()) | stdexec::then(functor_t{}));
754
756 using sndr_t = decltype(stdexec::when_all(std::declval<br_A_t>(), std::declval<br_B_t>(), std::declval<br_C_t>()));
757
758 using op_state_t = stdexec::connect_result_t<sndr_t, rcvr_t>;
759
760 using op_state_br_A_t = stdexec::connect_result_t<br_A_t, typename op_state_t::WhenAllChildReceiver>;
761 using op_state_br_C_t = stdexec::connect_result_t<br_C_t, typename op_state_t::WhenAllChildReceiver>;
762
763 using diagnose_t = Kokkos::Execution::Impl::diagnose_t<
765 >;
766
768 static_assert(
769 std::same_as<
770 diagnose_t,
771 stdexec::_ERROR_<
772 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
773 stdexec::_WHY_(Kokkos::Execution::GraphImpl::BECAUSE_AT_LEAST_ONE_CHILD_DOES_NOT_REMAIN_ON_GRAPH),
775 stdexec::_ERROR_<
776 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
777 stdexec::_WHY_(
778 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
779 stdexec::_ERROR_<
780 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
781 stdexec::_WHY_(
782 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
783 stdexec::_ERROR_<
784 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
786 typename op_state_br_A_t::inner_op_state_t::inner_op_state_t
787 >,
789 >,
792 >,
795 >,
796 stdexec::_ERROR_<
797 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
798 stdexec::_WHY_(
799 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
800 stdexec::_ERROR_<
801 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
802 stdexec::_WHY_(
803 Kokkos::Execution::GraphImpl::BECAUSE_THE_INNER_OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
804 stdexec::_ERROR_<
805 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::OPERATION_STATE_DOES_NOT_REMAIN_ON_GRAPH),
807 typename op_state_br_C_t::inner_op_state_t::inner_op_state_t
808 >,
810 >,
813 >,
816 >
817 >,
819 >
820 >);
821
822 return true;
823}
824
825static_assert(test_when_all_does_not_remain_on_graph_for_three_branches());
826
827} // 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
device_handle_t default_device_handle
RecorderListener< ConjunctionMatcher< EventDiscardMatcher< TEST_EXECUTION_SPACE >, GraphEventDiscardMatcher< TEST_EXECUTION_SPACE > >, BeginFenceEvent, BeginParallelForEvent, AllocateDataEvent, DeallocateDataEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent, Kokkos::Execution::GraphImpl::GraphAddAggregateNodeEvent, 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.
#define KOKKOS_EXECUTION_THREADS_THROWS_ON_SYNC_WAIT_ASSERT_AND_SKIP(_sndr_)
Definition context.hpp:76
#define KOKKOS_EXECUTION_TEST_UTILS_GRAPH_FENCE(_exec_)
#define KOKKOS_EXECUTION_STDEXEC_PRAGMA_DIAGNOSTIC_IGNORED
Basic list of ignored diagnostics when including anything from stdexec.
#define THEN_INCREMENT(_data_)
Add a then using Tests::Utils::Functors::Increment that may throw. // NOLINTNEXTLINE(cppcoreguideline...
Definition increment.hpp:64
#define THEN_INCREMENT_ATOMIC(_scope_, _data_)
Same as THEN_INCREMENT, using Tests::Utils::atomic_fetch_add. // NOLINTNEXTLINE(cppcoreguidelines-mac...
Definition increment.hpp:68
constexpr bool mandate_or_explain() noexcept
If T::value is false, diagnose.
typename Diagnose< Ts... >::type diagnose_t
consteval bool test_sndr_nothrow_transformable()
Definition test_bulk.cpp:87
consteval bool test_count_is_empty_when_as_one()
consteval bool test_sndr_traits()
Definition test_bulk.cpp:57
consteval bool test_when_all_does_not_remain_on_graph_for_two_branches()
consteval bool test_when_all_does_not_remain_on_graph_for_three_branches()
consteval bool test_when_all_remains_on_graph_for_two_branches()
consteval bool test_sndr_nothrow_connectable()
consteval bool test_sndr_cannot_mix_execution_space_type()
auto record_sync_wait(Sndr &&sndr)
Definition sync_wait.hpp:14
constexpr check_rcvr_env_queryable_with_t< true, Queries... > check_rcvr_env_queryable_with
auto span_from(const ViewType &view) noexcept
Get a std::span from a rank-one Kokkos::View.
Definition kokkos.hpp:46
Execution context using Kokkos::Experimental::Graph under the hood.
Definition graph.hpp:123
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 aggregate node is added.
Definition events.hpp:68
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
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Definition event.hpp:59
Receiver for stdexec::sync_wait.
Definition sync_wait.hpp:45
Tag to be used to signal children errors.
Tag to be used to signal an execution space.
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
Load the value at data and check it is equal to prev. Then, add value to it.
Kokkos::Impl::DeviceHandle< Exec > device_handle_t
A receiver that can handle all completions and does nothing with them.
A minimal tracking allocator.
#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_ADD_AGGREGATE_NODE(_graph_create_event_variant_,...)
Definition events.hpp:40
#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