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>);
75static_assert(test_schedule_from_sndr_traits());
86 static_assert(stdexec::__nothrow_connectable<continues_on_sndr_t, Tests::Utils::SinkReceiver>);
87 static_assert(stdexec::__nothrow_connectable<const continues_on_sndr_t&, Tests::Utils::SinkReceiver>);
100 static_assert(std::same_as<
101 stdexec::connect_result_t<
102 const continues_on_sndr_t&,
115static_assert(test_continues_on_sndr_traits());
118consteval bool test_sndr_nothrow_transformable() {
119 using continues_on_sndr_t =
120 decltype(stdexec::just() | stdexec::continues_on(std::declval<
typename TEST_CATEGORY(ContinuesOnTest)::scheduler_t>()));
122 static_assert(std::same_as<
125 stdexec::continues_on_t,
131 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
133 stdexec::set_value_t,
134 continues_on_sndr_t&&,
138 using schedule_from_sndr_t =
decltype(stdexec::schedule_from(
139 stdexec::schedule(std::declval<
typename TEST_CATEGORY(ContinuesOnTest)::scheduler_t>())));
141 static_assert(std::same_as<
142 schedule_from_sndr_t,
144 stdexec::schedule_from_t,
150 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
152 stdexec::set_value_t,
153 schedule_from_sndr_t&&,
160static_assert(test_sndr_nothrow_transformable());
167 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
170 experimental::execution::single_thread_context stc{};
175 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
176 | stdexec::continues_on(stc.get_scheduler()) | stdexec::continues_on(gctx.
get_scheduler())
177 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
179 using inner_sndr_t = stdexec::__sexpr<
180 stdexec::continues_on_t,
183 stdexec::schedule_from_t,
186 stdexec::continues_on_t,
187 stdexec::run_loop::scheduler,
189 stdexec::schedule_from_t,
197 using transform_sender_result_t =
198 stdexec::transform_sender_result_t<
decltype(sndr), stdexec::env_of_t<sync_wait_rcvr_t>>;
199 static_assert(std::same_as<
200 transform_sender_result_t,
204 using connect_result_t = stdexec::connect_result_t<
decltype(sndr),
sync_wait_rcvr_t>;
205 static_assert(std::same_as<
214 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
223 testing::ElementsAre(
235 ASSERT_EQ(data(), 7);
244 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
251 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
253 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
255 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
262 testing::ElementsAre(
273 ASSERT_EQ(data(), 7);
285 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
287 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
292 const context_t gctx_A{exec_A}, gctx_B{exec_B};
293 const device_handle_t device_handle_A{exec_A}, device_handle_B{exec_B};
298 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
299 | stdexec::continues_on(gctx_B.get_scheduler())
300 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()});
302 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
310 testing::ElementsAre(
326 testing::ElementsAre(
339 testing::ElementsAre(
353 ASSERT_EQ(data(), 7);
366 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
368 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
373 const context_t gctx_A{exec_A}, gctx_B{exec_B};
374 const device_handle_t device_handle_A{exec_A}, device_handle_B{exec_B};
379 | stdexec::then(functor_t{.prev = 0, .value = 4, .data = data.data()})
380 | stdexec::continues_on(gctx_B.get_scheduler())
381 | stdexec::then(functor_t{.prev = 4, .value = 3, .data = data.data()})
383 | stdexec::then(functor_t{.prev = 7, .value = 2, .data = data.data()});
385 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
391 ASSERT_THAT(recorded_events, testing::SizeIs(14));
394 testing::ElementsAre(
416 testing::ElementsAre(
431 ASSERT_THAT(recorded_events, testing::SizeIs(12));
434 testing::ElementsAre(
453 ASSERT_EQ(data(), 9);
458 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
460 const Kokkos::DefaultHostExecutionSpace exec_h{};
465 const auto device_handle_h = Kokkos::Experimental::get_device_handle(exec_h);
471 | stdexec::then(functor_device_t{.prev = 0, .value = 4, .data = data.data()})
473 | stdexec::then(functor_host_t{.prev = 4, .value = 3, .data = data.data()})
475 | stdexec::then(functor_device_t{.prev = 7, .value = 2, .data = data.data()});
477 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
485 testing::ElementsAre(
499 }
else if constexpr (
501 && std::same_as<Kokkos::DefaultHostExecutionSpace, TEST_EXECUTION_SPACE>) {
504 testing::ElementsAre(
525 testing::ElementsAre(
543 ASSERT_EQ(data(), 9);
constexpr std::string dispatch_label(const Exec &, const std::string_view 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_)
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
Kokkos::Execution::Impl::SyncWait::Receiver< TEST_EXECUTION_SPACE, std::true_type > sync_wait_rcvr_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()
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< execution_space >
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_ADDNODE(_graph_create_event_variant_, _device_handle_, _predecessor_,...)
#define MATCHER_FOR_GRAPH_SUBMIT(_exec_, _graph_create_event_variant_)
#define MATCHER_FOR_GRAPH_ROOT_NODE_OF(_graph_create_event_)