4 #include "ttg/config.h"
10 #ifdef TTG_HAVE_COROUTINE
30 template <
typename input_terminalsT,
typename output_terminalsT>
33 static constexpr
int numins = std::tuple_size_v<input_terminalsT>;
34 static constexpr
int numouts = std::tuple_size_v<output_terminalsT>;
40 std::vector<std::unique_ptr<TTBase>> tts;
46 TTG &operator=(
const TTG &) =
delete;
51 , ins(std::move(other.ins))
52 , outs(std::move(other.outs)) {
56 TTG &operator=(
TTG &&other) {
57 static_cast<TTBase &
>(*this) =
static_cast<TTBase &&
>(other);
59 tts = std::move(other.tts);
60 ins = std::move(other.ins);
61 outs = std::move(other.outs);
68 template <
typename ttseqT>
72 const std::string &name =
"ttg")
74 if (this->tts.size() == 0)
throw name +
":TTG: need to wrap at least one TT";
85 template <std::
size_t i>
87 return std::get<i>(ins);
91 template <std::
size_t i>
93 return std::get<i>(outs);
100 void fence()
override { tts[0]->fence(); }
103 for (
auto &op : tts) op->make_executable();
107 void own_my_tts()
const {
108 for (
auto &op : tts) op->owning_ttg =
this;
112 template <
typename ttseqT,
typename input_terminalsT,
typename output_terminalsT>
113 auto make_ttg(ttseqT &&tts,
const input_terminalsT &ins,
const output_terminalsT &outs,
114 const std::string &name =
"ttg") {
115 return std::make_unique<TTG<input_terminalsT, output_terminalsT>>(std::forward<ttseqT>(tts), ins, outs, name);
119 template <
typename keyT,
typename input_valueT>
121 static constexpr
int numins = 1;
122 static constexpr
int numouts = 0;
124 using input_terminals_type = std::tuple<ttg::In<keyT, input_valueT>>;
125 using input_edges_type = std::tuple<ttg::Edge<keyT, std::decay_t<input_valueT>>>;
126 using output_terminals_type = std::tuple<>;
129 input_terminals_type input_terminals;
130 output_terminals_type output_terminals;
137 template <
typename terminalT>
138 void register_input_callback(terminalT &input) {
139 using valueT = std::decay_t<typename terminalT::value_type>;
140 auto move_callback = [](
const keyT &key, valueT &&value) {};
141 auto send_callback = [](
const keyT &key,
const valueT &value) {};
142 auto broadcast_callback = [](
const ttg::span<const keyT> &key,
const valueT &value) {};
143 auto setsize_callback = [](
const keyT &key, std::size_t
size) {};
144 auto finalize_callback = [](
const keyT &key) {};
146 input.set_callback(send_callback, move_callback, broadcast_callback, setsize_callback, finalize_callback);
150 SinkTT(
const std::string &inname =
"junk") :
TTBase(
"sink", numins, numouts) {
152 register_input_callback(std::get<0>(input_terminals));
155 SinkTT(
const input_edges_type &inedges,
const std::string &inname =
"junk") :
TTBase(
"sink", numins, numouts) {
157 register_input_callback(std::get<0>(input_terminals));
158 std::get<0>(inedges).set_out(&std::get<0>(input_terminals));
170 template <std::
size_t i>
171 std::tuple_element_t<i, input_terminals_type> *
in() {
172 static_assert(i == 0);
173 return &std::get<i>(input_terminals);
179 #ifndef TTG_PROCESS_TT_OP_RETURN
180 #ifdef TTG_HAVE_COROUTINE
181 #define TTG_PROCESS_TT_OP_RETURN(result, id, invoke) \
183 using return_type = decltype(invoke); \
184 if constexpr (std::is_same_v<return_type, void>) { \
186 id = ttg::TaskCoroutineID::Invalid; \
188 auto coro_return = invoke; \
189 static_assert(std::is_same_v<return_type, void> || \
190 std::is_base_of_v<ttg::coroutine_handle<ttg::resumable_task_state>, decltype(coro_return)>|| \
191 std::is_base_of_v<ttg::coroutine_handle<ttg::device::detail::device_task_promise_type>, \
192 decltype(coro_return)>); \
193 if constexpr (std::is_base_of_v<ttg::coroutine_handle<ttg::resumable_task_state>, decltype(coro_return)>) \
194 id = ttg::TaskCoroutineID::ResumableTask; \
195 else if constexpr (std::is_base_of_v< \
196 ttg::coroutine_handle<ttg::device::detail::device_task_promise_type>, \
197 decltype(coro_return)>) \
198 id = ttg::TaskCoroutineID::DeviceTask; \
201 result = coro_return.address(); \
205 #define TTG_PROCESS_TT_OP_RETURN(result, id, invoke) invoke
208 #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")
void fence() override final
std::tuple_element_t< i, input_terminals_type > * in()
Returns pointer to input terminal i to facilitate connection — terminal cannot be copied,...
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.
input_terminalsT input_terminals_type
ttg::World get_world() const override final
static constexpr int numins
TTBase * get_op(std::size_t i)
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")