kokkos-execution 0.0.1
Loading...
Searching...
No Matches
continues_on.hpp
Go to the documentation of this file.
1#ifndef KOKKOS_EXECUTION_EXECUTION_SPACE_CONTINUES_ON_HPP
2#define KOKKOS_EXECUTION_EXECUTION_SPACE_CONTINUES_ON_HPP
3
10
12
14template <typename ParentOp, typename Env = stdexec::env_of_t<ParentOp>>
15struct ContinuesOnReceiver : public Impl::Receiver<ParentOp, Env> {
16 using exec_env_policy_t = typename ParentOp::exec_env_policy_t;
17
18 [[nodiscard]]
19 constexpr auto
20 get_env() const noexcept -> join_env_with_exec_t<exec_env_policy_t, Env, typename ParentOp::execution_space> {
22 stdexec::get_env(*this->parent_op), Impl::get_exec(*this->parent_op).get());
23 }
24};
25
26template <stdexec::scheduler Schd, stdexec::receiver Rcvr>
28 using execution_space = typename std::remove_cvref_t<Schd>::execution_space;
29
31 Rcvr rcvr;
32
33 constexpr explicit ContinuesOnOpStateBase(const Schd& schd, Rcvr rcvr_)
34 noexcept(std::is_nothrow_move_constructible_v<Rcvr>)
35 : state(schd.state)
36 , rcvr(std::move(rcvr_)) {
37 }
38
39 [[nodiscard]]
43
45};
46
47template <stdexec::scheduler Schd, stdexec::sender Sndr, stdexec::receiver Rcvr>
49 : public Impl::Immovable
50 , public ContinuesOnOpStateBase<Schd, Rcvr> {
52
55
56 using exec_env_policy_t = std::conditional_t<
57 std::same_as<stdexec::__completion_domain_of_t<stdexec::set_value_t, Sndr, stdexec::env_of_t<Rcvr>>, Domain>,
60 >;
61
63 using inner_opstate_t = stdexec::connect_result_t<Sndr, rcvr_t>;
64
67
69
70 [[no_unique_address]]
71 std::optional<dependency_t> dependency{};
73
74 constexpr explicit ContinuesOnOpState(
75 Sndr&& sndr, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
76 Schd&& schd, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
77 Rcvr rcvr)
78 noexcept(
79 std::is_nothrow_constructible_v<base_t, Rcvr&&, Schd&&> && stdexec::__nothrow_connectable<Sndr&&, rcvr_t>)
80 : base_t(std::forward<Schd>(schd), std::move(rcvr))
81 , inner_opstate(stdexec::connect(std::forward<Sndr>(sndr), rcvr_t{this})) {
82 }
83
84 void complete(stdexec::set_value_t) noexcept {
85 stdexec::set_value(std::move(this->rcvr));
86 }
87
88 template <typename Error>
89 void complete(stdexec::set_error_t, Error&& error) noexcept {
90 stdexec::set_error(std::move(this->rcvr), std::forward<Error>(error));
91 }
92
93 void complete(stdexec::set_stopped_t) noexcept {
94 stdexec::set_stopped(std::move(this->rcvr));
95 }
96
97 void submit() noexcept {
98 const auto& exec_from = Impl::get_exec(this->inner_opstate).get();
99 const auto& exec_to = Impl::get_exec(*this).get();
100 try {
101 this->dependency.emplace(exec_to, exec_from);
102 } catch (...) {
103 stdexec::set_error(std::move(this->rcvr), std::current_exception());
104 return;
105 }
106 if constexpr (std::same_as<completion_signal_policy_t, Impl::SubmittedPolicy::OrderOnExec>) {
107 std::move(this->rcvr).submitted();
108 } else {
109 static_assert(std::same_as<completion_signal_policy_t, Impl::SyncPolicy::InlineFenceExec>);
110 stdexec::set_value(std::move(this->rcvr));
111 }
112 }
113
114 void start() & noexcept {
115 stdexec::start(inner_opstate);
116 }
117};
118
120template <stdexec::scheduler Schd, stdexec::sender Sndr>
122 using sender_concept = stdexec::sender_tag;
123
125
126 template <stdexec::receiver Rcvr>
127 constexpr auto connect(Rcvr rcvr) && noexcept(
128 std::is_nothrow_constructible_v<ContinuesOnOpState<Schd, Sndr, Rcvr>, Sndr&&, Schd&&, Rcvr&&>)
131 std::forward<Sndr>(sndr), std::forward<Schd>(schd), std::move(rcvr)};
132 }
133
135
136 Schd schd;
137 Sndr sndr; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
138};
139
140template <>
141struct TransformSenderFor<stdexec::continues_on_t> {
142 template <typename Env, stdexec::__is_instance_of<Scheduler> Schd, stdexec::sender Sndr>
143 auto operator()(const Env&, stdexec::continues_on_t, Schd&& schd, Sndr&& sndr) const
144 noexcept(std::is_nothrow_constructible_v<ContinuesOnSender<Schd, Sndr>, Schd&&, Sndr&&>)
146 return {.schd = std::forward<Schd>(schd), .sndr = std::forward<Sndr>(sndr)};
147 }
148};
149
150} // namespace Kokkos::Execution::ExecutionSpaceImpl
151
152#endif // KOKKOS_EXECUTION_EXECUTION_SPACE_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
decltype(join_env_with_exec< ExecEnvPolicy >(std::declval< Env >(), std::declval< Exec >())) join_env_with_exec_t
Definition env.hpp:31
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
typename std::remove_cvref_t< Schd >::execution_space execution_space
constexpr auto query(Impl::get_exec_t) const noexcept -> Impl::ExecutionSpaceRef< execution_space >
constexpr ContinuesOnOpStateBase(const Schd &schd, Rcvr rcvr_) noexcept(std::is_nothrow_move_constructible_v< Rcvr >)
ContinuesOnReceiver< ContinuesOnOpState, stdexec::env_of_t< Rcvr > > rcvr_t
constexpr ContinuesOnOpState(Sndr &&sndr, Schd &&schd, Rcvr rcvr) noexcept(std::is_nothrow_constructible_v< base_t, Rcvr &&, Schd && > &&stdexec::__nothrow_connectable< Sndr &&, rcvr_t >)
stdexec::connect_result_t< Sndr, rcvr_t > inner_opstate_t
std::conditional_t< std::same_as< stdexec::__completion_domain_of_t< stdexec::set_value_t, Sndr, stdexec::env_of_t< Rcvr > >, Domain >, WithExecEnvPolicy, WithoutExecEnvPolicy > exec_env_policy_t
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
void complete(stdexec::set_error_t, Error &&error) noexcept
typename ParentOp::exec_env_policy_t exec_env_policy_t
constexpr auto get_env() const noexcept -> join_env_with_exec_t< exec_env_policy_t, Env, typename ParentOp::execution_space >
constexpr auto connect(Rcvr rcvr) &&noexcept(std::is_nothrow_constructible_v< ContinuesOnOpState< Schd, Sndr, Rcvr >, Sndr &&, Schd &&, Rcvr && >) -> ContinuesOnOpState< Schd, Sndr, Rcvr >
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