4#include "exec/single_thread_context.hpp"
42using namespace Kokkos::utils::callbacks;
44class TEST_CATEGORY(WhenAllTest)
77 using then_sndr_t =
decltype(stdexec::then(std::declval<schd_sndr_t>(), std::declval<functor_t>()));
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>())),
93static_assert(test_sndr_traits());
96consteval bool test_sndr_nothrow_transformable() {
97 using when_all_sndr_t =
decltype(stdexec::when_all(
98 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>()),
99 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
102 static_assert(std::same_as<
103 stdexec::__demangle_t<when_all_sndr_t>,
108 Tests::Utils::basic_sender_t<
110 Tests::Utils::Functors::NoOp<false, false, false>,
116 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
118 stdexec::set_value_t,
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>())
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&&,
142 static_assert(!std::is_nothrow_constructible_v<Kokkos::Experimental::Graph<TEST_EXECUTION_SPACE>>);
144 using when_all_sndr_t =
decltype(stdexec::when_all(
145 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>()),
146 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
147 | stdexec::then(Tests::Utils::Functors::NoOp<false, false, false>{})));
149 static_assert(!stdexec::__nothrow_connectable<when_all_sndr_t, Tests::Utils::SinkReceiver>);
159template <
typename ExecA,
typename ExecB>
161 if constexpr (std::same_as<ExecA, ExecB>)
164 using sndr_t = stdexec::transform_sender_result_t<
165 decltype(stdexec::when_all(
174 stdexec::__not_a_sender<
175 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::CANNOT_DISPATCH_THIS_ALGORITHM_TO_THE_GRAPH_SCHEDULER),
176 stdexec::_WHY_(Kokkos::Execution::GraphImpl::BECAUSE_THE_EXECUTION_SPACE_TYPE_IS_NOT_HOMOGENEOUS),
177 stdexec::_WHERE_(stdexec::_IN_ALGORITHM_, stdexec::when_all_t),
182 stdexec::_WITH_SENDERS_<
193static_assert(test_sndr_cannot_mix_execution_space_type<TEST_EXECUTION_SPACE, Kokkos::DefaultHostExecutionSpace>());
207 experimental::execution::single_thread_context stc{};
210 auto sndr = stdexec::when_all(
212 stdexec::schedule(stc.get_scheduler()) | stdexec::continues_on(gctx.
get_scheduler()) | stdexec::then([]() { }));
221 testing::ElementsAre(
226 recorded_events.at(0),
246 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
252 static_assert(std::same_as<
253 decltype(stdexec::get_completion_domain<stdexec::set_value_t>(stdexec::get_env(sndr))),
257 static_assert(std::same_as<stdexec::tag_of_t<
decltype(sndr)>, stdexec::then_t>);
260 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
268 testing::ElementsAre(
275 ASSERT_EQ(data(), 1);
289 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
293 auto sndr = stdexec::when_all(
296 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
304 testing::ElementsAre(
309 recorded_events.at(0),
315 ASSERT_EQ(data(), 1);
329 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
336 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b));
338 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
346 testing::ElementsAre(
353 recorded_events.at(0),
359 ASSERT_EQ(data(), 2);
375 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
383 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b), std::move(branch_c));
385 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
393 testing::ElementsAre(
402 recorded_events.at(0),
409 ASSERT_EQ(data(), 3);
429 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc(
"data - shared space"));
431 experimental::execution::single_thread_context stc_a{}, stc_b{}, stc_c{};
438 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
439 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
441 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
442 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
443 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
445 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
446 auto branch_c = stdexec::schedule(stc_c.get_scheduler())
447 | stdexec::then(functor_h_t{.prev = 0, .value = 4, .data = &data_per_branch(2)})
449 | stdexec::then(functor_d_t{.prev = 4, .value = 5, .data = &data_per_branch(2)});
451 auto sndr = stdexec::when_all(
452 std::move(branch_a), std::move(branch_b), std::move(branch_c));
455 <<
"Eager execution is not " "allowed.";
466 testing::ElementsAre(
475 recorded_events.at(0),
499 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc(
"data - shared space"));
501 experimental::execution::single_thread_context stc_a{}, stc_b{};
508 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
509 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
511 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
512 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
513 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
515 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
517 | stdexec::then(functor_d_t{.prev = 0, .value = 4, .data = &data_per_branch(2)});
519 auto sndr = stdexec::when_all(
520 std::move(branch_a), std::move(branch_b), std::move(branch_c));
523 <<
"Eager execution is not " "allowed.";
534 testing::ElementsAre(
543 recorded_events.at(0),
563 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
565 std::atomic<size_t> count = 0;
571 stdexec::sender
auto sndr =
574 stdexec::read_env(stdexec::get_allocator)
575 | stdexec::then([&value](
auto allocator) { value = Tests::Utils::round_trip_allocate(allocator, 42); })
580 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
588 testing::ElementsAre(
593 recorded_events.at(0),
599 ASSERT_EQ(data(), 1);
601 ASSERT_EQ(value, 42);
constexpr std::string dispatch_label(const Exec &, Label &&label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
#define TEST_CATEGORY(_name_)
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_)
#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...
#define THEN_INCREMENT_ATOMIC(_scope_, _data_)
Same as THEN_INCREMENT, using Tests::Utils::atomic_fetch_add. // NOLINTNEXTLINE(cppcoreguidelines-mac...
consteval bool test_sndr_nothrow_transformable()
consteval bool test_sndr_traits()
consteval bool test_sndr_nothrow_connectable()
consteval bool test_sndr_cannot_mix_execution_space_type()
typename stdexec::__basic_sender< Args... >::type basic_sender_t
See https://github.com/NVIDIA/stdexec/pull/1873#discussion_r2834863237.
auto record_sync_wait(Sndr &&sndr)
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.
Execution context using Kokkos::Experimental::Graph under the hood.
auto get_scheduler() const noexcept -> GraphImpl::Scheduler< Exec >
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph aggregate node is added.
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph node is added.
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is created.
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is instantiated.
Event to be sent to Kokkos::utils::callbacks::dispatch when a Kokkos graph is submitted.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Similar to EventDiscardMatcher, for graph-related events.
Kokkos::View< value_t, Kokkos::SharedSpace > view_s_t
Kokkos::Execution::GraphContext< Exec > context_t
Load the value at data and check it is equal to prev. Then, add value to it.
Kokkos::Impl::DeviceHandle< Exec > device_handle_t
device_handle_t device_handle
A receiver that can handle all completions and does nothing with them.
A minimal tracking allocator.
#define MATCHER_FOR_GRAPH_CREATE(_device_handle_)
#define MATCHER_FOR_GRAPH_SUBMIT(_exec_, _graph_create_event_variant_)
#define MATCHER_FOR_GRAPH_ADDNODE(_graph_create_event_variant_, _device_handle_, _predecessor_)
#define MATCHER_FOR_GRAPH_ADD_AGGREGATE_NODE(_graph_create_event_variant_,...)
#define MATCHER_FOR_GRAPH_ROOT_NODE_OF(_graph_create_event_)
#define MATCHER_FOR_GRAPH_NODE_OF(_graph_add_node_event_)