4#include "exec/single_thread_context.hpp"
39using namespace Kokkos::utils::callbacks;
68 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
74 static_assert(std::same_as<
75 decltype(stdexec::get_completion_domain<stdexec::set_value_t>(stdexec::get_env(sndr))),
79 static_assert(std::same_as<stdexec::tag_of_t<
decltype(sndr)>, stdexec::then_t>);
84 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
106 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
110 auto sndr = stdexec::when_all(
113 static_assert(std::same_as<
114 decltype(stdexec::get_completion_domain<stdexec::set_value_t>(stdexec::get_env(sndr))),
122 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
128 ASSERT_THAT(recorded_events, [&]() {
130 return testing::ElementsAre(
135 return testing::ElementsAre(
141 ASSERT_EQ(data(), 1);
155TEST_F(
WhenAllTest, schedule_sender_and_single_branch_followed_by_self) {
156 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
160 auto sndr = stdexec::when_all(
165 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
169 testing::ElementsAre(
174 ASSERT_EQ(data(), 2);
189TEST_F(
WhenAllTest, schedule_sender_and_single_mixed_branch_followed_by_self) {
190 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
193 experimental::execution::single_thread_context stc{};
195 auto sndr = stdexec::when_all(
196 stdexec::schedule(stc.get_scheduler()),
198 | stdexec::continues_on(stc.get_scheduler()) |
THEN_INCREMENT(data))
201 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
207 testing::ElementsAre(
213 ASSERT_EQ(data(), 3);
227TEST_F(
WhenAllTest, schedule_sender_and_single_branch_followed_by_other_and_finish_on_self) {
228 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
231 experimental::execution::single_thread_context stc{};
233 auto sndr = stdexec::when_all(
236 | stdexec::continues_on(stc.get_scheduler()) |
THEN_INCREMENT(data)
239 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
245 ASSERT_THAT(recorded_events, [&]() {
247 return testing::ElementsAre(
254 return testing::ElementsAre(
262 ASSERT_EQ(data(), 3);
276 const view_s_t data(Kokkos::view_alloc(
"data - shared space"));
279 experimental::execution::single_thread_context stc{};
281 auto w_a = stdexec::when_all(
288 decltype(stdexec::get_completion_domain<stdexec::set_value_t>(stdexec::get_env(w_a), stdexec::env<>{})),
294 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
300 testing::ElementsAre(
305 ASSERT_EQ(data(), 3);
319 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
321 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(
exec, 1, 1);
323 const context_t esc_A{exec_A}, esc_B{exec_B};
325 auto sndr = stdexec::when_all(
330 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
337 testing::ElementsAre(
343 ASSERT_THAT(recorded_events, [&]() {
345 return testing::ElementsAre(
354 return testing::ElementsAre(
364 ASSERT_EQ(data(), 3);
378 static_assert(std::same_as<stdexec::tag_of_t<
decltype(sndr)>, stdexec::when_all_t>);
379 static_assert(std::same_as<
380 stdexec::__completion_domain_of_t<stdexec::set_value_t,
decltype(sndr)>,
387 ASSERT_THAT(recorded_events, testing::IsEmpty());
404 const view_s_t data(Kokkos::view_alloc(
"data - shared space"));
409 const context_h_t esc_h{exec_h};
411 auto sndr = stdexec::when_all(
416 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
423 testing::ElementsAre(
429 ASSERT_THAT(recorded_events, [&]() {
431 return testing::ElementsAre(
439 return testing::ElementsAre(
449 ASSERT_EQ(data(), 3);
463TEST_F(
WhenAllTest, two_mixed_branches_followed_by_other_and_finish_on_self) {
464 const view_s_t data(Kokkos::view_alloc(
"data - shared space"));
467 experimental::execution::single_thread_context stc{};
469 auto sndr = stdexec::when_all(
471 | stdexec::continues_on(stc.get_scheduler()),
473 | stdexec::continues_on(stc.get_scheduler()) |
THEN_INCREMENT(data)
476 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
482 testing::ElementsAre(
488 ASSERT_EQ(data(), 4);
509 const view_s_t data(Kokkos::view_alloc(
"data - shared space"));
512 experimental::execution::single_thread_context stc{};
514 auto sndr = stdexec::when_all(
524 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
530 ASSERT_THAT(recorded_events, [&]() {
532 return testing::ElementsAre(
540 return testing::ElementsAre(
549 ASSERT_EQ(data(), 4);
564 const auto [exec_A, exec_B, exec_C] = Kokkos::Experimental::partition_space(
exec, 1, 1, 1);
566 const context_t esc_A{exec_A}, esc_B{exec_B}, esc_C{exec_C};
569 auto br_B = ::stdexec::schedule(esc_B.get_scheduler()) |
THEN_LABELED_PFOR(TEST_EXECUTION_SPACE,
'B');
570 auto br_C = ::stdexec::schedule(esc_C.get_scheduler()) |
THEN_LABELED_PFOR(TEST_EXECUTION_SPACE,
'C');
572 auto when_AB_then_D = ::stdexec::when_all(std::move(br_A), std::move(br_B))
575 auto sndr = ::stdexec::when_all(std::move(when_AB_then_D), std::move(br_C));
582 testing::ElementsAre(
590 ASSERT_THAT(recorded_events, [&]() {
592 return testing::ElementsAre(
604 return testing::ElementsAre(
630 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
632 constexpr size_t num_branches = 6;
634 unsigned int counter_start = 0, counter_after_stc = 0;
635 std::array<unsigned int, num_branches> order_start{}, order_after_stc{};
637 const auto [exec_A, exec_B, exec_C, exec_D, exec_E, exec_F] =
638 Kokkos::Experimental::partition_space(
exec, 1, 1, 1, 1, 1, 1);
640 using view_um_h_t = Kokkos::View<unsigned int, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
643#define DEFINE_ONE_BRANCH(_letter_, _id_) \
644 const context_t esc_##_letter_{exec_##_letter_}; \
645 experimental::execution::single_thread_context stc_##_letter_{}; \
646 auto br_##_letter_ = stdexec::just() \
648 increment_and_memorize_t{ \
649 .counter = view_um_h_t{std::addressof(counter_start)}, \
650 .value = view_um_h_t{std::addressof(order_start.at(_id_))}}) \
651 | stdexec::continues_on(stc_##_letter_.get_scheduler()) \
653 increment_and_memorize_t{ \
654 .counter = view_um_h_t{std::addressof(counter_after_stc)}, \
655 .value = view_um_h_t{std::addressof(order_after_stc.at(_id_))}}) \
656 | stdexec::continues_on(esc_##_letter_.get_scheduler()) | THEN_INCREMENT_ATOMIC(Device, data);
665 auto sndr = stdexec::when_all(
666 std::move(br_A), std::move(br_B), std::move(br_C), std::move(br_D), std::move(br_E), std::move(br_F));
668 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
672 stdexec::sync_wait(std::move(sndr));
674 ASSERT_EQ(counter_start, num_branches);
675 ASSERT_EQ(counter_after_stc, num_branches);
677 ASSERT_EQ(data(), num_branches);
680 ASSERT_THAT(order_start, testing::ElementsAre(0, 1, 2, 3, 4, 5));
685#define SHOW_ONE_BRANCH_ORDER_AFTER_STC(_letter_, _id_) \
686 SCOPED_TRACE(testing::Message() << "Branch " #_letter_ " order after 'stc' is " << order_after_stc.at(_id_));
696 ASSERT_THAT(order_after_stc, testing::UnorderedElementsAre(0, 1, 2, 3, 4, 5));
constexpr std::string dispatch_label(const Exec &, const std::string_view label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_SINGLE(_exec_, _label_)
#define MATCHER_FOR_WAIT_EVENT(_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, BeginSingleEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent > recorder_listener_t
Concept for a sender whose completion scheduler is Kokkos::Execution::ExecutionSpaceImpl::Scheduler.
#define KOKKOS_EXECUTION_THREADS_THROWS_ON_SYNC_WAIT_ASSERT_AND_SKIP(_sndr_)
Kokkos::DefaultHostExecutionSpace host_execution_space
#define DEFINE_ONE_BRANCH(_letter_, _id_)
#define SHOW_ONE_BRANCH_ORDER_AFTER_STC(_letter_, _id_)
#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...
#define THEN_LABELED_PFOR(_exec_, _id_)
Add a Kokkos::Execution::parallel_for using Tests::Utils::Functors::Labeled. // NOLINTNEXTLINE(cppcor...
constexpr check_rcvr_env_queryable_with_t< false, Queries... > check_rcvr_env_not_queryable_with
auto record_sync_wait(Sndr &&sndr)
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< execution_space >
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Kokkos::View< value_t, Kokkos::SharedSpace > view_s_t
Kokkos::Execution::ExecutionSpaceContext< Exec > context_t