<ahref="#ModuleAlgorithmInclude">Include the Header</a>
</li>
<liclass="level1">
<ahref="#WhatIsAModuleTask">What is a Module Task</a>
</li>
<liclass="level1">
<ahref="#CreateAModuleTaskOverACustomGraph">Create a Module Task over a Custom Graph</a>
</li>
</ul>
</div>
<divclass="textblock"><p>Taskflow provides template methods that let users create reusable building blocks called <em>modules</em>. Users can connect modules together to build more complex parallel algorithms.</p>
<p>You need to include the header file, <code><aclass="el" href="module_8hpp_source.html">taskflow/algorithm/module.hpp</a></code>, for creating a module task over a schedulable graph target.</p>
</div><!-- fragment --><h1><aclass="anchor" id="WhatIsAModuleTask"></a>
What is a Module Task</h1>
<p>Similar to <aclass="el" href="ComposableTasking.html">Composable Tasking</a>, but in a more general setting, the template function <aclass="el" href="namespacetf.html#a07b2225aa9794364b4c704ce0f449974" title="creates a module task using the given graph">tf::make_module_task</a> allows you to create a task over a Taskflow graph that can be executed by an executor. This provides a flexible mechanism to encapsulate and reuse complex task logic within your Taskflow applications. The following example demonstrates how to create and launch multiple Taskflow graphs in parallel using asynchronous tasking:</p>
<divclass="ttc" id="aclasstf_1_1Executor_html"><divclass="ttname"><ahref="classtf_1_1Executor.html">tf::Executor</a></div><divclass="ttdoc">class to create an executor</div><divclass="ttdef"><b>Definition</b> executor.hpp:62</div></div>
<divclass="ttc" id="aclasstf_1_1Executor_html_ab9aa252f70e9a40020a1e5a89d485b85"><divclass="ttname"><ahref="classtf_1_1Executor.html#ab9aa252f70e9a40020a1e5a89d485b85">tf::Executor::wait_for_all</a></div><divclass="ttdeci">void wait_for_all()</div><divclass="ttdoc">waits for all tasks to complete</div></div>
<divclass="ttc" id="aclasstf_1_1Executor_html_af960048056f7c6b5bc71f4f526f05df7"><divclass="ttname"><ahref="classtf_1_1Executor.html#af960048056f7c6b5bc71f4f526f05df7">tf::Executor::async</a></div><divclass="ttdeci">auto async(P &&params, F &&func)</div><divclass="ttdoc">creates a parameterized asynchronous task to run the given function</div></div>
<divclass="ttc" id="aclasstf_1_1FlowBuilder_html_a4d52a7fe2814b264846a2085e931652c"><divclass="ttname"><ahref="classtf_1_1FlowBuilder.html#a4d52a7fe2814b264846a2085e931652c">tf::FlowBuilder::emplace</a></div><divclass="ttdeci">Task emplace(C &&callable)</div><divclass="ttdoc">creates a static task</div><divclass="ttdef"><b>Definition</b> flow_builder.hpp:1781</div></div>
<divclass="ttc" id="aclasstf_1_1Taskflow_html"><divclass="ttname"><ahref="classtf_1_1Taskflow.html">tf::Taskflow</a></div><divclass="ttdoc">class to create a taskflow object</div><divclass="ttdef"><b>Definition</b> taskflow.hpp:64</div></div>
<divclass="ttc" id="anamespacetf_html_a07b2225aa9794364b4c704ce0f449974"><divclass="ttname"><ahref="namespacetf.html#a07b2225aa9794364b4c704ce0f449974">tf::make_module_task</a></div><divclass="ttdeci">auto make_module_task(T &target)</div><divclass="ttdoc">creates a module task using the given graph</div><divclass="ttdef"><b>Definition</b> module.hpp:74</div></div>
</div><!-- fragment --><divclass="dotgraph">
<iframescrolling="no" frameborder="0" src="dot_module_task_1.svg" width="371" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe></div>
<p>Since the four taskflows are launched asynchronously without any dependencies between them, we can observe any order of the output message:</p>
<divclass="fragment"><divclass="line"># one possible output</div>
<divclass="line">Taskflow B</div>
<divclass="line">Taskflow C</div>
<divclass="line">Taskflow A</div>
<divclass="line">Taskflow D</div>
<divclass="line"></div>
<divclass="line"># another possible output</div>
<divclass="line">Taskflow D</div>
<divclass="line">Taskflow A</div>
<divclass="line">Taskflow B</div>
<divclass="line">Taskflow C</div>
</div><!-- fragment --><p>If you need to enforce dependencies among these four taskflows, you can use dependent-async tasks. The example below launches the four taskflows one by one in sequential:</p>
<divclass="ttc" id="aclasstf_1_1Executor_html_a0015352aa28b50251a970354a0c4a159"><divclass="ttname"><ahref="classtf_1_1Executor.html#a0015352aa28b50251a970354a0c4a159">tf::Executor::dependent_async</a></div><divclass="ttdeci">auto dependent_async(F &&func, Tasks &&... tasks)</div><divclass="ttdoc">runs the given function asynchronously when the given predecessors finish</div></div>
<divclass="ttc" id="aclasstf_1_1Executor_html_a09e04696a50841c118472b2c2a7ff6f5"><divclass="ttname"><ahref="classtf_1_1Executor.html#a09e04696a50841c118472b2c2a7ff6f5">tf::Executor::silent_dependent_async</a></div><divclass="ttdeci">tf::AsyncTask silent_dependent_async(F &&func, Tasks &&... tasks)</div><divclass="ttdoc">runs the given function asynchronously when the given predecessors finish</div></div>
</div><!-- fragment --><divclass="dotgraph">
<iframescrolling="no" frameborder="0" src="dot_module_task_2.svg" width="443" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe></div>
<divclass="fragment"><divclass="line"># dependent-async tasks enforce a sequential execution of the four taskflows</div>
<divclass="line">Taskflow A</div>
<divclass="line">Taskflow B</div>
<divclass="line">Taskflow C</div>
<divclass="line">Taskflow D</div>
</div><!-- fragment --><p>The module task maker, <aclass="el" href="namespacetf.html#a07b2225aa9794364b4c704ce0f449974" title="creates a module task using the given graph">tf::make_module_task</a>, operates similarly to <aclass="el" href="classtf_1_1FlowBuilder.html#ac6f22228d4c2ea2e643c4b0d42c0e92a" title="creates a module task for the target object">tf::Taskflow::composed_of</a>, but provides a more general interface that can be used beyond Taskflow. Specifically, the following two approaches achieve equivalent functionality:</p>
<divclass="fragment"><divclass="line"><spanclass="comment">// approach 1: composition using composed_of</span></div>
<divclass="ttc" id="aclasstf_1_1Task_html"><divclass="ttname"><ahref="classtf_1_1Task.html">tf::Task</a></div><divclass="ttdoc">class to create a task handle over a taskflow node</div><divclass="ttdef"><b>Definition</b> task.hpp:569</div></div>
<divclass="ttc" id="aclasstf_1_1Task_html_ab38be520fe700cb4ca1f312308a95585"><divclass="ttname"><ahref="classtf_1_1Task.html#ab38be520fe700cb4ca1f312308a95585">tf::Task::composed_of</a></div><divclass="ttdeci">Task & composed_of(T &object)</div><divclass="ttdoc">creates a module task from a taskflow</div><divclass="ttdef"><b>Definition</b> task.hpp:1337</div></div>
</div><!-- fragment --><dlclass="section note"><dt>Note</dt><dd>Similar to <aclass="el" href="classtf_1_1FlowBuilder.html#ac6f22228d4c2ea2e643c4b0d42c0e92a" title="creates a module task for the target object">tf::Taskflow::composed_of</a>, <aclass="el" href="namespacetf.html#a07b2225aa9794364b4c704ce0f449974" title="creates a module task using the given graph">tf::make_module_task</a> does not assume ownership of the provided taskflow but a soft reference. You are responsible for ensuring that the encapsulated taskflow remains valid throughout its execution.</dd></dl>
<p>In addition to encapsulate taskflow graphs, you can create a module task to schedule a custom graph target. A schedulable target (of type <code>T</code>) must define the method <code>T::graph()</code> that returns a reference to the <aclass="el" href="classtf_1_1Graph.html" title="class to create a graph object">tf::Graph</a> object managed by <code>T</code>. The following example defines a custom graph that can be scheduled through making module tasks:</p>
<divclass="ttc" id="aclasstf_1_1FlowBuilder_html"><divclass="ttname"><ahref="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></div><divclass="ttdoc">class to build a task dependency graph</div><divclass="ttdef"><b>Definition</b> flow_builder.hpp:114</div></div>
<divclass="ttc" id="aclasstf_1_1Graph_html"><divclass="ttname"><ahref="classtf_1_1Graph.html">tf::Graph</a></div><divclass="ttdoc">class to create a graph object</div><divclass="ttdef"><b>Definition</b> graph.hpp:47</div></div>
</div><!-- fragment --><dlclass="section note"><dt>Note</dt><dd>Users are responsible for ensuring the given custom graph remains valid throughout its execution. The executor does not assume ownership of the custom graph. </dd></dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.13.1-->
<!-- start footer part -->
<divid="nav-path" class="navpath"><!-- id is needed for treeview function! -->