5 #include "flow_builder.hpp" 6 #include "topology.hpp" 20 friend class Topology;
118 assert(_topologies.empty());
128 return _graph.size();
133 return _graph.empty();
147 template <
typename V>
149 for(
size_t i=0; i<_graph._nodes.size(); ++i) {
150 visitor(
Task(_graph._nodes[i]));
163 os <<
"digraph Taskflow {\n";
173 dumper.stack.push(top);
174 dumper.visited.insert(top);
176 while(!dumper.stack.empty()) {
178 auto f = dumper.stack.top();
181 os <<
"subgraph cluster_p" << f <<
" {\nlabel=\"Taskflow: ";
182 if(f->_name.empty()) os <<
'p' << f;
185 _dump(os, f->_graph, dumper);
191 inline void Taskflow::_dump(
195 os <<
'p' << node <<
"[label=\"";
196 if(node->_name.empty()) os <<
'p' << node;
197 else os << node->_name;
201 switch(node->_handle.index()) {
203 case Node::CONDITION_WORK:
204 os <<
"shape=diamond color=black fillcolor=aquamarine style=filled";
207 #ifdef TF_ENABLE_CUDA 208 case Node::CUDAFLOW_WORK:
209 os <<
"shape=folder fillcolor=cyan style=filled";
219 for(
size_t s=0; s<node->_successors.size(); ++s) {
220 if(node->_handle.index() == Node::CONDITION_WORK) {
222 os <<
'p' << node <<
" -> p" << node->_successors[s]
223 <<
" [style=dashed label=\"" << s <<
"\"];\n";
226 os <<
'p' << node <<
" -> p" << node->_successors[s] <<
";\n";
231 if(node->_parent && node->_successors.size() == 0) {
232 os <<
'p' << node <<
" -> p" << node->_parent <<
";\n";
235 switch(node->_handle.index()) {
237 case Node::DYNAMIC_WORK: {
238 auto& sbg = nstd::get<Node::DynamicWork>(node->_handle).subgraph;
240 os <<
"subgraph cluster_p" << node <<
" {\nlabel=\"Subflow: ";
241 if(node->_name.empty()) os <<
'p' << node;
242 else os << node->_name;
244 os <<
"\";\n" <<
"color=blue\n";
245 _dump(os, sbg, dumper);
251 #ifdef TF_ENABLE_CUDA 252 case Node::CUDAFLOW_WORK: {
253 auto& cfg = nstd::get<Node::cudaFlowWork>(node->_handle).graph;
255 os <<
"subgraph cluster_p" << node <<
" {\nlabel=\"cudaFlow: ";
256 if(node->_name.empty()) os <<
'p' << node;
257 else os << node->_name;
259 os <<
"\";\n" <<
"color=\"purple\"\n";
261 for(
const auto& v : cfg._nodes) {
263 os <<
'p' << v.get() <<
"[label=\"";
264 if(v->_name.empty()) {
265 os <<
'p' << v.get() <<
"\"";
268 os << v->_name <<
"\"";
271 switch(v->_handle.index()) {
279 case cudaNode::KERNEL:
280 os <<
" style=\"filled\"" 281 <<
" color=\"white\" fillcolor=\"black\"" 282 <<
" fontcolor=\"white\"" 283 <<
" shape=\"box3d\"";
291 for(
const auto s : v->_successors) {
292 os <<
'p' << v.get() <<
" -> " <<
'p' << s <<
";\n";
295 if(v->_successors.size() == 0) {
296 os <<
'p' << v.get() <<
" -> p" << node <<
";\n";
312 inline void Taskflow::_dump(
316 for(
const auto& n : graph._nodes) {
319 if(n->_handle.index() != Node::MODULE_WORK) {
320 _dump(os, n, dumper);
325 auto module = nstd::get<Node::ModuleWork>(n->_handle).module;
327 os <<
'p' << n <<
"[shape=box3d, color=blue, label=\"";
328 if(n->_name.empty()) os << n;
330 os <<
" [Taskflow: ";
331 if(module->_name.empty()) os <<
'p' << module;
332 else os << module->_name;
335 if(dumper.visited.find(module) == dumper.visited.end()) {
336 dumper.visited.insert(module);
337 dumper.stack.push(module);
340 for(
const auto s : n->_successors) {
341 os <<
'p' << n <<
"->" <<
'p' << s <<
";\n";
350 using Framework = Taskflow;
Taskflow()
constructs a taskflow
Definition: taskflow.hpp:113
void for_each_task(V &&visitor) const
applies an visitor callable to each task in the taskflow
Definition: taskflow.hpp:148
const std::string & name() const
queries the name of the taskflow
Definition: taskflow.hpp:142
void clear()
clears the associated task dependency graph
Definition: taskflow.hpp:122
main entry to create a task dependency graph
Definition: taskflow.hpp:18
bool empty() const
queries the emptiness of the taskflow
Definition: taskflow.hpp:132
std::string dump() const
dumps the taskflow in DOT format to a std::string
Definition: taskflow.hpp:155
building methods of a task dependency graph
Definition: flow_builder.hpp:13
handle to a node in a task dependency graph
Definition: task.hpp:113
execution interface for running a taskflow graph
Definition: executor.hpp:43
size_t num_tasks() const
queries the number of tasks in the taskflow
Definition: taskflow.hpp:127
virtual ~Taskflow()
destroy the taskflow (virtual call)
Definition: taskflow.hpp:117