kokkos-execution 0.0.1
Loading...
Searching...
No Matches
continues_on.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_EXECUTION_GRAPH_CONTINUES_ON_HPP
2#define KOKKOS_EXECUTION_GRAPH_CONTINUES_ON_HPP
3
5
7
16
18
20template <typename ParentOp, typename Env = stdexec::env_of_t<ParentOp>>
21struct ContinuesOnReceiver : public Impl::Receiver<ParentOp, Env> {
22 using exec_env_policy_t = typename ParentOp::exec_env_policy_t;
23
24 [[nodiscard]]
25 constexpr auto get_env() const noexcept
26 -> ExecutionSpaceImpl::join_env_with_exec_t<exec_env_policy_t, Env, typename ParentOp::execution_space> {
28 stdexec::get_env(*this->parent_op), Impl::get_exec(*this->parent_op).get());
29 }
30};
31
32template <stdexec::scheduler Schd, stdexec::receiver Rcvr>
34 using execution_space = typename std::remove_cvref_t<Schd>::execution_space;
35
37 Rcvr rcvr;
38
39 constexpr explicit ContinuesOnOpStateBase(const Schd& schd, Rcvr rcvr_)
40 noexcept(std::is_nothrow_move_constructible_v<Rcvr>)
41 : state(schd.state)
42 , rcvr(std::move(rcvr_)) {
43 }
44
45 [[nodiscard]]
47 return Impl::ExecutionSpaceRef{state->exec};
48 }
49
51};
52
54template <stdexec::scheduler Schd, stdexec::sender Sndr, stdexec::receiver Rcvr>
56 : public Impl::Immovable
57 , public ContinuesOnOpStateBase<Schd, Rcvr> {
59
62
63 using exec_env_policy_t = std::conditional_t<
64 std::same_as<stdexec::__completion_domain_of_t<stdexec::set_value_t, Sndr, stdexec::env_of_t<Rcvr>>, Domain>,
67 >;
68
70 using inner_opstate_t = stdexec::connect_result_t<Sndr, rcvr_t>;
71
74
76
77 [[no_unique_address]]
78 std::optional<dependency_t> dependency{};
80
81 ContinuesOnOpState(Schd&& schd, Sndr&& sndr, Rcvr rcvr) noexcept( // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
82 std::is_nothrow_constructible_v<base_t, Schd&&, Rcvr&&> && stdexec::__nothrow_connectable<Sndr&&, rcvr_t>)
83 : base_t(std::forward<Schd>(schd), std::move(rcvr))
84 , inner_opstate(stdexec::connect(std::forward<Sndr>(sndr), rcvr_t{this})) {
85 }
86
87 void start() & noexcept {
88 stdexec::start(inner_opstate);
89 }
90
91 void submit() noexcept {
92 const auto& exec_from = Impl::get_exec(this->inner_opstate).get();
93 const auto& exec_to = Impl::get_exec(*this).get();
94 try {
95 this->dependency.emplace(exec_to, exec_from);
96 } catch (...) {
97 stdexec::set_error(std::move(this->rcvr), std::current_exception());
98 return;
99 }
100 if constexpr (std::same_as<completion_signal_policy_t, Impl::SubmittedPolicy::OrderOnExec>) {
101 std::move(this->rcvr).submitted();
102 } else {
103 static_assert(std::same_as<completion_signal_policy_t, Impl::SyncPolicy::InlineFenceExec>);
104 stdexec::set_value(std::move(this->rcvr));
105 }
106 }
107
108 void complete(stdexec::set_value_t) noexcept {
109 stdexec::set_value(std::move(this->rcvr));
110 }
111
112 template <typename Error>
113 void complete(stdexec::set_error_t, Error&& error) noexcept {
114 stdexec::set_error(std::move(this->rcvr), std::forward<Error>(error));
115 }
116
117 void complete(stdexec::set_stopped_t) noexcept {
118 stdexec::set_stopped(std::move(this->rcvr));
119 }
120};
121
123template <stdexec::operation_state OpState, Kokkos::ExecutionSpace Exec>
124requires(
125 stdexec::__is_instance_of<OpState, Kokkos::Execution::GraphImpl::ContinuesOnOpState>
126 && std::same_as<typename OpState::execution_space, Exec>)
127struct GraphOperationStateFor<OpState, Exec> : public std::true_type { };
128
130template <stdexec::scheduler Schd, stdexec::sender Sndr>
132 using sender_concept = stdexec::sender_tag;
133
135
136 template <typename Self, typename Rcvr>
138 ContinuesOnOpState<stdexec::__copy_cvref_t<Self, Schd>, stdexec::__copy_cvref_t<Self, Sndr>, Rcvr>;
139
140 template <typename Self, typename Rcvr>
141 static constexpr bool is_nothrow_connectable_v = std::is_nothrow_constructible_v<
145 Rcvr&&
146 >;
147
148 template <stdexec::__decays_to<ContinuesOnSender> Self, stdexec::receiver Rcvr>
149 STDEXEC_EXPLICIT_THIS_BEGIN(
150 auto connect)(this Self&& self, Rcvr rcvr) // NOLINT(cppcoreguidelines-missing-std-forward)
152 return {
153 KOKKOS_EXECUTION_IMPL_FORWARD_THIS(Self, self).schd,
154 KOKKOS_EXECUTION_IMPL_FORWARD_THIS(Self, self).sndr,
155 std::move(rcvr)};
156 }
157 STDEXEC_EXPLICIT_THIS_END(connect)
158
160
161 Schd schd; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
162 Sndr sndr; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
163};
164
165template <>
166struct TransformSenderFor<stdexec::continues_on_t> {
167 template <typename Env, stdexec::scheduler Schd, stdexec::sender Sndr>
168 requires stdexec::__sends<stdexec::set_value_t, Sndr, Env>
169 auto operator()(const Env&, stdexec::continues_on_t, Schd&& schd, Sndr&& sndr) const
170 noexcept(std::is_nothrow_constructible_v<ContinuesOnSender<Schd, Sndr>, Schd&&, Sndr&&>)
172 return {.schd = std::forward<Schd>(schd), .sndr = std::forward<Sndr>(sndr)};
173 }
174};
175
176} // namespace Kokkos::Execution::GraphImpl
177
178#endif // KOKKOS_EXECUTION_GRAPH_CONTINUES_ON_HPP
#define KOKKOS_EXECUTION_IMPL_FORWARDING_ATTRIBUTES_GET_ENV(_type_, _obj_)
#define KOKKOS_EXECUTION_COMPL_SIGS_KEEP(_decayed_self_type_, _sndr_type_)
#define KOKKOS_EXECUTION_GET_ENV(_type_, _obj_)
Retrieve the environment of _obj_. // NOLINTNEXTLINE(cppcoreguidelines-macro-usage).
Definition env.hpp:14
constexpr auto join_env_with_exec(Env &&env, const Exec &exec) noexcept
Unconditionally join exec to env.
Definition env.hpp:15
typename DependencyFor< InnerOp, ExecTo >::type dependency_for_t
std::conditional_t< ContinuesOn::signals_submitted< InnerOp, ExecTo, Rcvr >, Impl::SubmittedPolicy::OrderOnExec, Impl::SyncPolicy::InlineFenceExec > completion_signal_policy_t
constexpr get_exec_t get_exec
Definition get_exec.hpp:19
constexpr ContinuesOnOpStateBase(const Schd &schd, Rcvr rcvr_) noexcept(std::is_nothrow_move_constructible_v< Rcvr >)
typename std::remove_cvref_t< Schd >::execution_space execution_space
constexpr auto query(Impl::get_exec_t) const noexcept -> Impl::ExecutionSpaceRef< execution_space >
Operation state for stdexec::continues_on.
void complete(stdexec::set_error_t, Error &&error) noexcept
ContinuesOnOpStateBase< Schd, Rcvr > base_t
std::conditional_t< std::same_as< stdexec::__completion_domain_of_t< stdexec::set_value_t, Sndr, stdexec::env_of_t< Rcvr > >, Domain >, ExecutionSpaceImpl::WithExecEnvPolicy, ExecutionSpaceImpl::WithoutExecEnvPolicy > exec_env_policy_t
typename base_t::execution_space execution_space
Impl::SubmittedOperationStateTag operation_state_concept
ContinuesOnOpState(Schd &&schd, Sndr &&sndr, Rcvr rcvr) noexcept(//NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) std::is_nothrow_constructible_v< base_t, Schd &&, Rcvr && > &&stdexec::__nothrow_connectable< Sndr &&, rcvr_t >)
stdexec::connect_result_t< Sndr, rcvr_t > inner_opstate_t
void complete(stdexec::set_value_t) noexcept
Impl::ContinuesOn::completion_signal_policy_t< inner_opstate_t, execution_space, Rcvr > completion_signal_policy_t
Impl::ContinuesOn::dependency_for_t< inner_opstate_t, execution_space > dependency_t
ContinuesOnReceiver< ContinuesOnOpState, stdexec::env_of_t< Rcvr > > rcvr_t
void complete(stdexec::set_stopped_t) noexcept
typename ParentOp::exec_env_policy_t exec_env_policy_t
constexpr auto get_env() const noexcept -> ExecutionSpaceImpl::join_env_with_exec_t< exec_env_policy_t, Env, typename ParentOp::execution_space >
ContinuesOnOpState< stdexec::__copy_cvref_t< Self, Schd >, stdexec::__copy_cvref_t< Self, Sndr >, Rcvr > connect_result_t
auto operator()(const Env &, stdexec::continues_on_t, Schd &&schd, Sndr &&sndr) const noexcept(std::is_nothrow_constructible_v< ContinuesOnSender< Schd, Sndr >, Schd &&, Sndr && >) -> ContinuesOnSender< Schd, Sndr >
Wrap a Kokkos execution space to make it cheap to copy/move in new environments.
Definition get_exec.hpp:47
Receiver for an object parent_op that implements complete.
Definition receiver.hpp:13
Kokkos::DefaultExecutionSpace execution_space
#define KOKKOS_EXECUTION_IMPL_MEMBER_CVREF_T(_Self_, _member_)
Yields the type of member _member_ as accessed from expression _Self_, preserving the cv and ref qual...
#define KOKKOS_EXECUTION_IMPL_FORWARD_THIS(_Self_, _self_)
Equivalent to std::forward<_Self_>(_self_).