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 continues_after() && noexcept {
75 state->exec.fence(std::string(label));
76 result->emplace();
77 runloop_state->loop.finish();
78 }
79
80 void continues_after(const Impl::Event<Exec>& event) && noexcept {
82 result->emplace();
83 runloop_state->loop.finish();
84 }
85
86 [[nodiscard]]
87 constexpr auto get_env() const noexcept -> env {
88 return {.schd = runloop_state->loop.get_scheduler()};
89 }
90};
91
92struct SyncWait {
93 template <typename Sndr>
94 using sends_error = std::bool_constant<stdexec::__sends<stdexec::set_error_t, Sndr, env>>;
95
96 template <typename Sndr>
97 using result_t = stdexec::__sync_wait::__value_tuple_for_t<Sndr>;
98
99 template <typename Sndr>
101
102 template <typename Sndr>
103 static constexpr bool is_nothrow_connectable = stdexec::__nothrow_connectable<Sndr, receiver_t<Sndr>>;
104
109 template <stdexec::sender Sndr>
111 -> std::optional<result_t<Sndr&&>> {
113 static_assert(noexcept(std::declval<State<sends_error<Sndr&&>>>().loop.run()));
114
115 State<sends_error<Sndr&&>> runloop_state;
116
117 std::optional<result_t<Sndr&&>> result{};
118
119 Receiver rcvr{
120 .state = stdexec::get_completion_scheduler<stdexec::set_value_t>(
121 stdexec::get_env(sndr), env{.schd = runloop_state.loop.get_scheduler()})
122 .state,
123 .runloop_state = std::addressof(runloop_state),
124 .result = std::addressof(result)};
125
126 static_assert(std::same_as<decltype(rcvr), receiver_t<Sndr&&>>);
127
128 auto op_state = stdexec::connect(std::forward<Sndr>(sndr), std::move(rcvr));
129
130 stdexec::start(op_state);
131
132 runloop_state.loop.run();
133
134 if constexpr (sends_error<Sndr&&>::value)
135 if (runloop_state.error)
136 std::rethrow_exception(std::move(runloop_state.error));
137
138 return result;
139 }
140};
141
150template <template <typename...> typename SndrTrait>
152 template <typename Sndr>
153 requires SndrTrait<Sndr, env>::value
154 auto operator()(Sndr&& sndr) const noexcept(std::is_nothrow_invocable_v<SyncWait, Sndr&&>) {
155 return SyncWait{}(std::forward<Sndr>(sndr));
156 }
157};
158
159} // namespace Kokkos::Execution::Impl::SyncWait
160
161#endif // KOKKOS_EXECUTION_IMPL_SYNC_WAIT_HPP
Constrain an EventType type to be a valid event type for Exec execution space type.
Definition event.hpp:24
void wait(const Event< Exec > &event)
Wait for event to complete.
Definition event.hpp:145
consteval std::string_view dispatch_label() noexcept
View the dispatch label as a std::string_view.
An event that can be recorded on an execution space instance.
Definition event.hpp:108
auto operator()(Sndr &&sndr) const noexcept(std::is_nothrow_invocable_v< SyncWait, Sndr && >)
Receiver for stdexec::sync_wait.
Definition sync_wait.hpp:46
Impl::DeferredCompletionReceiverTag receiver_concept
Definition sync_wait.hpp:47
void continues_after(const Impl::Event< Exec > &event) &&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:87
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:94
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:97
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