11#ifdef TTG_HAVE_COROUTINE
31 template <
typename input_terminalsT,
typename output_terminalsT>
34 static constexpr int numins = std::tuple_size_v<input_terminalsT>;
35 static constexpr int numouts = std::tuple_size_v<output_terminalsT>;
41 std::vector<std::unique_ptr<TTBase>> tts;
47 TTG &operator=(
const TTG &) =
delete;
51 , tts(
std::move(other.tts))
52 , ins(
std::move(other.ins))
53 , outs(
std::move(other.outs)) {
57 TTG &operator=(
TTG &&other) {
58 static_cast<TTBase &
>(*this) =
static_cast<TTBase &&
>(other);
60 tts = std::move(other.tts);
61 ins = std::move(other.ins);
62 outs = std::move(other.outs);
69 template <
typename ttseqT>
73 const std::string &name =
"ttg")
75 if (this->tts.size() == 0)
throw name +
":TTG: need to wrap at least one TT";
86 template <std::
size_t i>
88 return std::get<i>(ins);
92 template <std::
size_t i>
94 return std::get<i>(outs);
101 void fence()
override { tts[0]->fence(); }
104 for (
auto &op : tts) op->make_executable();
108 void own_my_tts()
const {
109 for (
auto &op : tts) op->owning_ttg = this;
113 template <
typename ttseqT,
typename input_terminalsT,
typename output_terminalsT>
114 auto make_ttg(ttseqT &&tts,
const input_terminalsT &ins,
const output_terminalsT &outs,
115 const std::string &name =
"ttg") {
116 return std::make_unique<TTG<input_terminalsT, output_terminalsT>>(std::forward<ttseqT>(tts), ins, outs, name);
120 template <
typename keyT,
typename input_valueT>
122 static constexpr int numins = 1;
123 static constexpr int numouts = 0;
125 using input_terminals_type = std::tuple<ttg::In<keyT, input_valueT>>;
126 using input_edges_type = std::tuple<ttg::Edge<keyT, std::decay_t<input_valueT>>>;
127 using output_terminals_type = std::tuple<>;
130 input_terminals_type input_terminals;
131 output_terminals_type output_terminals;
138 template <
typename terminalT>
139 void register_input_callback(terminalT &input) {
140 using valueT = std::decay_t<typename terminalT::value_type>;
141 auto move_callback = [](
const keyT &key, valueT &&value) {};
142 auto send_callback = [](
const keyT &key,
const valueT &value) {};
143 auto broadcast_callback = [](
const ttg::span<const keyT> &key,
const valueT &value) {};
144 auto setsize_callback = [](
const keyT &key, std::size_t
size) {};
145 auto finalize_callback = [](
const keyT &key) {};
147 input.set_callback(send_callback, move_callback, broadcast_callback, setsize_callback, finalize_callback);
151 SinkTT(
const std::string &inname =
"junk") :
TTBase(
"sink", numins, numouts) {
153 register_input_callback(std::get<0>(input_terminals));
156 SinkTT(
const input_edges_type &inedges,
const std::string &inname =
"junk") :
TTBase(
"sink", numins, numouts) {
158 register_input_callback(std::get<0>(input_terminals));
159 std::get<0>(inedges).set_out(&std::get<0>(input_terminals));
171 template <std::
size_t i>
172 std::tuple_element_t<i, input_terminals_type> *
in() {
173 static_assert(i == 0);
174 return &std::get<i>(input_terminals);
180#ifndef TTG_PROCESS_TT_OP_RETURN
181#ifdef TTG_HAVE_COROUTINE
182#define TTG_PROCESS_TT_OP_RETURN(result, id, invoke) \
184 using return_type = decltype(invoke); \
185 if constexpr (std::is_same_v<return_type, void>) { \
187 id = ttg::TaskCoroutineID::Invalid; \
189 auto coro_return = invoke; \
190 static_assert(std::is_same_v<return_type, void> || \
191 std::is_base_of_v<ttg::coroutine_handle<ttg::resumable_task_state>, decltype(coro_return)>|| \
192 std::is_base_of_v<ttg::coroutine_handle<ttg::device::detail::device_task_promise_type>, \
193 decltype(coro_return)>); \
194 if constexpr (std::is_base_of_v<ttg::coroutine_handle<ttg::resumable_task_state>, decltype(coro_return)>) \
195 id = ttg::TaskCoroutineID::ResumableTask; \
196 else if constexpr (std::is_base_of_v< \
197 ttg::coroutine_handle<ttg::device::detail::device_task_promise_type>, \
198 decltype(coro_return)>) \
199 id = ttg::TaskCoroutineID::DeviceTask; \
202 result = coro_return.address(); \
206#define TTG_PROCESS_TT_OP_RETURN(result, id, invoke) invoke
209#error "TTG_PROCESS_TT_OP_RETURN already defined in ttg/tt.h, check your header guards"
A data sink for one input.
SinkTT(const std::string &inname="junk")
std::tuple_element_t< i, input_terminals_type > * in()
Returns pointer to input terminal i to facilitate connection — terminal cannot be copied,...
void fence() override final
World get_world() const override final
SinkTT(const input_edges_type &inedges, const std::string &inname="junk")
void make_executable() override final
Marks this executable.
A base class for all template tasks.
void set_terminals(std::index_sequence< IS... >, terminalsT &terms, const setfuncT setfunc)
virtual void make_executable()=0
Marks this executable.
void register_input_terminals(terminalsT &terms, const namesT &names)
a template task graph implementation
auto in()
Return a pointer to i'th input terminal.
auto out()
Return a pointer to i'th output terminal.
TTBase * get_op(std::size_t i)
input_terminalsT input_terminals_type
ttg::World get_world() const override final
static constexpr int numins
void make_executable() override
Marks this executable.
static constexpr int numouts
output_terminalsT output_terminals_type
TTG(ttseqT &&tts, const input_terminals_type &ins, const output_terminals_type &outs, const std::string &name="ttg")
top-level TTG namespace contains runtime-neutral functionality
int size(World world=default_execution_context())
ttg::World & get_default_world()
auto make_ttg(ttseqT &&tts, const input_terminalsT &ins, const output_terminalsT &outs, const std::string &name="ttg")