54 static_assert(stdexec::__nothrow_connectable<schedule_from_sndr_t, Tests::Utils::SinkReceiver>);
70 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
75 const context_t esc_A{exec_A}, esc_B{exec_B};
82 auto schs_A_then = std::move(schs_A) |
THEN_LABELED(
'A');
84 const auto sch_B = esc_B.get_scheduler();
85 auto schs_A_then_con_B = std::move(schs_A_then)
86 | stdexec::continues_on(sch_B);
89 ASSERT_EQ(stdexec::get_completion_scheduler<stdexec::set_value_t>(stdexec::get_env(schs_A_then_con_B)), sch_B);
91 auto schs_A_then_con_B_then = std::move(schs_A_then_con_B)
94 static_assert(std::same_as<
95 stdexec::__demangle_t<
decltype(schs_A_then_con_B_then)>,
100 stdexec::continues_on_t,
103 stdexec::schedule_from_t,
117 auto schs_A_then_con_B_then_con_h_then = std::move(schs_A_then_con_B_then)
120 stdexec::get_completion_scheduler<stdexec::set_value_t>(stdexec::get_env(schs_A_then_con_B_then_con_h_then)),
123 auto op_state = stdexec::connect(
124 std::move(schs_A_then_con_B_then_con_h_then),
126 .state = std::addressof(esc_h.
m_state), .runloop_state =
nullptr, .result =
nullptr});
132 const auto& then_opstate = op_state;
138 Kokkos::RangePolicy<host_execution_space, Kokkos::LaunchBounds<1>>
141 static_assert(std::same_as<
decltype(then_opstate.inner_opstate.rcvr), then_rcvr_t>);
145 const auto& con_h_then_opstate = then_opstate.inner_opstate;
146 static_assert(stdexec::__is_instance_of<
147 std::remove_cvref_t<
decltype(con_h_then_opstate)>,
150 using con_h_then_rcvr_t =
decltype(con_h_then_opstate.inner_opstate.rcvr);
152 static_assert(std::same_as<
153 stdexec::env_of_t<con_h_then_rcvr_t>,
159 stdexec::__env::__fwd<Kokkos::Execution::Impl::SyncWait::env>
164 const auto& sfrom_con_h_then_opstate = con_h_then_opstate.inner_opstate;
165 static_assert(stdexec::__is_instance_of<
166 std::remove_cvref_t<
decltype(sfrom_con_h_then_opstate)>,
169 using sfrom_con_h_then_rcvr_t =
decltype(sfrom_con_h_then_opstate.inner_opstate.completion_signal.rcvr);
173 const auto& then_sfrom_con_h_then_opstate = sfrom_con_h_then_opstate.inner_opstate;
174 static_assert(stdexec::__is_instance_of<
175 std::remove_cvref_t<
decltype(then_sfrom_con_h_then_opstate)>,
178 using then_sfrom_con_h_then_rcvr_t =
decltype(then_sfrom_con_h_then_opstate.inner_opstate.rcvr);
179 static_assert(!stdexec::__queryable_with<
180 stdexec::env_of_t<then_sfrom_con_h_then_rcvr_t>,
184 const auto& con_B_then_sfrom_con_h_then_opstate = then_sfrom_con_h_then_opstate.inner_opstate;
185 static_assert(stdexec::__is_instance_of<
186 std::remove_cvref_t<
decltype(con_B_then_sfrom_con_h_then_opstate)>,
189 using con_B_then_sfrom_con_h_then_rcvr_t =
decltype(con_B_then_sfrom_con_h_then_opstate.inner_opstate.rcvr);
190 static_assert(stdexec::__queryable_with<
191 stdexec::env_of_t<con_B_then_sfrom_con_h_then_rcvr_t>,
194 static_assert(std::same_as<
195 stdexec::env_of_t<con_B_then_sfrom_con_h_then_rcvr_t>,
201 stdexec::__env::__fwd<stdexec::env<
206 stdexec::__env::__fwd<Kokkos::Execution::Impl::SyncWait::env>
215 const auto& sfrom_con_B_then_sfrom_con_h_then_opstate = con_B_then_sfrom_con_h_then_opstate.inner_opstate;
216 static_assert(stdexec::__is_instance_of<
217 std::remove_cvref_t<
decltype(sfrom_con_B_then_sfrom_con_h_then_opstate)>,
220 using sfrom_con_B_then_sfrom_con_h_then_rcvr_t =
decltype(sfrom_con_B_then_sfrom_con_h_then_opstate.inner_opstate
221 .completion_signal.rcvr);
222 static_assert(!stdexec::__queryable_with<
223 stdexec::env_of_t<sfrom_con_B_then_sfrom_con_h_then_rcvr_t>,
227 const auto& then_sfrom_B_then_sfrom_con_h_then_opstate = sfrom_con_B_then_sfrom_con_h_then_opstate.inner_opstate;
228 static_assert(stdexec::__is_instance_of<
229 std::remove_cvref_t<
decltype(then_sfrom_B_then_sfrom_con_h_then_opstate)>,
232 using then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t =
decltype(then_sfrom_B_then_sfrom_con_h_then_opstate
233 .inner_opstate.rcvr);
234 static_assert(!stdexec::__queryable_with<
235 stdexec::env_of_t<then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t>,
242 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
248 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
252 ::testing::ElementsAre(
256 ASSERT_EQ(data(), 1);
266 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
274 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
278 ::testing::ElementsAre(
284 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
291TEST_F(
ContinuesOnTest, transition_to_another_execution_space_instance_and_back_same_type) {
292 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
294 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
305 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
312 ::testing::ElementsAre(
325 ::testing::ElementsAre(
333 ::testing::ElementsAre(
343 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
350TEST_F(
ContinuesOnTest, transition_to_another_execution_space_instance_and_back_different_type) {
351 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
362 using level_B_env_t = stdexec::__env::__fwd<stdexec::env<
367 stdexec::__env::__fwd<level_C_env_t>
369 using level_A_env_t = stdexec::__env::__fwd<stdexec::env<
382 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
389 ::testing::ElementsAre(
394 }
else if constexpr (
396 && std::same_as<host_execution_space, TEST_EXECUTION_SPACE>) {
399 ::testing::ElementsAre(
411 ::testing::ElementsAre(
420 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
425 using continues_on_sndr_t =
426 decltype(stdexec::just() | stdexec::continues_on(std::declval<typename ContinuesOnTest::scheduler_t>()));
428 static_assert(std::same_as<
429 stdexec::__demangle_t<continues_on_sndr_t>,
431 stdexec::continues_on_t,
434 stdexec::schedule_from_t,
441 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
443 stdexec::set_value_t,
444 continues_on_sndr_t&&,
448 using schedule_from_sndr_t =
decltype(stdexec::schedule_from(
449 stdexec::schedule(std::declval<typename ContinuesOnTest::scheduler_t>())));
451 static_assert(std::same_as<
452 stdexec::__demangle_t<schedule_from_sndr_t>,
454 stdexec::schedule_from_t,
460 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
462 stdexec::set_value_t,
463 schedule_from_sndr_t&&,
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_BEGIN_PFOR(_exec_, _label_)
#define MATCHER_FOR_RECORD_EVENT(_exec_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
RecorderListener< EventDiscardMatcher< TEST_EXECUTION_SPACE >, BeginFenceEvent, BeginParallelForEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent > recorder_listener_t
Determine if the Kokkos backend can enqueue a wait for an event into an execution space instance.
Kokkos::DefaultHostExecutionSpace host_execution_space
#define THEN_INCREMENT(_data_)
Add a then using Tests::Utils::Functors::Increment that may throw. // NOLINTNEXTLINE(cppcoreguideline...
#define THEN_LABELED(_id_)
Add a then using Tests::Utils::Functors::Labeled. // NOLINTNEXTLINE(cppcoreguidelines-macro-usage).
constexpr get_exec_t get_exec
consteval bool test_schedule_from_sndr_traits()
consteval bool test_sndr_nothrow_transformable()
consteval bool test_continues_on_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)
constexpr check_rcvr_env_t< ExpectedEnv > check_rcvr_env
bool are_same_instances(const Exec &exec, const OtherExec &other_exec)
Matcher to filter out events that are just noise for tests.
Execution context using a Kokkos execution space under the hood.
auto get_scheduler() const noexcept -> ExecutionSpaceImpl::Scheduler< Exec >
Inspired by https://github.com/kokkos/kokkos/blob/69273c3a4e7b6adeb95066341ca201d62fe1e698/core/src/i...
Wrap a Kokkos execution space to make it cheap to copy/move in new environments.
Receiver for an object parent_op that implements complete.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Receiver for stdexec::sync_wait.
Inspired by https://github.com/NVIDIA/stdexec/blob/16076a81efa4477513e6ede9c2741fd034ecef99/include/s...
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
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::ExecutionSpaceContext< Exec > context_t