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>())
101 static_assert(std::same_as<
102 stdexec::__demangle_t<when_all_sndr_t>,
114 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
116 stdexec::set_value_t,
121 using when_all_maythrow_on_move_sndr_t =
decltype(stdexec::when_all(
122 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
125 static_assert(!stdexec::__detail::__has_nothrow_transform_sender<
126 Kokkos::Execution::GraphImpl::Domain,
127 stdexec::set_value_t,
128 when_all_maythrow_on_move_sndr_t&&,
139 static_assert(!std::is_nothrow_constructible_v<Kokkos::Experimental::Graph<TEST_EXECUTION_SPACE>>);
141 using when_all_sndr_t =
decltype(stdexec::when_all(
142 stdexec::schedule(std::declval<
typename TEST_CATEGORY(WhenAllTest)::scheduler_t>())
143 | stdexec::then(Tests::Utils::Functors::NoOp<false, false, false>{})));
145 static_assert(!stdexec::__nothrow_connectable<when_all_sndr_t, Tests::Utils::SinkReceiver>);
155template <
typename ExecA,
typename ExecB>
157 if constexpr (std::same_as<ExecA, ExecB>)
160 using sndr_t = stdexec::transform_sender_result_t<
161 decltype(stdexec::when_all(
170 stdexec::__not_a_sender<
171 stdexec::_WHAT_(Kokkos::Execution::GraphImpl::CANNOT_DISPATCH_THIS_ALGORITHM_TO_THE_GRAPH_SCHEDULER),
172 stdexec::_WHY_(Kokkos::Execution::GraphImpl::BECAUSE_THE_EXECUTION_SPACE_TYPE_IS_NOT_HOMOGENEOUS),
173 stdexec::_WHERE_(stdexec::_IN_ALGORITHM_, stdexec::when_all_t),
178 stdexec::_WITH_SENDERS_<
189static_assert(test_sndr_cannot_mix_execution_space_type<TEST_EXECUTION_SPACE, Kokkos::DefaultHostExecutionSpace>());
196 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
202 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
210 testing::ElementsAre(
218 ASSERT_EQ(data(), 1);
226 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
233 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b));
235 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
243 testing::ElementsAre(
248 recorded_events.at(0),
254 ASSERT_EQ(data(), 2);
262 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
270 auto sndr = stdexec::when_all(std::move(branch_a), std::move(branch_b), std::move(branch_c));
272 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
280 testing::ElementsAre(
286 recorded_events.at(0),
293 ASSERT_EQ(data(), 3);
305 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc(
"data - shared space"));
307 experimental::execution::single_thread_context stc_a{}, stc_b{}, stc_c{};
314 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
315 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
317 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
318 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
319 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
321 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
322 auto branch_c = stdexec::schedule(stc_c.get_scheduler())
323 | stdexec::then(functor_h_t{.prev = 0, .value = 4, .data = &data_per_branch(2)})
325 | stdexec::then(functor_d_t{.prev = 4, .value = 5, .data = &data_per_branch(2)});
327 auto sndr = stdexec::when_all(
328 std::move(branch_a), std::move(branch_b), std::move(branch_c));
331 <<
"Eager execution is not " "allowed.";
342 testing::ElementsAre(
348 recorded_events.at(0),
364 const Kokkos::View<value_t[3], Kokkos::SharedSpace> data_per_branch(Kokkos::view_alloc(
"data - shared space"));
366 experimental::execution::single_thread_context stc_a{}, stc_b{};
373 auto branch_a = stdexec::schedule(stc_a.get_scheduler())
374 | stdexec::then(functor_h_t{.prev = 0, .value = 2, .data = &data_per_branch(0)})
376 | stdexec::then(functor_d_t{.prev = 2, .value = 3, .data = &data_per_branch(0)});
377 auto branch_b = stdexec::schedule(stc_b.get_scheduler())
378 | stdexec::then(functor_h_t{.prev = 0, .value = 3, .data = &data_per_branch(1)})
380 | stdexec::then(functor_d_t{.prev = 3, .value = 4, .data = &data_per_branch(1)});
382 | stdexec::then(functor_d_t{.prev = 0, .value = 4, .data = &data_per_branch(2)});
384 auto sndr = stdexec::when_all(
385 std::move(branch_a), std::move(branch_b), std::move(branch_c));
388 <<
"Eager execution is not " "allowed.";
399 testing::ElementsAre(
405 recorded_events.at(0),
417 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
419 std::atomic<size_t> count = 0;
425 stdexec::sender
auto sndr =
427 stdexec::read_env(stdexec::get_allocator)
433 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
441 testing::ElementsAre(
449 ASSERT_EQ(data(), 1);
451 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.
auto round_trip_allocate(Allocator &allocator, T &&value)
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_NODE_OF(_graph_add_node_event_)