ttg 1.0.0
Template Task Graph (TTG): flowgraph-based programming model for high-performance distributed-memory algorithms
Loading...
Searching...
No Matches
tt.h
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2#ifndef TTG_BASE_OP_H
3#define TTG_BASE_OP_H
4
5#include <cstdint>
6#include <iostream>
7#include <optional>
8#include <sstream>
9#include <string>
10#include <vector>
11
12#include "ttg/base/terminal.h"
13#include "ttg/util/demangle.h"
14#include "ttg/util/trace.h"
15
16namespace ttg {
17
18 namespace detail {
19 // If true prints trace of all assignments and all TT invocations
20 inline bool &tt_base_trace_accessor(void) {
21 static bool trace = false;
22 return trace;
23 }
24
25 inline bool &op_base_lazy_pull_accessor(void) {
26 static bool lazy_pull = false;
27 return lazy_pull;
28 }
29 } // namespace detail
30
32 class TTBase {
33 private:
34 int64_t instance_id;
35
36 std::string name;
37 std::vector<TerminalBase *> inputs;
38 std::vector<TerminalBase *> outputs;
39 bool trace_instance = false;
40 const TTBase *owning_ttg = nullptr;
41 template <typename input_terminalsT, typename output_terminalsT>
42 friend class TTG; // TTG needs to be able to control owning_ttg
43
44 bool executable = false;
45 bool is_ttg_ = false;
46 bool lazy_pull_instance = false;
47
48 // Default copy/move/assign all OK
49 static uint64_t next_instance_id() {
50 static uint64_t id = 0;
51 return id++;
52 }
53
54 protected:
55 void set_input(size_t i, TerminalBase *t) {
56 if (i >= inputs.size()) throw(name + ":TTBase: out of range i setting input");
57 inputs[i] = t;
58 }
59
60 void set_output(size_t i, TerminalBase *t) {
61 if (i >= outputs.size()) throw(name + ":TTBase: out of range i setting output");
62 outputs[i] = t;
63 }
64
65 template <bool out, typename terminalT, std::size_t i, typename setfuncT>
66 void register_terminal(terminalT &term, const std::string &name, const setfuncT setfunc) {
67 term.set(this, i, name, detail::demangled_type_name<typename terminalT::key_type>(),
68 detail::demangled_type_name<typename terminalT::value_type>(),
70 : (std::is_const_v<typename terminalT::value_type> ? TerminalBase::Type::Read
72 (this->*setfunc)(i, &term);
73 }
74
75 template <bool out, std::size_t... IS, typename terminalsT, typename namesT, typename setfuncT>
76 void register_terminals(std::index_sequence<IS...>, terminalsT &terms, const namesT &names,
77 const setfuncT setfunc) {
78 int junk[] = {
79 0, (register_terminal<out, std::tuple_element_t<IS, terminalsT>, IS>(std::get<IS>(terms), names[IS], setfunc),
80 0)...};
81 junk[0]++;
82 }
83
84 // Used by op ... terminalsT will be a tuple of terminals
85 template <typename terminalsT, typename namesT>
86 void register_input_terminals(terminalsT &terms, const namesT &names) {
87 register_terminals<false>(std::make_index_sequence<std::tuple_size_v<terminalsT>>{}, terms, names,
89 }
90
91 // Used by op ... terminalsT will be a tuple of terminals
92 template <typename terminalsT, typename namesT>
93 void register_output_terminals(terminalsT &terms, const namesT &names) {
94 register_terminals<true>(std::make_index_sequence<std::tuple_size_v<terminalsT>>{}, terms, names,
96 }
97
98 // Used by composite TT ... terminalsT will be a tuple of pointers to terminals
99 template <std::size_t... IS, typename terminalsT, typename setfuncT>
100 void set_terminals(std::index_sequence<IS...>, terminalsT &terms, const setfuncT setfunc) {
101 int junk[] = {0, ((this->*setfunc)(IS, std::get<IS>(terms)), 0)...};
102 junk[0]++;
103 }
104
105 // Used by composite TT ... terminalsT will be a tuple of pointers to terminals
106 template <typename terminalsT, typename setfuncT>
107 void set_terminals(const terminalsT &terms, const setfuncT setfunc) {
108 set_terminals(std::make_index_sequence<std::tuple_size_v<terminalsT>>{}, terms, setfunc);
109 }
110
111 private:
112 // non-copyable, but movable
113 TTBase(const TTBase &) = delete;
114 TTBase &operator=(const TTBase &) = delete;
115
116 protected:
117 TTBase(TTBase &&other)
118 : instance_id(other.instance_id)
119 , is_ttg_(std::move(other.is_ttg_))
120 , name(std::move(other.name))
121 , inputs(std::move(other.inputs))
122 , outputs(std::move(other.outputs)) {
123 other.instance_id = -1;
124 }
126 instance_id = other.instance_id;
127 is_ttg_ = std::move(other.is_ttg_);
128 name = std::move(other.name);
129 inputs = std::move(other.inputs);
130 outputs = std::move(other.outputs);
131 other.instance_id = -1;
132 return *this;
133 }
134
135 TTBase(const std::string &name, size_t numins, size_t numouts)
136 : instance_id(next_instance_id()), is_ttg_(false), name(name), inputs(numins), outputs(numouts) {}
137
138 static const std::vector<TerminalBase *> *&outputs_tls_ptr_accessor() {
139 static thread_local const std::vector<TerminalBase *> *outputs_tls_ptr = nullptr;
140 return outputs_tls_ptr;
141 }
142 void set_outputs_tls_ptr() { outputs_tls_ptr_accessor() = &this->outputs; }
143 void set_outputs_tls_ptr(const std::vector<TerminalBase *> *ptr) { outputs_tls_ptr_accessor() = ptr; }
144
145 public:
146 virtual ~TTBase() = default;
147
151 virtual void invoke() {
152 std::cerr << "TTBase::invoke() invoked on a TT that did not override it" << std::endl;
153 ttg::abort();
154 }
155
158 static bool set_trace_all(bool value) {
159 if constexpr (trace_enabled()) std::swap(ttg::detail::tt_base_trace_accessor(), value);
160 return value;
161 }
162
163 //Sets lazy pulling on.
164 //Lazy pulling delays invoking pull terminals until all inputs from push terminals for a task have arrived.
165 //Default is false.
166 static bool set_lazy_pull(bool value) {
167 std::swap(ttg::detail::op_base_lazy_pull_accessor(), value);
168 return value;
169 }
170
173 bool set_trace_instance(bool value) {
174 if constexpr (trace_enabled()) std::swap(trace_instance, value);
175 return value;
176 }
177
179 bool tracing() const {
180 if constexpr (trace_enabled())
181 return ttg::detail::tt_base_trace_accessor() || trace_instance;
182 else
183 return false;
184 }
185
187 template <typename T, typename... Ts>
188 inline void trace(const T &t, const Ts &...ts) {
189 if constexpr (trace_enabled()) {
190 if (this->tracing()) {
191 log(t, ts...);
192 }
193 }
194 }
195
196 bool set_lazy_pull_instance(bool value) {
197 std::swap(lazy_pull_instance, value);
198 return value;
199 }
200
201 bool is_lazy_pull() { return ttg::detail::op_base_lazy_pull_accessor() || lazy_pull_instance; }
202
203 std::optional<std::reference_wrapper<const TTBase>> ttg() const {
204 return owning_ttg ? std::cref(*owning_ttg) : std::optional<std::reference_wrapper<const TTBase>>{};
205 }
206
207 const TTBase *ttg_ptr() const {
208 return owning_ttg;
209 }
210
211 bool is_ttg() const {
212 return is_ttg_;
213 }
214
216 void set_name(const std::string &name) { this->name = name; }
217
219 const std::string &get_name() const { return name; }
220
222 std::string get_class_name() const { return ttg::detail::demangled_type_name(this); }
223
225 const std::vector<TerminalBase *> &get_inputs() const { return inputs; }
226
228 const std::vector<TerminalBase *> &get_outputs() const { return outputs; }
229
231 static const std::vector<TerminalBase *> *get_outputs_tls_ptr() { return outputs_tls_ptr_accessor(); }
232
234 virtual ttg::World get_world() const = 0;
235
238 if (i >= inputs.size()) throw name + ":TTBase: you are requesting an input terminal that does not exist";
239 return inputs[i];
240 }
241
244 if (i >= outputs.size()) throw name + "TTBase: you are requesting an output terminal that does not exist";
245 return outputs[i];
246 }
247
249 template <std::size_t i>
251 return in(i);
252 }
253
255 template <std::size_t i>
257 return out(i);
258 }
259
260 auto get_instance_id() const { return instance_id; }
261
264 virtual void fence() = 0;
265
266 virtual void release() {}
267
269 virtual void make_executable() = 0;
270
273 bool is_executable() const { return executable; }
274
278#define TTG_OP_ASSERT_EXECUTABLE() \
279 do { \
280 if (!this->is_executable()) { \
281 std::ostringstream oss; \
282 oss << "TT is not executable at " << __FILE__ << ":" << __LINE__; \
283 throw std::logic_error(oss.str().c_str()); \
284 } \
285 } while (0);
286 };
287
288 inline void TTBase::make_executable() { executable = true; }
289
290} // namespace ttg
291
292#endif // TTG_BASE_OP_H
A base class for all template tasks.
Definition tt.h:32
void set_terminals(const terminalsT &terms, const setfuncT setfunc)
Definition tt.h:107
virtual void invoke()
Definition tt.h:151
void set_outputs_tls_ptr(const std::vector< TerminalBase * > *ptr)
Definition tt.h:143
virtual ~TTBase()=default
void trace(const T &t, const Ts &...ts)
Like ttg::trace(), but only produces tracing output if this->tracing()==true
Definition tt.h:188
TTBase(const std::string &name, size_t numins, size_t numouts)
Definition tt.h:135
auto get_instance_id() const
Definition tt.h:260
void register_terminal(terminalT &term, const std::string &name, const setfuncT setfunc)
Definition tt.h:66
const std::vector< TerminalBase * > & get_outputs() const
Returns the vector of output terminals.
Definition tt.h:228
void set_terminals(std::index_sequence< IS... >, terminalsT &terms, const setfuncT setfunc)
Definition tt.h:100
bool set_trace_instance(bool value)
Definition tt.h:173
virtual void make_executable()=0
Marks this executable.
Definition tt.h:288
std::optional< std::reference_wrapper< const TTBase > > ttg() const
Definition tt.h:203
ttg::TerminalBase * in(size_t i)
Returns a pointer to the i'th input terminal.
Definition tt.h:237
bool tracing() const
Definition tt.h:179
ttg::TerminalBase * out(size_t i)
Returns a pointer to the i'th output terminal.
Definition tt.h:243
virtual ttg::World get_world() const =0
TTBase & operator=(TTBase &&other)
Definition tt.h:125
ttg::TerminalBase * out()
Returns a pointer to the i'th output terminal ... to make API consistent with TT.
Definition tt.h:256
std::string get_class_name() const
Gets the demangled class name (uses RTTI)
Definition tt.h:222
bool set_lazy_pull_instance(bool value)
Definition tt.h:196
bool is_executable() const
Definition tt.h:273
void set_output(size_t i, TerminalBase *t)
Definition tt.h:60
void set_name(const std::string &name)
Sets the name of this operation.
Definition tt.h:216
ttg::TerminalBase * in()
Returns a pointer to the i'th input terminal ... to make API consistent with TT.
Definition tt.h:250
static bool set_lazy_pull(bool value)
Definition tt.h:166
static const std::vector< TerminalBase * > *& outputs_tls_ptr_accessor()
Definition tt.h:138
bool is_ttg() const
Definition tt.h:211
virtual void release()
Definition tt.h:266
TTBase(TTBase &&other)
Definition tt.h:117
static const std::vector< TerminalBase * > * get_outputs_tls_ptr()
Returns this thread's pointer to the vector of output terminals.
Definition tt.h:231
const std::vector< TerminalBase * > & get_inputs() const
Returns the vector of input terminals.
Definition tt.h:225
static bool set_trace_all(bool value)
Definition tt.h:158
void register_input_terminals(terminalsT &terms, const namesT &names)
Definition tt.h:86
void register_terminals(std::index_sequence< IS... >, terminalsT &terms, const namesT &names, const setfuncT setfunc)
Definition tt.h:76
const TTBase * ttg_ptr() const
Definition tt.h:207
const std::string & get_name() const
Gets the name of this operation.
Definition tt.h:219
bool is_lazy_pull()
Definition tt.h:201
virtual void fence()=0
void set_input(size_t i, TerminalBase *t)
Definition tt.h:55
void register_output_terminals(terminalsT &terms, const namesT &names)
Definition tt.h:93
void set_outputs_tls_ptr()
Definition tt.h:142
a template task graph implementation
Definition tt.h:32
@ Write
can only be written to
@ Read
can only be used to read immutable data
@ Consume
can only be used to read consumable data
STL namespace.
bool & tt_base_trace_accessor(void)
Definition tt.h:20
bool & op_base_lazy_pull_accessor(void)
Definition tt.h:25
top-level TTG namespace contains runtime-neutral functionality
Definition keymap.h:9
void abort()
Aborts the TTG program using the default backend's ttg_abort method.
Definition run.h:104
void log(const T &t, const Ts &... ts)
atomically prints to std::clog a sequence of items (separated by ttg::print_separator) followed by st...
Definition print.h:147
bool tracing()
returns whether tracing is enabled
Definition trace.h:29
void trace(const T &t, const Ts &... ts)
Definition trace.h:44
constexpr bool trace_enabled()
returns whether tracing was enabled at configure time
Definition trace.h:16