21 template <ttg::Runtime Runtime>
23 template <
typename Value>
24 inline constexpr decltype(
auto)
operator()(Value &&value)
const {
25 return std::forward<Value>(value);
29 template <
typename keyT,
typename valueT>
34 if (terminal_ptr ==
nullptr) {
37 <<
": invalid type of ith output terminal, most likely due to mismatch between its type "
38 "and the type of key/value; make sure that the arguments to "
40 <<
"() match the types encoded in the output "
41 "terminals, or pass the output terminal tuple to the task function explicitly";
42 throw std::runtime_error(ss.str());
51 template <
typename keyT>
56 if (terminal_ptr ==
nullptr) {
59 <<
": invalid type of ith output terminal, most likely due to mismatch between its type "
60 "and the type of key; make sure that the arguments to "
62 <<
"() match the types encoded in the output "
63 "terminals, or pass the output terminal tuple to the task function explicitly";
64 throw std::runtime_error(ss.str());
79 template <
typename... TTBasePtrs>
80 inline std::enable_if_t<(std::is_convertible_v<decltype(*(std::declval<TTBasePtrs>())), TTBase &> && ...),
bool>
82 auto traverse =
ttg::make_traverse([](
auto &&x) { std::forward<decltype(x)>(x)->make_executable(); });
83 auto ret = traverse(std::forward<TTBasePtrs>(tts)...);
85 auto world = [&](
auto&& tt0,
auto&&... tts) {
return tt0->get_world(); }(std::forward<TTBasePtrs>(tts)...);
86 TTG_IMPL_NS::make_executable_hook(world);
93 template <
typename keyT,
typename valueT>
107 template <std::
size_t outindex, std::
size_t inindex,
typename producer_tt_ptr,
typename successor_tt_ptr>
108 inline void connect(producer_tt_ptr &p, successor_tt_ptr &c) {
109 connect(p->template out<outindex>(), c->template in<inindex>());
117 template <std::
size_t outindex, std::
size_t inindex,
typename producer_tt_ptr,
typename successor_tt_ptr>
118 inline void connect(producer_tt_ptr *p, successor_tt_ptr *c) {
119 connect(p->template out<outindex>(), c->template in<inindex>());
128 connect(producer->
out(outindex), consumer->
in(inindex));
137 template <
typename keyT,
typename... valuesT>
139 using valueT = std::tuple_element_t<0, std::tuple<valuesT...>>;
147 template <
typename... inedgesT>
148 inline auto edges(inedgesT &&...args) {
149 return std::make_tuple(std::forward<inedgesT>(args)...);
158 template <
typename keyT,
typename valueT,
typename output_terminalT, ttg::Runtime Runtime = ttg::ttg_runtime>
161 t.
send(key, copy_handler(std::forward<valueT>(value)));
169 template <
typename keyT>
179 template <
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
182 t.
sendv(copy_handler(std::forward<valueT>(value)));
198 template <
size_t i,
typename keyT,
typename valueT,
typename... out_keysT,
typename... out_valuesT,
200 inline std::enable_if_t<meta::is_none_void_v<keyT, std::decay_t<valueT>>,
void>
send(
203 std::get<i>(t).send(key, copy_handler(std::forward<valueT>(value)));
212 template <
typename keyT,
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
213 inline std::enable_if_t<meta::is_none_void_v<keyT, std::decay_t<valueT>>,
void>
send(
size_t i,
const keyT &key,
218 auto *terminal_ptr = detail::get_out_terminal<keyT, valueT>(i,
"ttg::send(i, key, value)");
219 terminal_ptr->send(key, copy_handler(std::forward<valueT>(value)));
229 template <
size_t i,
typename keyT,
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
230 inline std::enable_if_t<meta::is_none_void_v<keyT, std::decay_t<valueT>>,
void>
send(
const keyT &key,
234 send(i, key, std::forward<valueT>(value));
243 template <
size_t i,
typename keyT,
typename... out_keysT,
typename... out_valuesT>
244 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
sendk(
const keyT &key,
246 std::get<i>(t).sendk(key);
254 template <
typename keyT>
255 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
sendk(std::size_t i,
const keyT &key) {
258 auto *terminal_ptr = detail::get_out_terminal<keyT, void>(i,
"ttg::sendk(i, key)");
259 terminal_ptr->sendk(key);
268 template <
size_t i,
typename keyT>
269 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
sendk(
const keyT &key) {
281 template <
size_t i,
typename valueT,
typename... out_keysT,
typename... out_valuesT,
283 inline std::enable_if_t<!meta::is_void_v<std::decay_t<valueT>>,
void>
sendv(
286 std::get<i>(t).sendv(copy_handler(std::forward<valueT>(value)));
294 template <
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
295 inline std::enable_if_t<!meta::is_void_v<std::decay_t<valueT>>,
void>
sendv(std::size_t i, valueT &&value) {
299 auto *terminal_ptr = detail::get_out_terminal<void, valueT>(i,
"ttg::sendv(i, value)");
300 terminal_ptr->sendv(copy_handler(std::forward<valueT>(value)));
309 template <
size_t i,
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
310 inline std::enable_if_t<!meta::is_void_v<std::decay_t<valueT>>,
void>
sendv(valueT &&value) {
313 sendv(i, std::forward<valueT>(value));
321 template <
size_t i,
typename... out_keysT,
typename... out_valuesT>
323 std::get<i>(t).send();
330 inline void send(std::size_t i) {
331 auto *terminal_ptr = detail::get_out_terminal<void, void>(i,
"ttg::send(i)");
332 terminal_ptr->send();
346 template <
size_t KeyId,
size_t i,
size_t... I,
typename... RangesT,
typename valueT,
typename... out_keysT,
347 typename... out_valuesT>
348 inline void broadcast(
const std::tuple<RangesT...> &keylists, valueT &&value,
351 if (std::distance(std::begin(std::get<KeyId>(keylists)), std::end(std::get<KeyId>(keylists))) > 0) {
352 std::get<i>(t).broadcast(std::get<KeyId>(keylists), value);
355 std::get<i>(t).broadcast(std::get<KeyId>(keylists), value);
357 if constexpr (
sizeof...(I) > 0) {
362 template <
size_t KeyId,
size_t i,
size_t... I,
typename... RangesT,
typename valueT>
363 inline void broadcast(
const std::tuple<RangesT...> &keylists, valueT &&value) {
365 if (std::distance(std::begin(std::get<KeyId>(keylists)), std::end(std::get<KeyId>(keylists))) > 0) {
366 using key_t =
decltype(*std::begin(std::get<KeyId>(keylists)));
367 auto *terminal_ptr = detail::get_out_terminal<key_t, valueT>(i,
"ttg::broadcast(keylists, value)");
368 terminal_ptr->broadcast(std::get<KeyId>(keylists), value);
371 using key_t =
decltype(std::get<KeyId>(keylists));
372 auto *terminal_ptr = detail::get_out_terminal<key_t, valueT>(i,
"ttg::broadcast(keylists, value)");
373 terminal_ptr->broadcast(std::get<KeyId>(keylists), value);
375 if constexpr (
sizeof...(I) > 0) {
380 template <
size_t KeyId,
size_t i,
size_t... I,
typename... RangesT,
typename... out_keysT,
typename... out_valuesT>
383 if (std::distance(std::begin(std::get<KeyId>(keylists)), std::end(std::get<KeyId>(keylists))) > 0) {
384 std::get<i>(t).broadcast(std::get<KeyId>(keylists));
387 std::get<i>(t).broadcast(std::get<KeyId>(keylists));
389 if constexpr (
sizeof...(I) > 0) {
394 template <
size_t KeyId,
size_t i,
size_t... I,
typename... RangesT>
395 inline void broadcast(
const std::tuple<RangesT...> &keylists) {
397 if (std::distance(std::begin(std::get<KeyId>(keylists)), std::end(std::get<KeyId>(keylists))) > 0) {
398 using key_t =
decltype(*std::begin(std::get<KeyId>(keylists)));
399 auto *terminal_ptr = detail::get_out_terminal<key_t, void>(i,
"ttg::broadcast(keylists)");
400 terminal_ptr->broadcast(std::get<KeyId>(keylists));
403 using key_t =
decltype(std::get<KeyId>(keylists));
404 auto *terminal_ptr = detail::get_out_terminal<key_t, void>(i,
"ttg::broadcast(keylists)");
405 terminal_ptr->broadcast(std::get<KeyId>(keylists));
407 if constexpr (
sizeof...(I) > 0) {
413 template <
size_t i,
typename rangeT,
typename valueT,
typename... out_keysT,
typename... out_valuesT,
417 std::get<i>(t).broadcast(keylist, copy_handler(std::forward<valueT>(value)));
420 template <
typename rangeT,
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
421 inline void broadcast(std::size_t i,
const rangeT &keylist, valueT &&value) {
423 using key_t =
decltype(*std::begin(keylist));
424 auto *terminal_ptr = detail::get_out_terminal<key_t, valueT>(i,
"ttg::broadcast(keylist, value)");
425 terminal_ptr->broadcast(keylist, copy_handler(std::forward<valueT>(value)));
428 template <
size_t i,
typename rangeT,
typename valueT, ttg::Runtime Runtime = ttg::ttg_runtime>
429 inline void broadcast(
const rangeT &keylist, valueT &&value) {
430 broadcast(i, keylist, std::forward<valueT>(value));
433 template <
size_t i,
size_t... I,
typename... RangesT,
typename valueT,
typename... out_keysT,
typename... out_valuesT,
435 inline void broadcast(
const std::tuple<RangesT...> &keylists, valueT &&value,
437 static_assert(
sizeof...(I) + 1 ==
sizeof...(RangesT),
438 "Number of selected output terminals must match the number of keylists!");
440 detail::broadcast<0, i, I...>(keylists, copy_handler(std::forward<valueT>(value)), t);
444 inline void broadcast(
const std::tuple<RangesT...> &keylists, valueT &&value) {
445 static_assert(
sizeof...(I) + 1 ==
sizeof...(RangesT),
446 "Number of selected output terminals must match the number of keylists!");
448 detail::broadcast<0, i, I...>(keylists, copy_handler(std::forward<valueT>(value)));
451 template <
size_t i,
typename rangeT,
typename... out_keysT,
typename... out_valuesT,
454 std::get<i>(t).broadcast(keylist);
457 template <
typename rangeT, ttg::Runtime Runtime = ttg::ttg_runtime>
458 inline void broadcastk(std::size_t i,
const rangeT &keylist) {
459 using key_t =
decltype(*std::begin(keylist));
460 auto *terminal_ptr = detail::get_out_terminal<key_t, void>(i,
"ttg::broadcastk(keylist)");
461 terminal_ptr->broadcast(keylist);
464 template <
size_t i,
typename rangeT, ttg::Runtime Runtime = ttg::ttg_runtime>
469 template <
size_t i,
size_t... I,
typename... RangesT,
typename... out_keysT,
typename... out_valuesT,
472 static_assert(
sizeof...(I) + 1 ==
sizeof...(RangesT),
473 "Number of selected output terminals must match the number of keylists!");
478 inline void broadcastk(
const std::tuple<RangesT...> &keylists) {
479 static_assert(
sizeof...(I) + 1 ==
sizeof...(RangesT),
480 "Number of selected output terminals must match the number of keylists!");
484 template <
typename keyT,
typename out_valueT>
485 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
set_size(
const keyT &key,
const std::size_t
size,
494 template <
size_t i,
typename keyT,
typename... out_keysT,
typename... out_valuesT>
495 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
set_size(
const keyT &key,
const std::size_t
size,
497 std::get<i>(t).set_size(key,
size);
500 template <
typename keyT>
501 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
set_size(std::size_t i,
const keyT &key,
502 const std::size_t
size) {
503 auto *terminal_ptr = detail::get_out_base_terminal<keyT>(i,
"ttg::set_size(i, key, size)");
504 terminal_ptr->set_size(
size);
507 template <
size_t i,
typename keyT>
508 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
set_size(
const keyT &key,
const std::size_t
size) {
515 template <
typename out_keyT,
typename out_valueT>
524 template <
size_t i,
typename... out_keysT,
typename... out_valuesT>
526 std::get<i>(t).set_size(
size);
530 auto *terminal_ptr = detail::get_out_base_terminal<void>(i,
"ttg::set_size(i, size)");
531 terminal_ptr->set_size(
size);
534 template <std::
size_t i>
543 template <
typename keyT,
typename out_keyT,
typename out_valueT>
552 template <
size_t i,
typename keyT,
typename... out_keysT,
typename... out_valuesT>
553 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
finalize(
const keyT &key,
555 std::get<i>(t).finalize(key);
558 template <
typename keyT>
559 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
finalize(std::size_t i,
const keyT &key) {
560 auto *terminal_ptr = detail::get_out_base_terminal<keyT>(i,
"ttg::finalize(i, key)");
561 terminal_ptr->finalize(key);
564 template <std::
size_t i,
typename keyT>
565 inline std::enable_if_t<!meta::is_void_v<keyT>,
void>
finalize(
const keyT &key) {
571 template <
typename out_keyT,
typename out_valueT>
579 template <
size_t i,
typename... out_keysT,
typename... out_valuesT>
581 std::get<i>(t).finalize();
585 auto *terminal_ptr = detail::get_out_base_terminal<void>(i,
"ttg::finalize(i)");
586 terminal_ptr->finalize();
589 template <std::
size_t i>
Edge is used to connect In and Out terminals.
void connect(TerminalBase *in) override
std::enable_if_t< meta::is_void_v< Key > &&!meta::is_void_v< Value >, void > sendv(Value &&value)
std::enable_if_t<!meta::is_void_v< Key > &&meta::is_void_v< Value >, void > sendk(const Key &key)
std::enable_if_t< meta::is_all_void_v< Key, Value >, void > send()
std::enable_if_t<!meta::is_void_v< Key >, void > set_size(const Key &key, std::size_t size)
std::enable_if_t<!meta::is_void_v< Key >, void > finalize(const Key &key)
A base class for all template tasks.
ttg::TerminalBase * in(size_t i)
Returns a pointer to the i'th input terminal.
ttg::TerminalBase * out(size_t i)
Returns a pointer to the i'th output terminal.
static const std::vector< TerminalBase * > * get_outputs_tls_ptr()
Returns this thread's pointer to the vector of output terminals.
virtual void connect(TerminalBase *in)=0
auto get_out_terminal(size_t i, const char *func)
auto get_out_base_terminal(size_t i, const char *func)
void broadcast(const std::tuple< RangesT... > &keylists, valueT &&value, std::tuple< ttg::Out< out_keysT, out_valuesT >... > &t)
top-level TTG namespace contains runtime-neutral functionality
auto fuse(const Edge< keyT, valuesT > &...args)
Fuse edges into one This allows receiving one data from either of the combined edges.
void send()
Sends a control message (message without an accompanying task id or a value) to the template tasks at...
constexpr const ttg::Runtime ttg_runtime
int size(World world=default_execution_context())
std::enable_if_t<!meta::is_void_v< keyT >, void > set_size(const keyT &key, const std::size_t size, ttg::Out< keyT, out_valueT > &t)
void sendk(const keyT &key, ttg::Out< keyT, void > &t)
Sends a task id (without an accompanying value) to the given output terminal.
void sendv(valueT &&value, ttg::Out< void, valueT > &t)
Sends a value (without an accompanying task id) to the given output terminal.
void finalize()
Finalizes the TTG runtime.
void connect(ttg::Out< keyT, valueT > *out, ttg::In< keyT, valueT > *in)
Connect output terminal to successor input terminal.
auto make_traverse(TTVisitor &&tt_v=trivial_1param_lambda, InVisitor &&in_v=trivial_1param_lambda, OutVisitor &&out_v=trivial_1param_lambda)
void broadcast(const rangeT &keylist, valueT &&value, std::tuple< ttg::Out< out_keysT, out_valuesT >... > &t)
void broadcastk(const rangeT &keylist, std::tuple< ttg::Out< out_keysT, out_valuesT >... > &t)
std::enable_if_t<(std::is_convertible_v< decltype(*(std::declval< TTBasePtrs >())), TTBase & > &&...), bool > make_graph_executable(TTBasePtrs &&...tts)
Make the TTG tts executable. Applies.
auto edges(inedgesT &&...args)
Make a tuple of Edges to pass to.