ttg 1.0.0
Template Task Graph (TTG): flowgraph-based programming model for high-performance distributed-memory algorithms
Loading...
Searching...
No Matches
make_tt.h
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2// to be #include'd within runtime::ttg namespace
3
4#ifndef TTG_MAKE_TT_H
5#define TTG_MAKE_TT_H
6
7
8// Class to wrap a callable with signature
9//
10// case 1 (keyT != void): returnT op(auto&& key, input_valuesT&&..., std::tuple<output_terminalsT...>&)
11// case 2 (keyT == void): returnT op(input_valuesT&&..., std::tuple<output_terminalsT...>&)
12//
13// returnT is void for funcT = synchronous (ordinary) function and the appropriate return type for funcT=coroutine
14template <typename funcT, typename returnT, bool funcT_receives_input_tuple,
15 bool funcT_receives_outterm_tuple, ttg::ExecutionSpace space,
16 typename keyT, typename output_terminalsT, typename... input_valuesT>
18 : public TT<
19 keyT, output_terminalsT,
20 CallableWrapTT<funcT, returnT, funcT_receives_input_tuple, funcT_receives_outterm_tuple, space, keyT, output_terminalsT, input_valuesT...>,
21 ttg::typelist<input_valuesT...>, space> {
22 using baseT = typename CallableWrapTT::ttT;
23
24 using input_values_tuple_type = typename baseT::input_values_tuple_type;
25 using input_refs_tuple_type = typename baseT::input_refs_tuple_type;
26 using input_edges_type = typename baseT::input_edges_type;
27 using output_edges_type = typename baseT::output_edges_type;
28
29 using noref_funcT = std::remove_reference_t<funcT>;
30 std::conditional_t<std::is_function_v<noref_funcT>, std::add_pointer_t<noref_funcT>, noref_funcT> func;
31
32 using op_return_type =
33#ifdef TTG_HAVE_COROUTINE
34 std::conditional_t<std::is_same_v<returnT, ttg::resumable_task>,
36#ifdef TTG_HAVE_DEVICE
37 std::conditional_t<std::is_same_v<returnT, ttg::device::Task>,
38 ttg::device::Task::base_type,
39 void>
40#else // TTG_HAVE_DEVICE
41 void
42#endif // TTG_HAVE_DEVICE
43 >;
44#else // TTG_HAVE_COROUTINE
45 void;
46#endif // TTG_HAVE_COROUTINE
47
48protected:
49
50 template<typename ReturnT>
51 auto process_return(ReturnT&& ret, output_terminalsT &out) {
52 static_assert(std::is_same_v<std::remove_reference_t<decltype(ret)>, returnT>,
53 "CallableWrapTT<funcT,returnT,...>: returnT does not match the actual return type of funcT");
54 if constexpr (!std::is_void_v<returnT>) { // protect from compiling for void returnT
55#ifdef TTG_HAVE_COROUTINE
56 if constexpr (std::is_same_v<returnT, ttg::resumable_task>) {
58 // if task completed destroy it
59 if (ret.completed()) {
60 ret.destroy();
61 } else { // if task is suspended return the coroutine promise ptr
62 coro_handle = ret;
63 }
64 return coro_handle;
65 } else
66#ifdef TTG_HAVE_DEVICE
67 if constexpr (std::is_same_v<returnT, ttg::device::Task>) {
68 ttg::device::Task::base_type coro_handle = ret;
69 return coro_handle;
70 }
71#else // TTG_HAVE_DEVICE
72 ttg::abort(); // should not happen
73#endif // TTG_HAVE_DEVICE
74 if constexpr (!(std::is_same_v<returnT, ttg::resumable_task>
75#ifdef TTG_HAVE_DEVICE
76 || std::is_same_v<returnT, ttg::device::Task>
77#endif // TTG_HAVE_DEVICE
78 ))
79#endif
80 {
81 static_assert(std::tuple_size_v<std::remove_reference_t<decltype(out)>> == 1,
82 "CallableWrapTT<funcT,returnT,funcT_receives_outterm_tuple=true,...): funcT can return a "
83 "value only if there is only 1 out terminal");
84 static_assert(std::tuple_size_v<returnT> <= 2,
85 "CallableWrapTT<funcT,returnT,funcT_receives_outterm_tuple=true,...): funcT can return a "
86 "value only if it is a plain value (then sent with null key), a tuple-like containing a single "
87 "key (hence value is void), or a tuple-like containing a key and a value");
88 if constexpr (std::tuple_size_v<returnT> == 0)
89 std::get<0>(out).sendv(std::move(ret));
90 else if constexpr (std::tuple_size_v<returnT> == 1)
91 std::get<0>(out).sendk(std::move(std::get<0>(ret)));
92 else if constexpr (std::tuple_size_v<returnT> == 2)
93 std::get<0>(out).send(std::move(std::get<0>(ret)), std::move(std::get<1>(ret)));
94 return;
95 }
96 }
97 }
98
100 template <typename Key, typename Tuple, std::size_t... S>
101 auto call_func(Key &&key, Tuple &&args_tuple, output_terminalsT &out, std::index_sequence<S...>) {
102 using func_args_t = ttg::meta::tuple_concat_t<std::tuple<const Key &>, input_refs_tuple_type, output_edges_type>;
103 auto invoke_func_handle_ret = [&](auto&&... args){
104 if constexpr (std::is_void_v<returnT>) {
105 func(std::forward<Key>(key), std::forward<decltype(args)>(args)...);
106 } else {
107 return process_return(func(std::forward<Key>(key), std::forward<decltype(args)>(args)...), out);
108 }
109 };
110 auto unpack_input_tuple_if_needed = [&](auto&&... args){
111 if constexpr (funcT_receives_input_tuple) {
112 return invoke_func_handle_ret(std::forward<Tuple>(args_tuple), std::forward<decltype(args)>(args)...);
113 } else {
114 return invoke_func_handle_ret(baseT::template get<S, std::tuple_element_t<S + 1, func_args_t>>(std::forward<Tuple>(args_tuple))...,
115 std::forward<decltype(args)>(args)...);
116 }
117 };
118
119 if constexpr (funcT_receives_outterm_tuple) {
120 return unpack_input_tuple_if_needed(out);
121 } else {
122 auto old_output_tls_ptr = this->outputs_tls_ptr_accessor();
123 this->set_outputs_tls_ptr();
124 // make sure the output tls is reset
126 [this, old_output_tls_ptr](){
127 this->set_outputs_tls_ptr(old_output_tls_ptr);
128 });
129 return unpack_input_tuple_if_needed();
130 }
131 }
132
133 template <typename Tuple, std::size_t... S>
134 auto call_func(Tuple &&args_tuple, output_terminalsT &out, std::index_sequence<S...>) {
136
137 auto invoke_func_handle_ret = [&](auto&&... args){
138 if constexpr (std::is_void_v<returnT>) {
139 func(std::forward<decltype(args)>(args)...);
140 } else {
141 return process_return(func(std::forward<decltype(args)>(args)...), out);
142 }
143 };
144 auto unpack_input_tuple_if_needed = [&](auto&& fn, auto&&... args){
145 if constexpr (funcT_receives_input_tuple) {
146 return fn(std::forward<Tuple>(args_tuple), std::forward<decltype(args)>(args)...);
147 } else {
148 return fn(baseT::template get<S, std::tuple_element_t<S, func_args_t>>(std::forward<Tuple>(args_tuple))...,
149 std::forward<decltype(args)>(args)...);
150 }
151 };
152
153 if constexpr (funcT_receives_outterm_tuple) {
154 return unpack_input_tuple_if_needed(invoke_func_handle_ret, out);
155 } else {
156 auto old_output_tls_ptr = this->outputs_tls_ptr_accessor();
157 this->set_outputs_tls_ptr();
158 // make sure the output tls is reset
160 [this, old_output_tls_ptr](){
161 this->set_outputs_tls_ptr(old_output_tls_ptr);
162 });
163 return unpack_input_tuple_if_needed(invoke_func_handle_ret);
164 }
165 }
166
167 template <typename Key>
168 auto call_func(Key &&key, output_terminalsT &out) {
169 auto invoke_func_handle_ret = [&](auto&&... args){
170 if constexpr (std::is_void_v<returnT>) {
171 func(std::forward<Key>(key), std::forward<decltype(args)>(args)...);
172 } else {
173 return process_return(func(std::forward<Key>(key), std::forward<decltype(args)>(args)...), out);
174 }
175 };
176
177 auto invoke_func_empty_tuple = [&](auto&&... args){
178 if constexpr(funcT_receives_input_tuple) {
179 invoke_func_handle_ret(std::tuple<>{}, std::forward<decltype(args)>(args)...);
180 } else {
181 invoke_func_handle_ret(std::forward<decltype(args)>(args)...);
182 }
183 };
184
185 if constexpr (funcT_receives_outterm_tuple) {
186 invoke_func_handle_ret(out);
187 } else {
188 auto old_output_tls_ptr = this->outputs_tls_ptr_accessor();
189 this->set_outputs_tls_ptr();
190 // make sure the output tls is reset
192 [this, old_output_tls_ptr](){
193 this->set_outputs_tls_ptr(old_output_tls_ptr);
194 });
195 return invoke_func_handle_ret();
196 }
197 }
198
199 template <typename OutputTerminals>
200 auto call_func(OutputTerminals &out) {
201
202 auto invoke_func_handle_ret = [&](auto&&... args){
203 if constexpr (std::is_void_v<returnT>) {
204 func(std::forward<decltype(args)>(args)...);
205 } else {
206 return process_return(func(std::forward<decltype(args)>(args)...), out);
207 }
208 };
209
210 auto invoke_func_empty_tuple = [&](auto&&... args){
211 if constexpr(funcT_receives_input_tuple) {
212 return invoke_func_handle_ret(std::tuple<>{}, std::forward<decltype(args)>(args)...);
213 } else {
214 return invoke_func_handle_ret(std::forward<decltype(args)>(args)...);
215 }
216 };
217
218 if constexpr (funcT_receives_outterm_tuple) {
219 return invoke_func_empty_tuple(out);
220 } else {
221 auto old_output_tls_ptr = this->outputs_tls_ptr_accessor();
222 this->set_outputs_tls_ptr();
223 // make sure the output tls is reset
225 [this, old_output_tls_ptr](){
226 this->set_outputs_tls_ptr(old_output_tls_ptr);
227 });
228 return invoke_func_empty_tuple();
229 }
230 }
231
232 template <typename Tuple, std::size_t... I>
233 static auto make_output_terminal_ptrs(const Tuple &output_terminals, std::index_sequence<I...>) {
234 return std::array<ttg::TerminalBase *, sizeof...(I)>{
235 {static_cast<ttg::TerminalBase *>(&std::get<I>(output_terminals))...}};
236 }
237
238 public:
239 template <typename funcT_>
240 CallableWrapTT(funcT_ &&f, const input_edges_type &inedges, const typename baseT::output_edges_type &outedges,
241 const std::string &name, const std::vector<std::string> &innames,
242 const std::vector<std::string> &outnames)
243 : baseT(inedges, outedges, name, innames, outnames), func(std::forward<funcT_>(f)) {}
244
245 template <typename funcT_>
246 CallableWrapTT(funcT_ &&f, const std::string &name, const std::vector<std::string> &innames,
247 const std::vector<std::string> &outnames)
248 : baseT(name, innames, outnames), func(std::forward<funcT_>(f)) {}
249
250 template <typename Key, typename ArgsTuple>
251 std::enable_if_t<std::is_same_v<ArgsTuple, input_refs_tuple_type> &&
253 op_return_type>
254 op(Key &&key, ArgsTuple &&args_tuple, output_terminalsT &out) {
255 assert(&out == &baseT::get_output_terminals());
256 return call_func(std::forward<Key>(key), std::forward<ArgsTuple>(args_tuple), out,
257 std::make_index_sequence<std::tuple_size_v<ArgsTuple>>{});
258 };
259
260 template <typename ArgsTuple, typename Key = keyT>
261 std::enable_if_t<std::is_same_v<ArgsTuple, input_refs_tuple_type> &&
263 op_return_type>
264 op(ArgsTuple &&args_tuple, output_terminalsT &out) {
265 assert(&out == &baseT::get_output_terminals());
266 return call_func(std::forward<ArgsTuple>(args_tuple), out,
267 std::make_index_sequence<std::tuple_size_v<ArgsTuple>>{});
268 };
269
270 template <typename Key, typename ArgsTuple = input_refs_tuple_type>
271 std::enable_if_t<ttg::meta::is_empty_tuple_v<ArgsTuple> && !ttg::meta::is_void_v<Key>, op_return_type> op(
272 Key &&key, output_terminalsT &out) {
273 assert(&out == &baseT::get_output_terminals());
274 return call_func(std::forward<Key>(key), out);
275 };
276
277 template <typename Key = keyT, typename ArgsTuple = input_refs_tuple_type>
278 std::enable_if_t<ttg::meta::is_empty_tuple_v<ArgsTuple> && ttg::meta::is_void_v<Key>, op_return_type> op(
279 output_terminalsT &out) {
280 assert(&out == &baseT::get_output_terminals());
281 return call_func(out);
282 };
283};
284
285template <typename funcT, typename returnT, bool funcT_receives_input_tuple,
286 bool funcT_receives_outterm_tuple, ttg::ExecutionSpace space,
287 typename keyT, typename output_terminalsT, typename input_values_typelistT>
289
290template <typename funcT, typename returnT, bool funcT_receives_input_tuple,
291 bool funcT_receives_outterm_tuple, ttg::ExecutionSpace space,
292 typename keyT, typename output_terminalsT, typename... input_valuesT>
293struct CallableWrapTTAsTypelist<funcT, returnT, funcT_receives_input_tuple,
294 funcT_receives_outterm_tuple, space, keyT, output_terminalsT,
295 std::tuple<input_valuesT...>> {
296 using type = CallableWrapTT<funcT, returnT, funcT_receives_input_tuple,
297 funcT_receives_outterm_tuple, space, keyT, output_terminalsT,
298 std::remove_reference_t<input_valuesT>...>;
299};
300
301template <typename funcT, typename returnT, bool funcT_receives_input_tuple,
302 bool funcT_receives_outterm_tuple, ttg::ExecutionSpace space,
303 typename keyT, typename output_terminalsT, typename... input_valuesT>
304struct CallableWrapTTAsTypelist<funcT, returnT, funcT_receives_input_tuple,
305 funcT_receives_outterm_tuple, space, keyT, output_terminalsT,
306 ttg::meta::typelist<input_valuesT...>> {
307 using type = CallableWrapTT<funcT, returnT, funcT_receives_input_tuple,
308 funcT_receives_outterm_tuple, space, keyT, output_terminalsT,
309 std::remove_reference_t<input_valuesT>...>;
310};
311
312// clang-format off
338// clang-format on
339template <ttg::ExecutionSpace space,
340 typename keyT = void,
341 typename funcT,
342 typename... input_edge_valuesT,
343 typename... output_edgesT>
344auto make_tt_tpl(funcT &&func, const std::tuple<ttg::Edge<keyT, input_edge_valuesT>...> &inedges = std::tuple<>{},
345 const std::tuple<output_edgesT...> &outedges = std::tuple<>{}, const std::string &name = "wrapper",
346 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_edge_valuesT),
347 "input"),
348 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT),
349 "output")) {
350 // ensure input types do not contain Void
351 static_assert(ttg::meta::is_none_Void_v<input_edge_valuesT...>, "ttg::Void is for internal use only, do not use it");
352 using output_terminals_type = typename ttg::edges_to_output_terminals<std::tuple<output_edgesT...>>::type;
353
354 constexpr auto void_key = ttg::meta::is_void_v<keyT>;
355
356 // list of base datum types (T or const T)
358
359 // gross list of candidate argument types
360 using gross_candidate_func_args_t = ttg::meta::typelist<
363 std::tuple<std::add_lvalue_reference_t<typename ttg::Edge<keyT, input_edge_valuesT>::value_type>...>>,
365
366 // net list of candidate argument types excludes the empty typelists for void arguments
368
369 // compute list of argument types with which func can be invoked
370 constexpr static auto func_is_generic = ttg::meta::is_generic_callable_v<funcT>;
371 using return_type_typelist_and_gross_func_args_t =
372 decltype(ttg::meta::compute_arg_binding_types(func, candidate_func_args_t{}));
373 using func_return_t = std::tuple_element_t<0, std::tuple_element_t<0, return_type_typelist_and_gross_func_args_t>>;
374 using gross_func_args_t = std::tuple_element_t<1, return_type_typelist_and_gross_func_args_t>;
375 constexpr auto DETECTED_HOW_TO_INVOKE_GENERIC_FUNC =
376 func_is_generic ? !std::is_same_v<gross_func_args_t, ttg::typelist<>> : true;
377 static_assert(DETECTED_HOW_TO_INVOKE_GENERIC_FUNC,
378 "ttd::make_tt_tpl(func, inedges, ...): could not detect how to invoke generic callable func, either "
379 "the signature of func "
380 "is faulty, or inedges does match the expected list of types, or both");
381
382 // net argument typelist
384 constexpr auto num_args = std::tuple_size_v<func_args_t>;
385
386 // if given task id, make sure it's passed via const lvalue ref
387 constexpr bool TASK_ID_PASSED_AS_CONST_LVALUE_REF =
389 constexpr bool TASK_ID_PASSED_AS_NONREF =
391 static_assert(
392 TASK_ID_PASSED_AS_CONST_LVALUE_REF || TASK_ID_PASSED_AS_NONREF,
393 "ttg::make_tt_tpl(func, ...): if given to func, the task id must be passed by const lvalue ref or by value");
394
395 // if given out-terminal tuple, make sure it's passed via nonconst lvalue ref
396 constexpr bool have_outterm_tuple =
399 gross_func_args_t>;
400 constexpr bool OUTTERM_TUPLE_PASSED_AS_NONCONST_LVALUE_REF =
402 static_assert(
403 OUTTERM_TUPLE_PASSED_AS_NONCONST_LVALUE_REF,
404 "ttd::make_tt_tpl(func, ...): if given to func, the output terminal tuple must be passed by nonconst lvalue ref");
405
406 static_assert(num_args == 3 - (void_key ? 1 : 0) - (have_outterm_tuple ? 0 : 1),
407 "ttg::make_tt_tpl(func, ...): func takes wrong number of arguments (2, or 1, if keyT=void + optional "
408 "tuple of output terminals)");
409
410 // 2. input_args_t = {input_valuesT&&...}
411 using nondecayed_input_args_t = std::tuple_element_t<void_key ? 0 : 1, func_args_t>;
412 constexpr auto NO_ARGUMENTS_PASSED_AS_NONCONST_LVALUE_REF =
414 static_assert(
415 NO_ARGUMENTS_PASSED_AS_NONCONST_LVALUE_REF,
416 "ttg::make_tt_tpl(func, inedges, outedges): one or more arguments to func can only be passed by nonconst lvalue "
417 "ref; this is illegal, should only pass arguments as const lvalue ref or (nonconst) rvalue ref");
418 using input_args_t = std::decay_t<nondecayed_input_args_t>;
419 using decayed_input_args_t = ttg::meta::decayed_typelist_t<input_args_t>;
420 using wrapT = typename CallableWrapTTAsTypelist<funcT, func_return_t, true, have_outterm_tuple, space, keyT,
421 output_terminals_type, input_args_t>::type;
422 static_assert(std::is_same_v<decayed_input_args_t, std::tuple<input_edge_valuesT...>>,
423 "ttg::make_tt_tpl(func, inedges, outedges): inedges value types do not match argument types of func");
424
425 return std::make_unique<wrapT>(std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
426}
427
428template <typename keyT = void,
429 typename funcT,
430 typename... input_edge_valuesT,
431 typename... output_edgesT>
432auto make_tt_tpl(funcT &&func, const std::tuple<ttg::Edge<keyT, input_edge_valuesT>...> &inedges = std::tuple<>{},
433 const std::tuple<output_edgesT...> &outedges = std::tuple<>{}, const std::string &name = "wrapper",
434 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_edge_valuesT),
435 "input"),
436 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT),
437 "output"))
438{
439 return make_tt_tpl<ttg::ExecutionSpace::Host, keyT>(
440 std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
441}
442// clang-format off
488// clang-format on
489template <ttg::ExecutionSpace space,
490 typename keyT = void, typename funcT,
491 typename... input_edge_valuesT, typename... output_edgesT>
492auto make_tt(funcT &&func, const std::tuple<ttg::Edge<keyT, input_edge_valuesT>...> &inedges = std::tuple<>{},
493 const std::tuple<output_edgesT...> &outedges = std::tuple<>{}, const std::string &name = "wrapper",
494 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_edge_valuesT), "input"),
495 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT), "output")) {
496 // ensure input types do not contain Void
497 static_assert(ttg::meta::is_none_Void_v<input_edge_valuesT...>, "ttg::Void is for internal use only, do not use it");
498
499 using output_terminals_type = typename ttg::edges_to_output_terminals<std::tuple<output_edgesT...>>::type;
500
501 constexpr auto void_key = ttg::meta::is_void_v<keyT>;
502
503 // list of base datum types (T or const T)
505
506 // gross list of candidate argument types
507 using gross_candidate_func_args_t = ttg::meta::typelist<
511
512 // net list of candidate argument types excludes the empty typelists for void arguments
514
515 // gross argument typelist for invoking func, can include void for optional args
516 constexpr static auto func_is_generic = ttg::meta::is_generic_callable_v<funcT>;
517 using return_type_typelist_and_gross_func_args_t =
518 decltype(ttg::meta::compute_arg_binding_types(func, candidate_func_args_t{}));
519 using func_return_t = std::tuple_element_t<0, std::tuple_element_t<0, return_type_typelist_and_gross_func_args_t>>;
520 using gross_func_args_t = std::tuple_element_t<1, return_type_typelist_and_gross_func_args_t>;
521 constexpr auto DETECTED_HOW_TO_INVOKE_GENERIC_FUNC =
522 func_is_generic ? !std::is_same_v<gross_func_args_t, ttg::typelist<>> : true;
523 static_assert(DETECTED_HOW_TO_INVOKE_GENERIC_FUNC,
524 "ttd::make_tt(func, inedges, ...): could not detect how to invoke generic callable func, either the "
525 "signature of func "
526 "is faulty, or inedges does match the expected list of types, or both");
527
528 // net argument typelist
530 constexpr auto num_args = std::tuple_size_v<func_args_t>;
531
532 // if given task id, make sure it's passed via const lvalue ref
533 constexpr bool TASK_ID_PASSED_AS_CONST_LVALUE_REF =
535 constexpr bool TASK_ID_PASSED_AS_NONREF =
537 static_assert(
538 TASK_ID_PASSED_AS_CONST_LVALUE_REF || TASK_ID_PASSED_AS_NONREF,
539 "ttg::make_tt(func, ...): if given to func, the task id must be passed by const lvalue ref or by value");
540
541 // if given out-terminal tuple, make sure it's passed via nonconst lvalue ref
542 constexpr bool have_outterm_tuple =
545 constexpr bool OUTTERM_TUPLE_PASSED_AS_NONCONST_LVALUE_REF =
547 static_assert(
548 OUTTERM_TUPLE_PASSED_AS_NONCONST_LVALUE_REF,
549 "ttg::make_tt(func, ...): if given to func, the output terminal tuple must be passed by nonconst lvalue ref");
550
551 // TT needs actual types of arguments to func ... extract them and pass to CallableWrapTT
552 using input_edge_value_types = ttg::meta::typelist<std::decay_t<input_edge_valuesT>...>;
553 // input_args_t = {input_valuesT&&...}
554 using input_args_t = typename ttg::meta::take_first_n<
555 typename ttg::meta::drop_first_n<func_args_t, std::size_t(void_key ? 0 : 1)>::type,
556 std::tuple_size_v<func_args_t> - (void_key ? 0 : 1) - (have_outterm_tuple ? 1 : 0)>::type;
557 constexpr auto NO_ARGUMENTS_PASSED_AS_NONCONST_LVALUE_REF =
559 static_assert(
560 NO_ARGUMENTS_PASSED_AS_NONCONST_LVALUE_REF,
561 "ttg::make_tt(func, inedges, outedges): one or more arguments to func can only be passed by nonconst lvalue "
562 "ref; this is illegal, should only pass arguments as const lvalue ref or (nonconst) rvalue ref");
563 using decayed_input_args_t = ttg::meta::decayed_typelist_t<input_args_t>;
564 // 3. full_input_args_t = edge-types with non-void types replaced by input_args_t
566 using wrapT = typename CallableWrapTTAsTypelist<funcT, func_return_t, false, have_outterm_tuple, space, keyT,
567 output_terminals_type, full_input_args_t>::type;
568
569 return std::make_unique<wrapT>(std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
570}
571
572template <typename keyT = void, typename funcT,
573 typename... input_edge_valuesT, typename... output_edgesT>
574auto make_tt(funcT &&func, const std::tuple<ttg::Edge<keyT, input_edge_valuesT>...> &inedges = std::tuple<>{},
575 const std::tuple<output_edgesT...> &outedges = std::tuple<>{}, const std::string &name = "wrapper",
576 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_edge_valuesT), "input"),
577 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT), "output")) {
578 return make_tt<ttg::ExecutionSpace::Host, keyT>(std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
579}
580
581template <typename keyT, typename funcT, typename... input_valuesT, typename... output_edgesT>
582[[deprecated("use make_tt_tpl instead")]] inline auto wrapt(
583 funcT &&func, const std::tuple<ttg::Edge<keyT, input_valuesT>...> &inedges,
584 const std::tuple<output_edgesT...> &outedges, const std::string &name = "wrapper",
585 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_valuesT), "input"),
586 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT), "output")) {
587 return make_tt_tpl<keyT>(std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
588}
589
590template <typename keyT, typename funcT, typename... input_edge_valuesT, typename... output_edgesT>
591[[deprecated("use make_tt instead")]] auto wrap(
592 funcT &&func, const std::tuple<ttg::Edge<keyT, input_edge_valuesT>...> &inedges,
593 const std::tuple<output_edgesT...> &outedges, const std::string &name = "wrapper",
594 const std::vector<std::string> &innames = std::vector<std::string>(sizeof...(input_edge_valuesT), "input"),
595 const std::vector<std::string> &outnames = std::vector<std::string>(sizeof...(output_edgesT), "output")) {
596 return make_tt<keyT>(std::forward<funcT>(func), inedges, outedges, name, innames, outnames);
597}
598
599#endif // TTG_MAKE_TT_H
CallableWrapTT(funcT_ &&f, const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames)
Definition make_tt.h:246
auto call_func(Key &&key, Tuple &&args_tuple, output_terminalsT &out, std::index_sequence< S... >)
Definition make_tt.h:101
auto call_func(Tuple &&args_tuple, output_terminalsT &out, std::index_sequence< S... >)
Definition make_tt.h:134
auto call_func(Key &&key, output_terminalsT &out)
Definition make_tt.h:168
std::enable_if_t< std::is_same_v< ArgsTuple, input_refs_tuple_type > &&!ttg::meta::is_empty_tuple_v< input_refs_tuple_type > &&!ttg::meta::is_void_v< Key >, op_return_type > op(Key &&key, ArgsTuple &&args_tuple, output_terminalsT &out)
Definition make_tt.h:254
auto call_func(OutputTerminals &out)
Definition make_tt.h:200
std::enable_if_t< ttg::meta::is_empty_tuple_v< ArgsTuple > &&ttg::meta::is_void_v< Key >, op_return_type > op(output_terminalsT &out)
Definition make_tt.h:278
std::enable_if_t< ttg::meta::is_empty_tuple_v< ArgsTuple > &&!ttg::meta::is_void_v< Key >, op_return_type > op(Key &&key, output_terminalsT &out)
Definition make_tt.h:271
static auto make_output_terminal_ptrs(const Tuple &output_terminals, std::index_sequence< I... >)
Definition make_tt.h:233
auto process_return(ReturnT &&ret, output_terminalsT &out)
Definition make_tt.h:51
CallableWrapTT(funcT_ &&f, const input_edges_type &inedges, const typename baseT::output_edges_type &outedges, const std::string &name, const std::vector< std::string > &innames, const std::vector< std::string > &outnames)
Definition make_tt.h:240
std::enable_if_t< std::is_same_v< ArgsTuple, input_refs_tuple_type > &&!ttg::meta::is_empty_tuple_v< input_refs_tuple_type > &&ttg::meta::is_void_v< Key >, op_return_type > op(ArgsTuple &&args_tuple, output_terminalsT &out)
Definition make_tt.h:264
Edge is used to connect In and Out terminals.
Definition edge.h:26
auto wrap(funcT &&func, const std::tuple< ttg::Edge< keyT, input_edge_valuesT >... > &inedges, const std::tuple< output_edgesT... > &outedges, const std::string &name="wrapper", const std::vector< std::string > &innames=std::vector< std::string >(sizeof...(input_edge_valuesT), "input"), const std::vector< std::string > &outnames=std::vector< std::string >(sizeof...(output_edgesT), "output"))
Definition make_tt.h:591
auto make_tt_tpl(funcT &&func, const std::tuple< ttg::Edge< keyT, input_edge_valuesT >... > &inedges=std::tuple<>{}, const std::tuple< output_edgesT... > &outedges=std::tuple<>{}, const std::string &name="wrapper", const std::vector< std::string > &innames=std::vector< std::string >(sizeof...(input_edge_valuesT), "input"), const std::vector< std::string > &outnames=std::vector< std::string >(sizeof...(output_edgesT), "output"))
Factory function to assist in wrapping a callable with signature.
Definition make_tt.h:344
auto make_tt(funcT &&func, const std::tuple< ttg::Edge< keyT, input_edge_valuesT >... > &inedges=std::tuple<>{}, const std::tuple< output_edgesT... > &outedges=std::tuple<>{}, const std::string &name="wrapper", const std::vector< std::string > &innames=std::vector< std::string >(sizeof...(input_edge_valuesT), "input"), const std::vector< std::string > &outnames=std::vector< std::string >(sizeof...(output_edgesT), "output"))
Factory function to assist in wrapping a callable with signature.
Definition make_tt.h:492
auto wrapt(funcT &&func, const std::tuple< ttg::Edge< keyT, input_valuesT >... > &inedges, const std::tuple< output_edgesT... > &outedges, const std::string &name="wrapper", const std::vector< std::string > &innames=std::vector< std::string >(sizeof...(input_valuesT), "input"), const std::vector< std::string > &outnames=std::vector< std::string >(sizeof...(output_edgesT), "output"))
Definition make_tt.h:582
STL namespace.
constexpr bool is_none_Void_v
Definition meta.h:249
constexpr bool probe_last_v
Definition meta.h:118
auto compute_arg_binding_types(Func &func, typelist< Typelists... > argument_type_lists)
Definition callable.h:155
typename tuple_concat< TupleTs... >::type tuple_concat_t
Definition meta.h:58
typename candidate_argument_bindings< T >::type candidate_argument_bindings_t
Definition callable.h:222
constexpr auto get(typelist< T, RestOfTs... >)
Definition typelist.h:102
top-level TTG namespace contains runtime-neutral functionality
Definition keymap.h:9
ExecutionSpace
denotes task execution space
Definition execution.h:18
void abort()
Aborts the TTG program using the default backend's ttg_abort method.
Definition run.h:104
TTG_CXX_COROUTINE_NAMESPACE::coroutine_handle< Promise > coroutine_handle
Definition coroutine.h:25
drops N elements from the front
Definition meta.h:334
take first N elements of a type list
Definition meta.h:358
A container for types.
Definition typelist.h:25