kokkos-execution 0.0.1
Loading...
Searching...
No Matches
test_split.cpp
Go to the documentation of this file.
2PRAGMA_DIAGNOSTIC_PUSH
4#include "exec/split.hpp"
5#include "exec/static_thread_pool.hpp"
6PRAGMA_DIAGNOSTIC_POP
7
9
12
17
29
31
32using namespace Kokkos::utils::callbacks;
33
46
48TEST_F(SplitTest, split_and_sync_wait) {
49 const context_t esc{exec};
50
51 stdexec::sender auto chain = stdexec::schedule(esc.get_scheduler()) | experimental::execution::split();
52
53 ASSERT_THAT(Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(chain)), testing::IsEmpty());
54}
55
60TEST_F(SplitTest, within) {
61 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
62
63 experimental::execution::static_thread_pool pool{4};
64 const context_t esc{exec};
65
66 stdexec::sender auto fork = stdexec::schedule(pool.get_scheduler()) | experimental::execution::split();
67
68 static_assert(!stdexec::dependent_sender<decltype(fork)>);
69
70 auto branch_a = fork | stdexec::continues_on(esc.get_scheduler()) | THEN_INCREMENT_ATOMIC(System, data)
71 | THEN_INCREMENT_ATOMIC(System, data);
72 auto branch_b = fork | stdexec::continues_on(pool.get_scheduler()) | THEN_INCREMENT_ATOMIC(System, data)
73 | stdexec::continues_on(esc.get_scheduler());
74 auto branch_c = std::move(fork) | stdexec::continues_on(esc.get_scheduler()) | THEN_INCREMENT_ATOMIC(System, data)
75 | THEN_INCREMENT_ATOMIC(System, data);
76
77 static_assert(!stdexec::dependent_sender<decltype(branch_a)>);
78 static_assert(stdexec::dependent_sender<decltype(branch_b)>);
79 static_assert(!stdexec::dependent_sender<decltype(branch_c)>);
80
81 stdexec::sender auto w_a = stdexec::when_all(std::move(branch_a), std::move(branch_b), std::move(branch_c));
82
83 static_assert(stdexec::dependent_sender<decltype(w_a)>);
84
85 static_assert(std::same_as<
86 stdexec::__completion_domain_of_t<stdexec::set_value_t, decltype(w_a), stdexec::env<>>,
88 >);
89
90 stdexec::sender auto sndr = std::move(w_a) | stdexec::continues_on(pool.get_scheduler())
91 | stdexec::then([&data]() { EXPECT_EQ(data(), 5); });
92
93 static_assert(stdexec::dependent_sender<decltype(sndr)>);
94
95 static_assert(std::same_as<
96 stdexec::__completion_domain_of_t<
97 stdexec::set_value_t,
98 decltype(sndr),
99 stdexec::prop<stdexec::get_start_scheduler_t, stdexec::run_loop::scheduler>
100 >,
101 experimental::execution::_pool::_static_thread_pool::domain
102 >);
103
104 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
105
107
108 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(sndr));
109
112 ASSERT_THAT(recorded_events, ::testing::SizeIs(8));
113 ASSERT_THAT(
114 recorded_events,
115 ::testing::Contains(MATCHER_FOR_BEGIN_SINGLE(exec, dispatch_label(exec, "then"))).Times(4));
116 ASSERT_THAT(recorded_events, ::testing::Contains(MATCHER_FOR_RECORD_EVENT(exec)).Times(2));
117 std::ranges::for_each(
118 recorded_events | std::views::filter([](const auto& event) -> bool {
119 return std::holds_alternative<Kokkos::Execution::Impl::RecordEvent>(event);
120 }),
121 [&](const auto& event) {
122 ASSERT_THAT(recorded_events, ::testing::Contains(MATCHER_FOR_WAIT_EVENT(event)).Times(1));
123 });
124 } else {
125 ASSERT_THAT(
126 recorded_events,
127 testing::UnorderedElementsAre(
130 MATCHER_FOR_BEGIN_FENCE(exec, dispatch_label(exec, "after dispatch")),
133 MATCHER_FOR_BEGIN_FENCE(exec, dispatch_label(exec, "after dispatch"))));
134 }
135
136 ASSERT_EQ(data(), 5);
137}
138
139} // namespace Tests::ExecutionSpaceImpl
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_RECORD_EVENT(_exec_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
RecorderListener< EventDiscardMatcher< TEST_EXECUTION_SPACE >, BeginFenceEvent, BeginSingleEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent > recorder_listener_t
#define KOKKOS_EXECUTION_THREADS_THROWS_ON_SYNC_WAIT_ASSERT_AND_SKIP(_sndr_)
Definition context.hpp:76
#define KOKKOS_EXECUTION_STDEXEC_PRAGMA_DIAGNOSTIC_IGNORED
Basic list of ignored diagnostics when including anything from stdexec.
#define THEN_INCREMENT_ATOMIC(_scope_, _data_)
Same as THEN_INCREMENT, using Tests::Utils::atomic_fetch_add. // NOLINTNEXTLINE(cppcoreguidelines-mac...
Definition increment.hpp:68
auto record_sync_wait(Sndr &&sndr)
Definition sync_wait.hpp:14
Matcher to filter out events that are just noise for tests.
auto get_scheduler() const noexcept -> ExecutionSpaceImpl::Scheduler< execution_space >
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Definition event.hpp:59
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Definition event.hpp:80
Kokkos::Execution::ExecutionSpaceContext< Exec > context_t
Definition context.hpp:33