YOrch 1.0.0
Loading...
Searching...
No Matches
fanout.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <tuple>
5#include <type_traits>
6#include <utility>
7
8#include "../../context.hpp"
9#include "../../detail/maybe_storage.hpp"
10#include "../../task_tree/policies.hpp"
11#include "prev_validation.hpp"
12
13namespace yorch::detail {
14
15template <typename Task>
16inline constexpr bool task_uses_copy_only_prev_access_v =
21
22template <typename Task>
25
26template <typename Plan, std::size_t I>
28 requires {
29 { Plan::no_parent } -> std::convertible_to<std::size_t>;
30 { Plan::template parent_index<I> } -> std::convertible_to<std::size_t>;
31 { Plan::template child_count<I> } -> std::convertible_to<std::size_t>;
32 typename Plan::template task_type<I>;
33 typename Plan::template output_type<I>;
34 typename Plan::template fanout_policy_type<I>;
35 };
36
37template <typename Plan, std::size_t Child>
39inline constexpr bool node_uses_copy_only_prev_access_v =
41
42template <typename Plan, std::size_t Child>
46
47template <typename Plan, std::size_t Parent, std::size_t... Ord>
48[[nodiscard]] consteval std::size_t parent_exclusive_prev_child_count_impl(std::index_sequence<Ord...>) {
49 return (std::size_t {0} + ... +
52 ? std::size_t {1}
53 : std::size_t {0}));
54}
55
56template <typename Plan, std::size_t Parent, std::size_t... Ord>
57[[nodiscard]] consteval std::size_t parent_copy_only_prev_child_count_impl(std::index_sequence<Ord...>) {
58 return (std::size_t {0} + ... +
60 Plan,
61 Plan::template child_index<Parent, Ord>>
62 ? std::size_t {1}
63 : std::size_t {0}));
64}
65
66template <typename Plan, std::size_t Parent, std::size_t... Ord>
68 std::index_sequence<Ord...>) {
69 return (std::size_t {0} + ... +
71 Plan,
72 Plan::template child_index<Parent, Ord>>
73 ? std::size_t {1}
74 : std::size_t {0}));
75}
76
77template <typename Plan, std::size_t Parent, std::size_t... Ord>
78[[nodiscard]] consteval bool parent_has_non_copy_or_consume_prev_child_impl(std::index_sequence<Ord...>) {
80 typename Plan::template task_type<Plan::template child_index<Parent, Ord>>> &&
82 Plan,
83 Plan::template child_index<Parent, Ord>> &&
85 Plan,
86 Plan::template child_index<Parent, Ord>>) || ...);
87}
88
89template <typename Plan, std::size_t Parent>
92 using policy_t = typename Plan::template fanout_policy_type<Parent>;
93
94 if constexpr (Plan::template child_count<Parent> == 0) {
95 return true;
96 } else if constexpr (std::is_same_v<policy_t, yorch::fanout_auto_policy>) {
97 if constexpr (Plan::template child_count<Parent> <= 1) {
98 return true;
99 } else {
101 std::make_index_sequence<Plan::template child_count<Parent>> {}) == 0;
102 }
103 } else if constexpr (std::is_same_v<policy_t, yorch::fanout_shared_readonly_policy>) {
105 std::make_index_sequence<Plan::template child_count<Parent>> {}) == 0;
106 } else {
107 static_assert(std::is_same_v<policy_t, yorch::fanout_consume_with_copies_policy>,
108 "Unsupported fanout policy");
109
111 std::make_index_sequence<Plan::template child_count<Parent>> {}) &&
113 std::make_index_sequence<Plan::template child_count<Parent>> {}) <= 1;
114 }
115}
116
117template <typename Plan, std::size_t... I>
119[[nodiscard]] consteval bool plan_fanout_policy_valid_impl(std::index_sequence<I...>) {
120 return (parent_fanout_policy_valid<Plan, I>() && ...);
121}
122
123template <typename Plan>
124inline constexpr bool plan_fanout_policy_valid_v =
125 plan_fanout_policy_valid_impl<Plan>(std::make_index_sequence<Plan::node_count> {});
126
127template <typename Plan, std::size_t Parent>
129inline constexpr bool parent_requires_fanout_staging_v =
130 std::is_same_v<typename Plan::template fanout_policy_type<Parent>,
133 std::make_index_sequence<Plan::template child_count<Parent>> {}) == 1) &&
135 std::make_index_sequence<Plan::template child_count<Parent>> {}) != 0);
136
137template <typename Plan, std::size_t Parent>
141
142template <typename Plan, std::size_t Child>
144inline constexpr bool node_uses_staged_copy_prev_v = [] {
145 if constexpr (Plan::template parent_index<Child> == Plan::no_parent) {
146 return false;
147 } else {
150 }
151}();
152
154 constexpr void destroy() noexcept {}
155
156 [[nodiscard]] static constexpr bool has_value() noexcept {
157 return false;
158 }
159};
160
161template <typename Plan, std::size_t Parent, typename = void>
165
166template <typename Plan, std::size_t Parent>
168 Plan,
169 Parent,
170 std::enable_if_t<parent_has_staged_copy_children_v<Plan, Parent>>> {
172};
173
174template <typename Plan, std::size_t... I>
175[[nodiscard]] consteval auto make_plan_fanout_stage_tuple(std::index_sequence<I...>)
176 -> std::tuple<typename fanout_stage_slot<Plan, I>::type...>;
177
178template <typename Plan>
180 decltype(make_plan_fanout_stage_tuple<Plan>(std::make_index_sequence<Plan::node_count> {}));
181
182template <typename Plan>
184 template <std::size_t Parent>
185 constexpr void prepare_fanout_staging(auto& slots) {
187 auto& source = slots.template get<Parent>();
188 using parent_output_t = typename Plan::template output_type<Parent>;
189
190 static_assert(
191 std::is_constructible_v<parent_output_t, const parent_output_t&>,
192 "fanout_consume_with_copies_policy requires the parent output type "
193 "to be constructible from const T& for copy_prev children");
194
195 stage_slot<Parent>().emplace(source);
196 }
197 }
198
199 template <std::size_t Parent>
202 stage_slot<Parent>().destroy();
203 }
204 }
205
206 template <std::size_t Parent>
207 [[nodiscard]] constexpr auto staged_prev_view_for_parent() & {
209 "staged_prev_view_for_parent<I>() requires a parent with staged copy children");
210 return prev_slot(stage_slot<Parent>().get());
211 }
212
213 template <std::size_t Parent>
216 "staged_prev_view_for_parent<I>() requires a parent with staged copy children");
217 return prev_slot(stage_slot<Parent>().get());
218 }
219
220private:
221 template <std::size_t Parent>
222 [[nodiscard]] constexpr auto& stage_slot() & noexcept {
223 return std::get<Parent>(staging_);
224 }
225
226 template <std::size_t Parent>
227 [[nodiscard]] constexpr const auto& stage_slot() const& noexcept {
228 return std::get<Parent>(staging_);
229 }
230
232};
233
234} // namespace yorch::detail
constexpr bool node_uses_staged_copy_prev_v
Definition fanout.hpp:144
consteval bool parent_has_non_copy_or_consume_prev_child_impl(std::index_sequence< Ord... >)
Definition fanout.hpp:78
consteval std::size_t parent_consume_only_prev_child_count_impl(std::index_sequence< Ord... >)
Definition fanout.hpp:67
constexpr bool node_uses_consume_only_prev_access_v
Definition fanout.hpp:44
constexpr bool node_uses_copy_only_prev_access_v
Definition fanout.hpp:39
constexpr bool parent_requires_fanout_staging_v
Definition fanout.hpp:129
consteval bool parent_fanout_policy_valid()
Definition fanout.hpp:91
constexpr bool task_uses_prev_access_v
constexpr bool parent_has_staged_copy_children_v
Definition fanout.hpp:139
consteval std::size_t parent_copy_only_prev_child_count_impl(std::index_sequence< Ord... >)
Definition fanout.hpp:57
constexpr bool plan_fanout_policy_valid_v
Definition fanout.hpp:124
constexpr bool task_uses_consume_only_prev_access_v
Definition fanout.hpp:23
constexpr bool task_uses_copy_only_prev_access_v
Definition fanout.hpp:16
constexpr bool task_uses_exclusive_prev_access_v
consteval std::size_t parent_exclusive_prev_child_count_impl(std::index_sequence< Ord... >)
Definition fanout.hpp:48
constexpr bool is_adapter_descriptor_v
Definition adapters.hpp:63
consteval bool plan_fanout_policy_valid_impl(std::index_sequence< I... >)
Definition fanout.hpp:119
decltype(make_plan_fanout_stage_tuple< Plan >(std::make_index_sequence< Plan::node_count > {})) plan_fanout_stage_tuple_t
Definition fanout.hpp:180
consteval auto make_plan_fanout_stage_tuple(std::index_sequence< I... >) -> std::tuple< typename fanout_stage_slot< Plan, I >::type... >
constexpr auto prev_slot(T &value) noexcept -> prev_slot_view< T >
Creates a borrowed view over a direct parent payload object.
Definition context.hpp:91
static constexpr bool has_value() noexcept
Definition fanout.hpp:156
constexpr void destroy() noexcept
Definition fanout.hpp:154
Manual-lifetime storage for an optional in-place T.
constexpr void destroy_fanout_staging() noexcept
Definition fanout.hpp:200
constexpr void prepare_fanout_staging(auto &slots)
Definition fanout.hpp:185
constexpr auto staged_prev_view_for_parent() &
Definition fanout.hpp:207
constexpr auto staged_prev_view_for_parent() const &
Definition fanout.hpp:214
Mixed fanout policy that allows one consumer plus any number of copies.
Definition policies.hpp:46