46 static_assert(stdexec::__nothrow_connectable<schedule_from_sndr_t, Tests::Utils::SinkReceiver>);
62 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
67 const context_t esc_A{exec_A}, esc_B{exec_B};
72 static_assert(!stdexec::__queryable_with<
73 decltype(stdexec::get_env(schs_A)),
77 auto schs_A_then = std::move(schs_A) |
THEN_LABELED(
'A');
79 const auto sch_B = esc_B.get_scheduler();
80 auto schs_A_then_con_B = std::move(schs_A_then)
81 | stdexec::continues_on(sch_B);
84 ASSERT_EQ(stdexec::get_completion_scheduler<stdexec::set_value_t>(stdexec::get_env(schs_A_then_con_B)), sch_B);
86 auto schs_A_then_con_B_then = std::move(schs_A_then_con_B)
89 static_assert(std::same_as<
90 stdexec::__demangle_t<
decltype(schs_A_then_con_B_then)>,
95 stdexec::continues_on_t,
98 stdexec::schedule_from_t,
112 auto schs_A_then_con_B_then_con_h_then = std::move(schs_A_then_con_B_then)
115 stdexec::get_completion_scheduler<stdexec::set_value_t>(stdexec::get_env(schs_A_then_con_B_then_con_h_then)),
118 auto op_state = stdexec::connect(
119 std::move(schs_A_then_con_B_then_con_h_then),
121 .state = std::addressof(esc_h.
m_state), .runloop_state =
nullptr, .result =
nullptr});
124 constexpr auto check_env = []<
typename T, Kokkos::ExecutionSpace Exec>()
constexpr ->
bool {
126 stdexec::env_of_t<T>,
127 stdexec::__env::__fwd<stdexec::env<
132 stdexec::__env::__fwd<Kokkos::Execution::Impl::env>
147 Kokkos::RangePolicy<host_execution_space, Kokkos::LaunchBounds<1>>
150 static_assert(std::same_as<
decltype(op_state.inner_opstate.rcvr.rcvr.rcvr), then_rcvr_t>);
160 static_assert(std::same_as<
decltype(op_state.inner_opstate.rcvr.rcvr), con_h_then_rcvr_t>);
161 static_assert(stdexec::__queryable_with<
162 stdexec::env_of_t<con_h_then_rcvr_t>,
171 using sfrom_con_h_then_rcvr_t =
173 static_assert(std::same_as<
decltype(op_state.inner_opstate.rcvr), sfrom_con_h_then_rcvr_t>);
174 static_assert(stdexec::__queryable_with<
175 stdexec::env_of_t<sfrom_con_h_then_rcvr_t>,
178 static_assert(check_env.template operator()<sfrom_con_h_then_rcvr_t, TEST_EXECUTION_SPACE>());
182 using then_sfrom_con_h_then_rcvr_t =
184 sfrom_con_h_then_rcvr_t,
188 Kokkos::RangePolicy<TEST_EXECUTION_SPACE, Kokkos::LaunchBounds<1>>
192 std::same_as<
decltype(op_state.inner_opstate.inner_opstate.rcvr.rcvr.rcvr), then_sfrom_con_h_then_rcvr_t>);
193 static_assert(stdexec::__queryable_with<
194 stdexec::env_of_t<then_sfrom_con_h_then_rcvr_t>,
197 static_assert(check_env.template operator()<then_sfrom_con_h_then_rcvr_t, TEST_EXECUTION_SPACE>());
200 stdexec::get_env(op_state.inner_opstate.inner_opstate.rcvr.rcvr.rcvr))
204 using con_B_then_sfrom_con_h_then_rcvr_t =
207 std::same_as<
decltype(op_state.inner_opstate.inner_opstate.rcvr.rcvr), con_B_then_sfrom_con_h_then_rcvr_t>);
208 static_assert(stdexec::__queryable_with<
209 stdexec::env_of_t<con_B_then_sfrom_con_h_then_rcvr_t>,
212 static_assert(check_env.template operator()<con_B_then_sfrom_con_h_then_rcvr_t, TEST_EXECUTION_SPACE>());
215 stdexec::get_env(op_state.inner_opstate.inner_opstate.rcvr.rcvr))
219 using sfrom_con_B_then_sfrom_con_h_then_rcvr_t =
222 std::same_as<
decltype(op_state.inner_opstate.inner_opstate.rcvr), sfrom_con_B_then_sfrom_con_h_then_rcvr_t>);
223 static_assert(stdexec::__queryable_with<
224 stdexec::env_of_t<sfrom_con_B_then_sfrom_con_h_then_rcvr_t>,
227 static_assert(check_env.template operator()<sfrom_con_B_then_sfrom_con_h_then_rcvr_t, TEST_EXECUTION_SPACE>());
233 using then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t =
235 sfrom_con_B_then_sfrom_con_h_then_rcvr_t,
239 Kokkos::RangePolicy<TEST_EXECUTION_SPACE, Kokkos::LaunchBounds<1>>
242 static_assert(std::same_as<
243 decltype(op_state.inner_opstate.inner_opstate.inner_opstate.rcvr),
244 then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t
246 static_assert(stdexec::__queryable_with<
247 stdexec::env_of_t<then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t>,
250 static_assert(check_env.template operator()<then_sfrom_con_B_then_sfrom_con_h_then_rcvr_t, TEST_EXECUTION_SPACE>());
253 stdexec::get_env(op_state.inner_opstate.inner_opstate.inner_opstate.rcvr))
260 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
266 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
269 recorder_listener_t::record([chain = std::move(chain)]()
mutable { stdexec::sync_wait(std::move(chain)); }),
270 ::testing::ElementsAre(
274 ASSERT_EQ(data(), 1);
284 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
292 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
295 recorder_listener_t::record([chain = std::move(chain)]()
mutable { stdexec::sync_wait(std::move(chain)); }),
296 ::testing::ElementsAre(
302 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
309TEST_F(
ContinuesOnTest, transition_to_another_execution_space_instance_and_back_same_type) {
310 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
312 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
323 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
325 const auto recorded_events = recorder_listener_t::record(
326 [chain = std::move(chain)]()
mutable { stdexec::sync_wait(std::move(chain)); });
331 ::testing::ElementsAre(
339 ::testing::ElementsAre(
348 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
355TEST_F(
ContinuesOnTest, transition_to_another_execution_space_instance_and_back_different_type) {
356 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
370 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
372 const auto recorded_events = recorder_listener_t::record(
373 [chain = std::move(chain)]()
mutable { stdexec::sync_wait(std::move(chain)); });
378 ::testing::ElementsAre(
386 ::testing::ElementsAre(
395 ASSERT_EQ(data(), 3) <<
"A synchronization is missing.";
401 decltype(stdexec::just_stopped() | stdexec::continues_on(std::declval<typename ContinuesOnTest::scheduler_t>()) | stdexec::then([]() {
418 using sndr_continues_on_t =
419 decltype(stdexec::just() | stdexec::continues_on(std::declval<typename ContinuesOnTest::scheduler_t>()));
421 static_assert(std::same_as<
422 stdexec::__demangle_t<sndr_continues_on_t>,
424 stdexec::continues_on_t,
427 stdexec::schedule_from_t,
434 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
436 stdexec::set_value_t,
437 sndr_continues_on_t&&,
441 using sndr_schedule_from_t =
decltype(stdexec::schedule_from(
442 stdexec::schedule(std::declval<typename ContinuesOnTest::scheduler_t>())));
444 static_assert(std::same_as<
445 stdexec::__demangle_t<sndr_schedule_from_t>,
447 stdexec::schedule_from_t,
453 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
455 stdexec::set_value_t,
456 sndr_schedule_from_t&&,
constexpr std::string dispatch_label(const Exec &, Label &&label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_PFOR(_exec_, _label_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
RecorderListener< EventDiscardMatcher< TEST_EXECUTION_SPACE >, BeginFenceEvent, BeginParallelForEvent > recorder_listener_t
#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_no_throw_transformable()
consteval bool test_continues_on_after_just_stopped()
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.
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 a Kokkos execution space under the hood.
auto get_scheduler() const noexcept -> ExecutionSpaceImpl::Scheduler< Exec >
Receiver for continues_on.
Wrap a Kokkos execution space to make it cheap to copy/move in new environments.
Receiver for schedule_from.
Sender for schedule_from.
Inspired by https://github.com/kokkos/kokkos/blob/69273c3a4e7b6adeb95066341ca201d62fe1e698/core/src/i...
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
Kokkos::DefaultHostExecutionSpace host_execution_space