kokkos-execution 0.0.1
Loading...
Searching...
No Matches
test_on.cpp
Go to the documentation of this file.
3
5
12
24
25using host_execution_space = Kokkos::DefaultHostExecutionSpace;
26
28
29using namespace Kokkos::utils::callbacks;
30
43
49TEST_F(OnTest, on_same_execution_space_instance) {
50 const view_s_t data(Kokkos::view_alloc("data", exec));
51
52 const context_t esc{exec};
53
54 auto chain = stdexec::schedule(esc.get_scheduler())
56 | THEN_INCREMENT(data)
57 | stdexec::on(
58 esc.get_scheduler(),
60 | THEN_INCREMENT(data))
62 | THEN_INCREMENT(data);
63
64 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
65
66 ASSERT_THAT(
68 testing::ElementsAre(
73
74 ASSERT_EQ(data(), 3);
75}
76
83TEST_F(OnTest, on_another_execution_space_instance_same_type) {
84 const view_s_t data(Kokkos::view_alloc("data", exec));
85
86 const auto [exec_A, exec_B] = Kokkos::Experimental::partition_space(exec, 1, 1);
87
88 const context_t esc_A{exec_A};
89 Tests::Utils::show_exec_space_id(exec_A, "exec_A");
90 const context_t esc_B{exec_B};
91 Tests::Utils::show_exec_space_id(exec_B, "exec_B");
92
93 auto chain = stdexec::schedule(esc_A.get_scheduler()) | THEN_INCREMENT(data)
94 | stdexec::on(esc_B.get_scheduler(), THEN_INCREMENT(data)) | THEN_INCREMENT(data);
95
96 static_assert(!Tests::Utils::has_completion_scheduler_for<decltype(chain), stdexec::set_value_t>);
97 static_assert(stdexec::dependent_sender<decltype(chain)>);
98 static_assert(Tests::Utils::has_completion_scheduler_for<decltype(chain), stdexec::set_value_t, stdexec::env<>>);
99
100 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
101
102 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(chain));
103
105 ASSERT_THAT(
106 recorded_events,
107 testing::ElementsAre(
110 MATCHER_FOR_WAIT_EXEC_EVENT(exec_B, recorded_events.at(1)),
113 MATCHER_FOR_WAIT_EXEC_EVENT(exec_A, recorded_events.at(4)),
115 MATCHER_FOR_BEGIN_FENCE(exec_A, dispatch_label(exec, "sync_wait"))));
116 } else {
117 if (Tests::Utils::are_same_instances(exec_A, exec_B)) {
118 ASSERT_THAT(
119 recorded_events,
120 testing::ElementsAre(
124 MATCHER_FOR_BEGIN_FENCE(exec_A, dispatch_label(exec, "sync_wait"))));
125 } else {
126 ASSERT_THAT(
127 recorded_events,
128 testing::ElementsAre(
130 MATCHER_FOR_BEGIN_FENCE(exec_A, dispatch_label(exec, "dependency")),
132 MATCHER_FOR_BEGIN_FENCE(exec_B, dispatch_label(exec, "dependency")),
134 MATCHER_FOR_BEGIN_FENCE(exec_A, dispatch_label(exec, "sync_wait"))));
135 }
136 }
137
138 ASSERT_EQ(data(), 3) << "A synchronization is missing.";
139}
140
147TEST_F(OnTest, many_execution_space_instances_of_different_type) {
148 const view_s_t data(Kokkos::view_alloc(exec, "data - shared space"));
149
150 const host_execution_space exec_h{};
151
153 const context_t esc{exec};
154
156 Tests::Utils::show_exec_space_id(exec_h, "exec_h");
157
158 auto chain = stdexec::schedule(esc.get_scheduler()) | THEN_INCREMENT(data)
159 | stdexec::on(esc_h.get_scheduler(), THEN_INCREMENT(data)) | THEN_INCREMENT(data);
160
161 ASSERT_EQ(data(), 0) << "Eager execution is not allowed.";
162
163 const auto recorded_events = Tests::Utils::record_sync_wait<recorder_listener_t>(std::move(chain));
164
166 ASSERT_THAT(
167 recorded_events,
168 testing::ElementsAre(
170 MATCHER_FOR_BEGIN_SINGLE(exec_h, dispatch_label(exec_h, "then")),
173 } else if constexpr (
175 && std::same_as<host_execution_space, TEST_EXECUTION_SPACE>) {
176 ASSERT_THAT(
177 recorded_events,
178 testing::ElementsAre(
181 MATCHER_FOR_WAIT_EXEC_EVENT(exec_h, recorded_events.at(1)),
182 MATCHER_FOR_BEGIN_SINGLE(exec_h, dispatch_label(exec_h, "then")),
184 MATCHER_FOR_WAIT_EXEC_EVENT(exec, recorded_events.at(4)),
187 } else {
188 ASSERT_THAT(
189 recorded_events,
190 testing::ElementsAre(
193 MATCHER_FOR_BEGIN_SINGLE(exec_h, dispatch_label(exec_h, "then")),
194 MATCHER_FOR_BEGIN_FENCE(exec_h, dispatch_label(exec_h, "dependency")),
197 }
198
199 ASSERT_EQ(data(), 3) << "A synchronization is missing.";
200}
201
202} // 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_EXEC_EVENT(_exec_, _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
Definition test_on.cpp:35
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...
Definition increment.hpp:64
auto record_sync_wait(Sndr &&sndr)
Definition sync_wait.hpp:14
void show_exec_space_id(const Exec &exec, std::string_view label="", std::ostream &out=std::cout)
Definition kokkos.hpp:38
bool are_same_instances(const Exec &exec, const OtherExec &other_exec)
Definition kokkos.hpp:18
constexpr check_completion_scheduler_type_t< Tag, Schd > check_completion_scheduler_type
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.
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