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 template <
19 stdexec::__one_of<stdexec::get_scheduler_t, stdexec::get_start_scheduler_t, stdexec::get_delegation_scheduler_t>
20 Query
21 >
22 [[nodiscard]]
23 auto query(Query) const noexcept -> stdexec::run_loop::scheduler {
24 return schd;
25 }
26};
27
29template <typename HasErrorPtr>
30struct State;
31
32template <>
33struct State<std::true_type> {
34 std::exception_ptr error;
35 stdexec::run_loop loop;
36};
37
38template <>
39struct State<std::false_type> {
40 stdexec::run_loop loop;
41};
42
44template <Kokkos::ExecutionSpace Exec, typename HasErrorPtr = std::false_type, typename ResultType = std::tuple<>>
45struct Receiver {
47
48 static constexpr auto label = KOKKOS_EXECUTION_IMPL_DISPATCH_LABEL(Exec, ": sync_wait");
49
52 std::optional<ResultType>* result;
53
54 template <typename... Args>
55 void set_value(Args&&... args) && noexcept {
56 result->emplace(std::forward<Args>(args)...);
57 runloop_state->loop.finish();
58 }
59
60 template <typename Error>
61 void set_error(Error&& err) && noexcept requires HasErrorPtr::value
62 {
63 runloop_state->error = std::forward<Error>(err);
64 state->exec.fence(std::string(label));
65 runloop_state->loop.finish();
66 }
67
68 void set_stopped() && noexcept {
69 runloop_state->loop.finish();
70 }
71
72 void submitted() && noexcept {
73 state->exec.fence(std::string(label));
74 result->emplace();
75 runloop_state->loop.finish();
76 }
77
78 void submitted(OptionalConstEventRef<Exec> dep) && noexcept {
79 if (dep.has_value()) {
80 Impl::wait(dep.get());
81 }
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
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
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
void wait(const Event< Exec > &... events)
Wait for events to complete.
Definition event.hpp:157
auto operator()(Sndr &&sndr) const noexcept(std::is_nothrow_invocable_v< SyncWait, Sndr && >)
Receiver for stdexec::sync_wait.
Definition sync_wait.hpp:45
void submitted(OptionalConstEventRef< Exec > dep) &&noexcept
Definition sync_wait.hpp:78
void set_error(Error &&err) &&noexcept
Definition sync_wait.hpp:61
void set_value(Args &&... args) &&noexcept
Definition sync_wait.hpp:55
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:30
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
stdexec::run_loop::scheduler schd
Definition sync_wait.hpp:16
auto query(Query) const noexcept -> stdexec::run_loop::scheduler
Definition sync_wait.hpp:23