kokkos-execution 0.0.1
Loading...
Searching...
No Matches
sync_wait.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_EXECUTION_IMPL_SYNC_WAIT_HPP
2#define KOKKOS_EXECUTION_IMPL_SYNC_WAIT_HPP
3
5
11
13
15struct env {
16 stdexec::run_loop::scheduler schd;
17
18 [[nodiscard]]
19 auto query(stdexec::get_scheduler_t) const noexcept -> stdexec::run_loop::scheduler {
20 return schd;
21 }
22
23 [[nodiscard]]
24 auto query(stdexec::get_delegation_scheduler_t) const noexcept -> stdexec::run_loop::scheduler {
25 return schd;
26 }
27};
28
30template <typename HasErrorPtr>
31struct State;
32
33template <>
34struct State<std::true_type> {
35 std::exception_ptr error;
36 stdexec::run_loop loop;
37};
38
39template <>
40struct State<std::false_type> {
41 stdexec::run_loop loop;
42};
43
45template <Kokkos::ExecutionSpace Exec, typename HasErrorPtr = std::false_type, typename ResultType = std::tuple<>>
46struct Receiver {
48
49 static constexpr auto label = Impl::dispatch_label<Exec, ": sync_wait">();
50
53 std::optional<ResultType>* result;
54
55 template <typename... Args>
56 void set_value(Args&&... args) && noexcept {
57 result->emplace(std::forward<Args>(args)...);
58 runloop_state->loop.finish();
59 }
60
61 template <typename Error>
62 void set_error(Error&& err) && noexcept requires HasErrorPtr::value
63 {
64 runloop_state->error = std::forward<Error>(err);
65 state->exec.fence(std::string(label));
66 runloop_state->loop.finish();
67 }
68
69 void set_stopped() && noexcept {
70 state->exec.fence(std::string(label));
71 runloop_state->loop.finish();
72 }
73
74 void submitted() && noexcept {
75 state->exec.fence(std::string(label));
76 result->emplace();
77 runloop_state->loop.finish();
78 }
79
80 void submitted(OptionalConstEventRef<Exec> dep) && noexcept {
81 if (dep.has_value()) {
82 Impl::wait(dep.get());
83 }
84 result->emplace();
85 runloop_state->loop.finish();
86 }
87
88 [[nodiscard]]
89 constexpr auto get_env() const noexcept -> env {
90 return {.schd = runloop_state->loop.get_scheduler()};
91 }
92};
93
94struct SyncWait {
95 template <typename Sndr>
96 using sends_error = std::bool_constant<stdexec::__sends<stdexec::set_error_t, Sndr, env>>;
97
98 template <typename Sndr>
99 using result_t = stdexec::__sync_wait::__value_tuple_for_t<Sndr>;
100
101 template <typename Sndr>
103
104 template <typename Sndr>
105 static constexpr bool is_nothrow_connectable = stdexec::__nothrow_connectable<Sndr, receiver_t<Sndr>>;
106
111 template <stdexec::sender Sndr>
113 -> std::optional<result_t<Sndr&&>> {
115 static_assert(noexcept(std::declval<State<sends_error<Sndr&&>>>().loop.run()));
116
117 State<sends_error<Sndr&&>> runloop_state;
118
119 std::optional<result_t<Sndr&&>> result{};
120
121 Receiver rcvr{
122 .state = stdexec::get_completion_scheduler<stdexec::set_value_t>(
123 stdexec::get_env(sndr), env{.schd = runloop_state.loop.get_scheduler()})
124 .state,
125 .runloop_state = std::addressof(runloop_state),
126 .result = std::addressof(result)};
127
128 static_assert(std::same_as<decltype(rcvr), receiver_t<Sndr&&>>);
129
130 auto op_state = stdexec::connect(std::forward<Sndr>(sndr), std::move(rcvr));
131
132 stdexec::start(op_state);
133
134 runloop_state.loop.run();
135
136 if constexpr (sends_error<Sndr&&>::value)
137 if (runloop_state.error)
138 std::rethrow_exception(std::move(runloop_state.error));
139
140 return result;
141 }
142};
143
152template <template <typename...> typename SndrTrait>
154 template <typename Sndr>
155 requires SndrTrait<Sndr, env>::value
156 auto operator()(Sndr&& sndr) const noexcept(std::is_nothrow_invocable_v<SyncWait, Sndr&&>) {
157 return SyncWait{}(std::forward<Sndr>(sndr));
158 }
159};
160
161} // namespace Kokkos::Execution::Impl::SyncWait
162
163#endif // KOKKOS_EXECUTION_IMPL_SYNC_WAIT_HPP
OptionalRef< const Event< Exec > > OptionalConstEventRef
Optionally stores a reference to a const Impl::Event.
Definition event.hpp:178
void wait(const Event< Exec > &... events)
Wait for events to complete.
Definition event.hpp:152
consteval std::string_view dispatch_label() noexcept
View the dispatch label as a std::string_view.
auto operator()(Sndr &&sndr) const noexcept(std::is_nothrow_invocable_v< SyncWait, Sndr && >)
Receiver for stdexec::sync_wait.
Definition sync_wait.hpp:46
void submitted(OptionalConstEventRef< Exec > dep) &&noexcept
Definition sync_wait.hpp:80
void set_error(Error &&err) &&noexcept
Definition sync_wait.hpp:62
void set_value(Args &&... args) &&noexcept
Definition sync_wait.hpp:56
constexpr auto get_env() const noexcept -> env
Definition sync_wait.hpp:89
Inspired by https://github.com/NVIDIA/stdexec/blob/16076a81efa4477513e6ede9c2741fd034ecef99/include/s...
Definition sync_wait.hpp:31
Receiver< Impl::exec_of_t< Sndr, env >, sends_error< Sndr >, result_t< Sndr > > receiver_t
std::bool_constant< stdexec::__sends< stdexec::set_error_t, Sndr, env > > sends_error
Definition sync_wait.hpp:96
auto operator()(Sndr &&sndr) const noexcept(!sends_error< Sndr && >::value &&is_nothrow_connectable< Sndr && >) -> std::optional< result_t< Sndr && > >
stdexec::__sync_wait::__value_tuple_for_t< Sndr > result_t
Definition sync_wait.hpp:99
Inspired by https://github.com/NVIDIA/stdexec/blob/16076a81efa4477513e6ede9c2741fd034ecef99/include/s...
Definition sync_wait.hpp:15
auto query(stdexec::get_delegation_scheduler_t) const noexcept -> stdexec::run_loop::scheduler
Definition sync_wait.hpp:24
stdexec::run_loop::scheduler schd
Definition sync_wait.hpp:16
auto query(stdexec::get_scheduler_t) const noexcept -> stdexec::run_loop::scheduler
Definition sync_wait.hpp:19