kokkos-execution 0.0.1
Loading...
Searching...
No Matches
completion_signal.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_EXECUTION_IMPL_COMPLETION_SIGNAL_HPP
2#define KOKKOS_EXECUTION_IMPL_COMPLETION_SIGNAL_HPP
3
5
6#if defined(KOKKOS_EXECUTION_ENABLE_DEBUG_LOGGING)
7# include "plog/Log.h"
8#endif
9
11
18
20
28template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
31 bool operator()(const Exec& exec, const Rcvr& rcvr) const noexcept
32 requires(stdexec::__queryable_with<stdexec::env_of_t<Rcvr>, get_exec_t>)
33 {
34 if constexpr (std::same_as<exec_of_t<stdexec::env_of_t<Rcvr>>, Exec>) {
35 const auto& src = exec;
36 const auto& dst = get_exec(stdexec::get_env(rcvr)).get();
37#if defined(KOKKOS_EXECUTION_ENABLE_DEBUG_LOGGING)
38 PLOG_DEBUG << "The synchronization happens if " << Kokkos::Tools::Experimental::device_id(src)
39 << " is not equal to " << Kokkos::Tools::Experimental::device_id(dst) << '.';
40#endif
41 return src != dst;
42 }
43 return true;
44 }
45
47 constexpr bool operator()(const Exec&, const Rcvr&) const noexcept
48 requires(!stdexec::__queryable_with<stdexec::env_of_t<Rcvr>, get_exec_t>)
49 {
50#if defined(KOKKOS_EXECUTION_ENABLE_DEBUG_LOGGING)
51 PLOG_DEBUG << "Synchronization always required.";
52#endif
53 return true;
54 }
55};
56
57template <typename Policy, Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
59
60struct SyncPolicyTag { };
61
74
75template <typename Policy>
76concept sync_policy = std::derived_from<Policy, SyncPolicyTag>;
77
83template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
84struct CompletionSignal<SyncPolicy::InlineFenceExec, Exec, Rcvr> {
85 static constexpr auto label = KOKKOS_EXECUTION_IMPL_DISPATCH_LABEL(Exec, ": after dispatch");
86
87 Rcvr rcvr;
88
89 void propagate(const Exec& exec) & noexcept {
90 if (!RequiresSync<Exec, Rcvr>{}(exec, rcvr)) {
91 stdexec::set_value(std::move(rcvr));
92 } else {
93 try {
94 exec.fence(std::string(label));
95 stdexec::set_value(std::move(rcvr));
96 } catch (...) {
97 stdexec::set_error(std::move(rcvr), std::current_exception());
98 }
99 }
100 }
101};
102
103template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
105 using receiver_concept = stdexec::receiver_tag;
106
108
109 void set_value() && noexcept {
110 try {
112 stdexec::set_value(std::move(completion_signal->rcvr));
113 } catch (...) {
114 stdexec::set_error(std::move(completion_signal->rcvr), std::current_exception());
115 }
116 }
117};
118
125template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
126struct CompletionSignal<SyncPolicy::ScheduleWaitEvent, Exec, Rcvr> {
129 using inner_op_state_t = stdexec::connect_result_t<
130 stdexec::schedule_result_t<delegation_scheduler_t>,
132 >;
133
134 Rcvr rcvr;
135 event_storage_t event = std::nullopt;
137
138 void propagate(const Exec& exec) & noexcept {
139 if (!RequiresSync<Exec, Rcvr>{}(exec, rcvr)) {
140 stdexec::set_value(std::move(rcvr));
141 } else {
142 try {
143 event.emplace();
144 record(*event, exec);
146 stdexec::connect,
147 stdexec::schedule(stdexec::get_delegation_scheduler(stdexec::get_env(rcvr))),
149 stdexec::start(inner_op_state.get());
150 } catch (...) {
151 stdexec::set_error(std::move(rcvr), std::current_exception());
152 }
153 }
154 }
155};
156
158
171
172template <typename Policy>
173concept submitted_policy = std::derived_from<Policy, SubmittedPolicyTag>;
174
175template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
176struct CompletionSignal<SubmittedPolicy::OrderOnExec, Exec, Rcvr> {
177 Rcvr rcvr;
178
179 void propagate(const Exec&) & noexcept {
180 std::move(rcvr).submitted();
181 }
182};
183
190template <Kokkos::ExecutionSpace Exec, stdexec::receiver Rcvr>
191struct CompletionSignal<SubmittedPolicy::DependOnEvent, Exec, Rcvr> {
193
194 Rcvr rcvr;
196
197 void propagate(const Exec& exec) & noexcept {
198 if (RequiresSync<Exec, Rcvr>{}(exec, rcvr)) {
199 auto& event = event_storage.emplace();
200 Impl::record(event, exec);
201 std::move(rcvr).submitted(OptionalConstEventRef{event});
202 } else {
203 std::move(rcvr).submitted(OptionalConstEventRef<Exec>{});
204 }
205 }
206};
207
208} // namespace Kokkos::Execution::Impl
209
210#endif // KOKKOS_EXECUTION_IMPL_COMPLETION_SIGNAL_HPP
Data structure that has an interface similar to std::optional but stores the value with stdexec::__ma...
constexpr auto emplace_from(Func &&func, Args &&... args) noexcept(noexcept(T{std::forward< Func >(func)(std::forward< Args >(args)...)})) -> T &
constexpr auto get() &noexcept -> T &
Constrain an EventType type to be a valid event type for Exec execution space type.
Definition event.hpp:31
Constrain the accepted label types.
Definition label.hpp:40
#define KOKKOS_EXECUTION_IMPL_DISPATCH_LABEL(_exec_, _suffix_)
OptionalRef< const Event< Exec > > OptionalConstEventRef
Optionally stores a reference to a const Impl::Event.
Definition event.hpp:183
std::optional< Event< Exec > > event_storage_t
Definition event.hpp:179
stdexec::__query_result_t< const Env &, stdexec::get_delegation_scheduler_t > delegation_scheduler_of_t
Definition schedulers.hpp:9
void record(Event< Exec > &event, const Exec &exec)
Record event on exec.
Definition event.hpp:145
void wait(const Event< Exec > &... events)
Wait for events to complete.
Definition event.hpp:157
constexpr get_exec_t get_exec
Definition get_exec.hpp:24
stdexec::connect_result_t< stdexec::schedule_result_t< delegation_scheduler_t >, ScheduleWaitEventReceiver< Exec, Rcvr > > inner_op_state_t
Impl::delegation_scheduler_of_t< stdexec::env_of_t< Rcvr > > delegation_scheduler_t
constexpr bool operator()(const Exec &, const Rcvr &) const noexcept
bool operator()(const Exec &exec, const Rcvr &rcvr) const noexcept
CompletionSignal< SyncPolicy::ScheduleWaitEvent, Exec, Rcvr > * completion_signal
Under a sync policy, a terminal completion is propagated: in-flight operations must complete.