tf::Taskflow tf::FlowBuilder taskflow/core/taskflow.hpp tf::Taskflow::Dumper class friend class Topology Topology Topology class friend class Executor Executor Executor class friend class FlowBuilder FlowBuilder FlowBuilder std::mutex std::mutex tf::Taskflow::_mutex _mutex std::string std::string tf::Taskflow::_name _name Graph Graph tf::Taskflow::_graph _graph std::queue< std::shared_ptr< Topology > > std::queue<std::shared_ptr<Topology> > tf::Taskflow::_topologies _topologies std::optional< std::list< Taskflow >::iterator > std::optional<std::list<Taskflow>::iterator> tf::Taskflow::_satellite _satellite tf::Taskflow::Taskflow (const std::string &name) Taskflow const std::string & name constructs a taskflow with the given name tf::Taskflowtaskflow("MyTaskflow"); std::cout<<taskflow.name();//"MyTaskflow" tf::Taskflow::Taskflow () Taskflow constructs a taskflow tf::Taskflow::Taskflow (Taskflow &&rhs) Taskflow Taskflow && rhs constructs a taskflow from a moved taskflow Constructing a taskflow taskflow1 from a moved taskflow taskflow2 will migrate the graph of taskflow2 to taskflow1. After the move, taskflow2 will become empty. tf::Taskflowtaskflow1(std::move(taskflow2)); assert(taskflow2.empty()); Notice that taskflow2 should not be running in an executor during the move operation, or the behavior is undefined. Taskflow & Taskflow & tf::Taskflow::operator= (Taskflow &&rhs) operator= Taskflow && rhs move assignment operator Moving a taskflow taskflow2 to another taskflow taskflow1 will destroy the existing graph of taskflow1 and assign it the graph of taskflow2. After the move, taskflow2 will become empty. taskflow1=std::move(taskflow2); assert(taskflow2.empty()); Notice that both taskflow1 and taskflow2 should not be running in an executor during the move operation, or the behavior is undefined. tf::Taskflow::~Taskflow ()=default ~Taskflow default destructor When the destructor is called, all tasks and their associated data (e.g., captured data) will be destroyed. It is your responsibility to ensure all submitted execution of this taskflow have completed before destroying it. For instance, the following code results in undefined behavior since the executor may still be running the taskflow while it is destroyed after the block. { tf::Taskflowtaskflow; executor.run(taskflow); } To fix the problem, we must wait for the execution to complete before destroying the taskflow. { tf::Taskflowtaskflow; executor.run(taskflow).wait(); } void void tf::Taskflow::dump (std::ostream &ostream) const dump std::ostream & ostream dumps the taskflow to a DOT format through a std::ostream target taskflow.dump(std::cout);//dumpthegraphtothestandardoutput std::ofstreamofs("output.dot"); taskflow.dump(ofs);//dumpthegraphtothefileoutput.dot For dynamically spawned tasks, such as module tasks, subflow tasks, and GPU tasks, you need to run the taskflow first before you can dump the entire graph. tf::Taskparent=taskflow.emplace([](tf::Subflowsf){ sf.emplace([](){std::cout<<"child\n";}); }); taskflow.dump(std::cout);//thisdumpsonlytheparenttasks executor.run(taskflow).wait(); taskflow.dump(std::cout);//thisdumpsbothparentandchildtasks std::string std::string tf::Taskflow::dump () const dump dumps the taskflow to a std::string of DOT format This method is similar to tf::Taskflow::dump(std::ostream& ostream), but returning a string of the graph in DOT format. size_t size_t tf::Taskflow::num_tasks () const num_tasks queries the number of tasks bool bool tf::Taskflow::empty () const empty queries the emptiness of the taskflow An empty taskflow has no tasks. That is the return of tf::Taskflow::num_tasks is zero. void void tf::Taskflow::name (const std::string &) name const std::string & name assigns a name to the taskflow taskflow.name("assignanothername"); const std::string & const std::string & tf::Taskflow::name () const name queries the name of the taskflow std::cout<<"mynameis:"<<taskflow.name(); void void tf::Taskflow::clear () clear clears the associated task dependency graph When you clear a taskflow, all tasks and their associated data (e.g., captured data in task callables) will be destroyed. The behavior of clearing a running taskflow is undefined. typename V void void tf::Taskflow::for_each_task (V &&visitor) const for_each_task V && visitor applies a visitor to each task in the taskflow A visitor is a callable that takes an argument of type tf::Task and returns nothing. The following example iterates each task in a taskflow and prints its name: taskflow.for_each_task([](tf::Tasktask){ std::cout<<task.name()<<'\n'; }); void void tf::Taskflow::remove_dependency (Task from, Task to) remove_dependency Task from Task to removes dependencies that go from task from to task to from from task (dependent) to to task (successor) tf::Taskflowtaskflow; autoa=taskflow.placeholder().name("a"); autob=taskflow.placeholder().name("b"); autoc=taskflow.placeholder().name("c"); autod=taskflow.placeholder().name("d"); a.precede(b,c,d); assert(a.num_successors()==3); assert(b.num_dependents()==1); assert(c.num_dependents()==1); assert(d.num_dependents()==1); taskflow.remove_dependency(a,b); assert(a.num_successors()==2); assert(b.num_dependents()==0); Graph & Graph & tf::Taskflow::graph () graph returns a reference to the underlying graph object A graph object (of type tf::Graph) is the ultimate storage for the task dependency graph and should only be used as an opaque data structure to interact with the executor (e.g., composition). void void tf::Taskflow::_dump (std::ostream &, const Graph *) const _dump std::ostream & os const Graph * top void void tf::Taskflow::_dump (std::ostream &, const Node *, Dumper &) const _dump std::ostream & os const Node * node Dumper & dumper void void tf::Taskflow::_dump (std::ostream &, const Graph *, Dumper &) const _dump std::ostream & os const Graph * graph Dumper & dumper class to create a taskflow object A taskflow manages a task dependency graph where each task represents a callable object (e.g., lambda, std::function) and an edge represents a dependency between two tasks. A task is one of the following types: static task : the callable constructible from std::function<void()> subflow task : the callable constructible from std::function<void(tf::Subflow&)> condition task : the callable constructible from std::function<int()> multi-condition task: the callable constructible from std::function<tf::SmallVector<int>()> module task : the task constructed from tf::Taskflow::composed_of std::function<void(tf::Runtime&)> Each task is a basic computation unit and is run by one worker thread from an executor. The following example creates a simple taskflow graph of four static tasks, A, B, C, and D, where A runs before B and C and D runs after B and C. tf::Executorexecutor; tf::Taskflowtaskflow("simple"); tf::TaskA=taskflow.emplace([](){std::cout<<"TaskA\n";}); tf::TaskB=taskflow.emplace([](){std::cout<<"TaskB\n";}); tf::TaskC=taskflow.emplace([](){std::cout<<"TaskC\n";}); tf::TaskD=taskflow.emplace([](){std::cout<<"TaskD\n";}); A.precede(B,C);//ArunsbeforeBandC D.succeed(B,C);//DrunsafterBandC executor.run(taskflow).wait(); The taskflow object itself is NOT thread-safe. You should not modifying the graph while it is running, such as adding new tasks, adding new dependencies, and moving the taskflow to another. To minimize the overhead of task creation, our runtime leverages a global object pool to recycle tasks in a thread-safe manner. Please refer to Cookbook to learn more about each task type and how to submit a taskflow to an executor. _graph tf::Taskflow_dump tf::Taskflow_dump tf::Taskflow_dump tf::Taskflow_graph tf::Taskflow_mutex tf::Taskflow_name tf::Taskflow_satellite tf::Taskflow_topologies tf::Taskflowclear tf::Taskflowcomposed_of tf::Taskflowdump tf::Taskflowdump tf::Taskflowemplace tf::Taskflowemplace tf::Taskflowemplace tf::Taskflowemplace tf::Taskflowemplace tf::Taskflowempty tf::Taskflowerase tf::Taskflowexclusive_scan tf::TaskflowExecutor tf::Taskflowfind_if tf::Taskflowfind_if_not tf::TaskflowFlowBuilder tf::TaskflowFlowBuilder tf::Taskflowfor_each tf::Taskflowfor_each_index tf::Taskflowfor_each_task tf::Taskflowgraph tf::Taskflowinclusive_scan tf::Taskflowinclusive_scan tf::Taskflowlinearize tf::Taskflowlinearize tf::Taskflowmax_element tf::Taskflowmin_element tf::Taskflowname tf::Taskflowname tf::Taskflownum_tasks tf::Taskflowoperator= tf::Taskflowplaceholder tf::Taskflowreduce tf::Taskflowremove_dependency tf::Taskflowsort tf::Taskflowsort tf::TaskflowTaskflow tf::TaskflowTaskflow tf::TaskflowTaskflow tf::TaskflowTopology tf::Taskflowtransform tf::Taskflowtransform tf::Taskflowtransform_exclusive_scan tf::Taskflowtransform_inclusive_scan tf::Taskflowtransform_inclusive_scan tf::Taskflowtransform_reduce tf::Taskflowtransform_reduce tf::Taskflow~Taskflow