<!-- iframe showing the search results (closed by default) -->
<divid="MSearchResultsWindow">
<iframesrc="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<divclass="header">
<divclass="headertitle">
<divclass="title">C1: Static Tasking </div></div>
</div><!--header-->
<divclass="contents">
<divclass="textblock"><p>This chapter demonstrates how to create a static task dependency graph. Static tasking captures the static parallel structure of a decomposition and is defined only by the program itself. It has a flat task hierarchy and cannot spawn new tasks from a running dependency graph.</p>
<p>A task in Cpp-Taskflow is a <em>callable</em> object for which the operation <ahref="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a> is applicable. It can be either a functor, a lambda expression, a bind expression, or a class objects with <code>operator()</code> overloaded. All tasks are created from <aclass="el" href="classtf_1_1Taskflow.html" title="the class to create a task dependency graph ">tf::Taskflow</a>, the class that manages a task dependency graph. Cpp-Taskflow provides two methods, <aclass="el" href="classtf_1_1FlowBuilder.html#acab0b4ac82260f47fdb36a3244ee3aaf" title="creates an empty task ">tf::Taskflow::placeholder</a> and <aclass="el" href="classtf_1_1FlowBuilder.html#a4d52a7fe2814b264846a2085e931652c" title="creates a task from a given callable object ">tf::Taskflow::emplace</a> to create a task.</p>
<li>Line 1 creates a taskflow object, or a <em>graph</em></li>
<li>Line 2 creates a placeholder task without work (i.e., callable) </li>
<li>Line 3 creates a task from a given callable object and returns a task handle </li>
<li>Line 5-9 creates three tasks in one call using C++ structured binding coupled with <aclass="elRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/utility/tuple.html">std::tuple</a></li>
</ul>
<p>Each time you create a task, the taskflow object creates a node in the task graph and returns a task handle of type <aclass="el" href="classtf_1_1Task.html" title="task handle to a node in a task dependency graph ">tf::Task</a>. A task handle is a lightweight object that wraps up a particular node in a graph and provides a set of methods for you to assign different attributes to the task such as adding dependencies, naming, and assigning a new work.</p>
<li>Line 5-6 assigns a name and a work to task A, and add a precedence link to task B </li>
<li>Line 7 adds a dependency link from A to B </li>
<li>Line 9-14 dumps the task attributes</li>
</ul>
<p>Cpp-Taskflow uses the general-purpose polymorphic function wrapper <aclass="elRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a> to store and invoke a callable in a task. You need to follow its contract to create a task.</p>
<p>You can dump a taskflow to a DOT format and visualize the graph using free online tools such as <ahref="https://dreampuf.github.io/GraphvizOnline/">GraphvizOnline</a> and <ahref="http://www.webgraphviz.com/">WebGraphviz</a>.</p>
<p>This example demonstrates how to modify a task's attributes using methods defined in the task handler.</p>
<divclass="fragment"><divclass="line"> 1: #include <taskflow/taskflow.hpp></div><divclass="line"> 2:</div><divclass="line"> 3: <spanclass="keywordtype">int</span> main() {</div><divclass="line"> 4:</div><divclass="line"> 5: <aclass="code" href="classtf_1_1Taskflow.html">tf::Taskflow</a> taskflow;</div><divclass="line"> 6:</div><divclass="line"> 7: <aclass="codeRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector<tf::Task></a> tasks = { </div><divclass="line"> 8: taskflow.<aclass="code" href="classtf_1_1FlowBuilder.html#acab0b4ac82260f47fdb36a3244ee3aaf">placeholder</a>(), <spanclass="comment">// create a task with no work</span></div><divclass="line"> 9: taskflow.<aclass="code" href="classtf_1_1FlowBuilder.html#acab0b4ac82260f47fdb36a3244ee3aaf">placeholder</a>() <spanclass="comment">// create a task with no work</span></div><divclass="line">10: };</div><divclass="line">11:</div><divclass="line">12: tasks[0].name(<spanclass="stringliteral">"This is Task 0"</span>);</div><divclass="line">13: tasks[1].name(<spanclass="stringliteral">"This is Task 1"</span>);</div><divclass="line">14: tasks[0].precede(tasks[1]);</div><divclass="line">15:</div><divclass="line">16: <spanclass="keywordflow">for</span>(<spanclass="keyword">auto</span> task : tasks) { <spanclass="comment">// print out each task's attributes</span></div><divclass="line">17: <aclass="codeRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << task.name() << <spanclass="stringliteral">": "</span></div><divclass="line">18: << <spanclass="stringliteral">"num_dependents="</span> << task.num_dependents() << <spanclass="stringliteral">", "</span></div><divclass="line">19: << <spanclass="stringliteral">"num_successors="</span> << task.num_successors() << <spanclass="charliteral">'\n'</span>;</div><divclass="line">20: }</div><divclass="line">21:</div><divclass="line">22: taskflow.<aclass="code" href="classtf_1_1Taskflow.html#ac433018262e44b12c4cc9f0c4748d758">dump</a>(<aclass="codeRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a>); <spanclass="comment">// dump the taskflow graph</span></div><divclass="line">23:</div><divclass="line">24: tasks[0].work([](){ <aclass="codeRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <spanclass="stringliteral">"got a new work!\n"</span>; });</div><divclass="line">25: tasks[1].work([](){ <aclass="codeRef" doxygen="/home/tsung-wei/Code/cpp-taskflow/doxygen/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <spanclass="stringliteral">"got a new work!\n"</span>; });</div><divclass="line">26:</div><divclass="line">27: <spanclass="keywordflow">return</span> 0;</div><divclass="line">28: }</div></div><!-- fragment --><p>The output of this program looks like the following:</p>
<divclass="fragment"><divclass="line">This is Task 0: num_dependents=0, num_successors=1</div><divclass="line">This is Task 1: num_dependents=1, num_successors=0</div><divclass="line">digraph Taskflow {</div><divclass="line">"This is Task 1";</div><divclass="line">"This is Task 0";</div><divclass="line">"This is Task 0" -> "This is Task 1";</div><divclass="line">}</div></div><!-- fragment --><p>Debrief: </p><ul>
<li>Line 5 creates a taskflow object </li>
<li>Line 7-10 creates two placeholder tasks with no works and stores the corresponding task handles in a vector </li>
<li>Line 12-13 names the two tasks with human-readable strings </li>
<li>Line 14 adds a dependency link from the first task to the second task </li>
<li>Line 16-20 prints out the name of each task, the number of dependents, and the number of successors </li>
<li>Line 22 dumps the task dependency graph to a <ahref="https://dreampuf.github.io/GraphvizOnline/">GraphViz Online</a> format (dot) </li>
<li>Line 24-25 assigns a new target to each task</li>
</ul>
<p>You can change the name and work of a task at anytime before running the graph. The later assignment overwrites the previous values.</p>
<h1><aclass="anchor" id="C1_LifetimeOfATask"></a>
Lifetime of A Task</h1>
<p>A task lives with its graph and belongs to only a graph at a time, and is not destroyed until the graph gets cleaned up. The lifetime of a task refers to the user-given callable object, including captured values. As long as the graph is alive, all the associated tasks exist. It is your responsibility to keep tasks and graph alive during their execution. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<divid="nav-path" class="navpath"><!-- id is needed for treeview function! -->