4#include "exec/single_thread_context.hpp"
40using namespace Kokkos::utils::callbacks;
42class TEST_CATEGORY(ContinuesOnTest)
69 static_assert(stdexec::__nothrow_connectable<schedule_from_sndr_t, Tests::Utils::SinkReceiver>);
70 static_assert(stdexec::__nothrow_connectable<const schedule_from_sndr_t&, Tests::Utils::SinkReceiver>);
74static_assert(test_schedule_from_sndr_traits());
85 static_assert(stdexec::__nothrow_connectable<continues_on_sndr_t, Tests::Utils::SinkReceiver>);
86 static_assert(stdexec::__nothrow_connectable<const continues_on_sndr_t&, Tests::Utils::SinkReceiver>);
99 static_assert(std::same_as<
100 stdexec::connect_result_t<
101 const continues_on_sndr_t&,
113static_assert(test_continues_on_sndr_traits());
116consteval bool test_sndr_nothrow_transformable() {
117 using continues_on_sndr_t =
118 decltype(stdexec::just() | stdexec::continues_on(std::declval<
typename TEST_CATEGORY(ContinuesOnTest)::scheduler_t>()));
120 static_assert(std::same_as<
121 stdexec::__demangle_t<continues_on_sndr_t>,
123 stdexec::continues_on_t,
133 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
135 stdexec::set_value_t,
136 continues_on_sndr_t&&,
140 using schedule_from_sndr_t =
decltype(stdexec::schedule_from(
141 stdexec::schedule(std::declval<
typename TEST_CATEGORY(ContinuesOnTest)::scheduler_t>())));
143 static_assert(std::same_as<
144 stdexec::__demangle_t<schedule_from_sndr_t>,
146 stdexec::schedule_from_t,
152 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
154 stdexec::set_value_t,
155 schedule_from_sndr_t&&,
161static_assert(test_sndr_nothrow_transformable());
168 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
171 experimental::execution::single_thread_context stc{};
176 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
177 | stdexec::continues_on(stc.get_scheduler()) | stdexec::continues_on(gctx.
get_scheduler())
178 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
181 stdexec::continues_on_t,
184 stdexec::schedule_from_t,
187 stdexec::continues_on_t,
188 stdexec::run_loop::scheduler,
190 stdexec::schedule_from_t,
202 using transform_sender_result_t =
203 stdexec::transform_sender_result_t<
decltype(sndr), stdexec::env_of_t<sync_wait_rcvr_t>>;
204 static_assert(std::same_as<
205 stdexec::__demangle_t<transform_sender_result_t>,
209 using connect_result_t = stdexec::connect_result_t<
decltype(sndr),
sync_wait_rcvr_t>;
210 static_assert(std::same_as<
211 stdexec::__demangle_t<connect_result_t>,
219 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
228 testing::ElementsAre(
238 ASSERT_EQ(data(), 7);
247 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
254 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
256 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
258 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
265 testing::ElementsAre(
274 ASSERT_EQ(data(), 7);
286 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
288 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
293 const context_t gctx_A{exec_A}, gctx_B{exec_B};
294 const device_handle_t device_handle_A{exec_A}, device_handle_B{exec_B};
299 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
300 | stdexec::continues_on(gctx_B.get_scheduler())
301 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
303 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
311 testing::ElementsAre(
325 testing::ElementsAre(
336 testing::ElementsAre(
348 ASSERT_EQ(data(), 7);
361 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
363 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
368 const context_t gctx_A{exec_A}, gctx_B{exec_B};
369 const device_handle_t device_handle_A{exec_A}, device_handle_B{exec_B};
374 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
375 | stdexec::continues_on(gctx_B.get_scheduler())
376 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()})
378 | stdexec::then(functor_t{.prev = 7, .value = 2, .data = data.data()});
380 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
386 ASSERT_THAT(recorded_events, testing::SizeIs(14));
389 testing::ElementsAre(
408 testing::ElementsAre(
420 ASSERT_THAT(recorded_events, testing::SizeIs(12));
423 testing::ElementsAre(
439 ASSERT_EQ(data(), 9);
444 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
446 const Kokkos::DefaultHostExecutionSpace exec_h{};
451 const auto device_handle_h = Kokkos::Experimental::get_device_handle(exec_h);
457 | stdexec::then(functor_device_t{.prev = 0, .value = 4, .data = data.data()})
459 | stdexec::then(functor_host_t{.prev = 4, .value = 3, .data = data.data()})
461 | stdexec::then(functor_device_t{.prev = 7, .value = 2, .data = data.data()});
463 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
471 testing::ElementsAre(
482 }
else if constexpr (
484 && std::same_as<Kokkos::DefaultHostExecutionSpace, TEST_EXECUTION_SPACE>) {
487 testing::ElementsAre(
505 testing::ElementsAre(
520 ASSERT_EQ(data(), 9);
constexpr std::string dispatch_label(const Exec &, Label &&label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_WAIT_EXEC_EVENT(_exec_, _record_event_variant_)
#define MATCHER_FOR_RECORD_EVENT(_exec_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
#define TEST_CATEGORY(_name_)
Kokkos::Execution::Impl::SyncWait::Receiver< TEST_EXECUTION_SPACE, std::true_type > sync_wait_rcvr_t
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::GraphAddNodeEvent, Kokkos::Execution::GraphImpl::GraphCreateEvent, Kokkos::Execution::GraphImpl::GraphInstantiateEvent, Kokkos::Execution::GraphImpl::GraphSubmitEvent > recorder_listener_t
Determine if the Kokkos backend can enqueue a wait for an event into an execution space instance.
#define KOKKOS_EXECUTION_THREADS_THROWS_ON_SYNC_WAIT_ASSERT_AND_SKIP(_sndr_)
#define KOKKOS_EXECUTION_STDEXEC_PRAGMA_DIAGNOSTIC_IGNORED
Basic list of ignored diagnostics when including anything from stdexec.
consteval bool test_continues_on_sndr_traits()
consteval bool test_schedule_from_sndr_traits()
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)
consteval bool check_continues_on()
Check how the scheduler customizes stdexec::continues_on.
void show_exec_space_id(const Exec &exec, std::string_view label="", std::ostream &out=std::cout)
bool are_same_instances(const Exec &exec, const OtherExec &other_exec)
Execution context using Kokkos::Experimental::Graph under the hood.
auto get_scheduler() const noexcept -> GraphImpl::Scheduler< Exec >
Operation state for stdexec::continues_on.
Sender for stdexec::continues_on.
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.
Operation state that adds all closures as a sequence of nodes.
Sender for stdexec::schedule_from.
Sender for stdexec::then.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Receiver for stdexec::sync_wait.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Similar to EventDiscardMatcher, for graph-related events.
decltype(std::declval< const context_t >().get_scheduler()) scheduler_t
decltype(stdexec::schedule(std::declval< scheduler_t >())) schedule_sender_t
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
#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_)