Skip to content

Commit 76209c1

Browse files
updated flowbuilder
1 parent f66510a commit 76209c1

22 files changed

+111
-262
lines changed

CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,6 @@ target_link_libraries(nested_subflow ${PROJECT_NAME} Threads::Threads)
122122
add_executable(debug ${TF_EXAMPLE_DIR}/debug.cpp)
123123
target_link_libraries(debug ${PROJECT_NAME} Threads::Threads)
124124

125-
add_executable(emplace ${TF_EXAMPLE_DIR}/emplace.cpp)
126-
target_link_libraries(emplace ${PROJECT_NAME} Threads::Threads)
127-
128125
add_executable(reduce ${TF_EXAMPLE_DIR}/reduce.cpp)
129126
target_link_libraries(reduce ${PROJECT_NAME} Threads::Threads)
130127

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ The folder `example/` contains several examples and is a great place to learn to
770770
| [threadpool_cxx14.cpp](./example/threadpool_cxx14.cpp)| shows use of the C++14-compatible threadpool implementation, which may be used when you have no inter-task (taskflow) dependencies to express |
771771
| [taskflow.cpp](./example/taskflow.cpp)| benchmarks taskflow on different task dependency graphs |
772772
| [executor.cpp](./example/executor.cpp)| shows how to create multiple taskflow objects sharing one executor to avoid the thread over-subscription problem |
773+
| [framework.cpp](./example/framework.cpp)| shows the usage of framework to create reusable task dependency graphs |
773774

774775
# Get Involved
775776

docs/basic__taskflow_8hpp_source.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
<div class="ttc" id="classtf_1_1BasicTaskflow_html"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html">tf::BasicTaskflow</a></div><div class="ttdoc">The base class to derive a taskflow class. </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:38</div></div>
100100
<div class="ttc" id="shared_ptr_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/memory/shared_ptr.html">std::shared_ptr&lt; Executor &gt;</a></div></div>
101101
<div class="ttc" id="classtf_1_1BasicTaskflow_html_abe76e5288016861aaf1dafc0218d3084"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#abe76e5288016861aaf1dafc0218d3084">tf::BasicTaskflow::share_executor</a></div><div class="ttdeci">std::shared_ptr&lt; Executor &gt; share_executor()</div><div class="ttdoc">shares ownership of the executor associated with this taskflow object </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:611</div></div>
102-
<div class="ttc" id="classtf_1_1SubflowBuilder_html_a39793fbfee4d3fe01541cfd04bf1a5c7"><div class="ttname"><a href="classtf_1_1SubflowBuilder.html#a39793fbfee4d3fe01541cfd04bf1a5c7">tf::SubflowBuilder::detached</a></div><div class="ttdeci">bool detached() const</div><div class="ttdoc">queries if the subflow will be detached from its parent task </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:762</div></div>
102+
<div class="ttc" id="classtf_1_1SubflowBuilder_html_a39793fbfee4d3fe01541cfd04bf1a5c7"><div class="ttname"><a href="classtf_1_1SubflowBuilder.html#a39793fbfee4d3fe01541cfd04bf1a5c7">tf::SubflowBuilder::detached</a></div><div class="ttdeci">bool detached() const</div><div class="ttdoc">queries if the subflow will be detached from its parent task </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:804</div></div>
103103
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a18341302575dcb719e455d84a738273f"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a18341302575dcb719e455d84a738273f">tf::BasicTaskflow::num_nodes</a></div><div class="ttdeci">size_t num_nodes() const</div><div class="ttdoc">queries the number of nodes in the present task dependency graph </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:593</div></div>
104104
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a848e425f67b49a8a7ac21f6b791999c5"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">tf::BasicTaskflow::dispatch</a></div><div class="ttdeci">std::shared_future&lt; void &gt; dispatch()</div><div class="ttdoc">dispatches the present graph to threads and returns immediately </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:644</div></div>
105105
<div class="ttc" id="namespacetf_html"><div class="ttname"><a href="namespacetf.html">tf</a></div><div class="ttdef"><b>Definition:</b> taskflow.hpp:6</div></div>
@@ -110,7 +110,7 @@
110110
<div class="ttc" id="basic_string_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/string/basic_string.html">std::string</a></div></div>
111111
<div class="ttc" id="shared_future_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/shared_future.html">std::shared_future</a></div></div>
112112
<div class="ttc" id="classtf_1_1Framework_html"><div class="ttname"><a href="classtf_1_1Framework.html">tf::Framework</a></div><div class="ttdoc">A reusable task dependency graph. </div><div class="ttdef"><b>Definition:</b> framework.hpp:17</div></div>
113-
<div class="ttc" id="classtf_1_1SubflowBuilder_html"><div class="ttname"><a href="classtf_1_1SubflowBuilder.html">tf::SubflowBuilder</a></div><div class="ttdoc">The building blocks of dynamic tasking. </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:713</div></div>
113+
<div class="ttc" id="classtf_1_1SubflowBuilder_html"><div class="ttname"><a href="classtf_1_1SubflowBuilder.html">tf::SubflowBuilder</a></div><div class="ttdoc">The building blocks of dynamic tasking. </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:755</div></div>
114114
<div class="ttc" id="basic_ostringstream_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/io/basic_ostringstream.html">std::ostringstream</a></div></div>
115115
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a7e97ed52d9d0470d2751f32748adb253"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a7e97ed52d9d0470d2751f32748adb253">tf::BasicTaskflow::num_topologies</a></div><div class="ttdeci">size_t num_topologies() const</div><div class="ttdoc">queries the number of existing topologies </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:605</div></div>
116116
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a8f0ce2026118e97b83cbd727ed0932af"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af">tf::BasicTaskflow::wait_for_topologies</a></div><div class="ttdeci">void wait_for_topologies()</div><div class="ttdoc">blocks until all running topologies complete and then cleans up all associated storages ...</div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:686</div></div>

docs/chapter3.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
<div class="textblock"><p>Running a for-loop in parallel is the most fundamental building block in parallel programming. In this chapter, we are going to demonstrate how to use Cpp-Taskflow to create a task dependency graph of parallel for-loop.</p>
9999
<h1><a class="anchor" id="RangeBasedForLoop"></a>
100100
Range-based For-loop</h1>
101-
<p>Cpp-Taskflow has a STL-style method <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="constructs a task dependency graph of range-based parallel_for ">tf::Taskflow::parallel_for(I beg, I end, C&amp;&amp; callable, size_t chunk)</a> that takes a range of items and applies a callable to each of the item in parallel. The method constructs a task dependency graph representing this workload and returns a task pair as two synchronization points to this task graph.</p>
101+
<p>Cpp-Taskflow has a STL-style method <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="creates a task from a given callable object without access to the result ">tf::Taskflow::parallel_for(I beg, I end, C&amp;&amp; callable, size_t chunk)</a> that takes a range of items and applies a callable to each of the item in parallel. The method constructs a task dependency graph representing this workload and returns a task pair as two synchronization points to this task graph.</p>
102102
<div class="fragment"><div class="line"> 1: <a class="code" href="classtf_1_1BasicTaskflow.html">tf::Taskflow</a> taskflow;</div><div class="line"> 2:</div><div class="line"> 3: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;int&gt;</a> items {1, 2, 3, 4, 5, 6, 7, 8};</div><div class="line"> 4:</div><div class="line"> 5: <span class="keyword">auto</span> [S, T] = taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(items.begin(), items.end(), [] (<span class="keywordtype">int</span> item) {</div><div class="line"> 6: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/thread/get_id.html">std::this_thread::get_id</a>() &lt;&lt; <span class="stringliteral">&quot; runs &quot;</span> &lt;&lt; item &lt;&lt; <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/manip/endl.html">std::endl</a>;</div><div class="line"> 7: });</div><div class="line"> 8:</div><div class="line"> 9: S.work([] () { <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; <span class="stringliteral">&quot;S\n&quot;</span>; }).name(<span class="stringliteral">&quot;S&quot;</span>);</div><div class="line">10: T.work([] () { <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; <span class="stringliteral">&quot;T\n&quot;</span>; }).name(<span class="stringliteral">&quot;T&quot;</span>);</div><div class="line">11:</div><div class="line">12: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#adac448e1cc44307856b3116d7ed5490f">dump</a>();</div><div class="line">13:</div><div class="line">14: taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>();</div></div><!-- fragment --><p>The above code generates the following task dependency graph. The label 0x56* represents an internal task node to execute the callable object. By default (<code>chunk=0</code>), Cpp-Taskflow evenly partitions and distributes the workload to all threads. In our example of eight tasks and four workers, each internal node is responsible for two items.</p>
103103
<div class="image">
104104
<img src="parallel_for1.png" alt="parallel_for1.png" width="60%"/>
@@ -131,7 +131,7 @@ <h1><a class="anchor" id="ConstructTheGraphExplicitly"></a>
131131
<div class="fragment"><div class="line">1: taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(0, 10, 2, [] (<span class="keywordtype">int</span> i) {</div><div class="line">2: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; <span class="stringliteral">&quot;parallel on &quot;</span> &lt;&lt; i &lt;&lt; <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/manip/endl.html">std::endl</a>;</div><div class="line">3: }, 2);</div><div class="line">4: <span class="comment">// print 0, 2, 4, 6, 8 (three groups {0, 2}, {4, 6}, {8})</span></div></div><!-- fragment --><p>By default, Cpp-Taskflow performs even partition across the number of available threads if no group size is given.</p>
132132
<h1><a class="anchor" id="Chapter3Example1"></a>
133133
Example 1: Parallel Map</h1>
134-
<p>This example demonstrates how to use <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="constructs a task dependency graph of range-based parallel_for ">tf::Taskflow::parallel_for</a> to create a parallel map pattern. The map operator modifies each item in the container to one if it is an odd number, or zero if it is an even number.</p>
134+
<p>This example demonstrates how to use <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="creates a task from a given callable object without access to the result ">tf::Taskflow::parallel_for</a> to create a parallel map pattern. The map operator modifies each item in the container to one if it is an odd number, or zero if it is an even number.</p>
135135
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;taskflow/taskflow.hpp&gt;</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line"></div><div class="line"> <a class="code" href="classtf_1_1BasicTaskflow.html">tf::Taskflow</a> taskflow;</div><div class="line"></div><div class="line"> <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;int&gt;</a> items{1, 2, 3, 4, 5, 6, 7, 8};</div><div class="line"></div><div class="line"> taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(items.begin(), items.end(), [] (<span class="keywordtype">int</span>&amp; item) {</div><div class="line"> item = (item &amp; 1) ? 1 : 0;</div><div class="line"> });</div><div class="line"></div><div class="line"> taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">for</span>(<span class="keyword">auto</span> item : items) {</div><div class="line"> <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> &lt;&lt; item &lt;&lt; <span class="stringliteral">&quot; &quot;</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>The program outputs the following:</p>
136136
<div class="fragment"><div class="line">1 0 1 0 1 0 1 0 </div></div><!-- fragment --><h1><a class="anchor" id="Chapter3Example2"></a>
137137
Example 2: Pipeline a Parallel For-loop</h1>

docs/classtf_1_1BasicTaskflow-members.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@
136136
<tr><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html#abe76e5288016861aaf1dafc0218d3084">share_executor</a>()</td><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html">tf::BasicTaskflow&lt; E &gt;</a></td><td class="entry"></td></tr>
137137
<tr class="even"><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html#a0126001a2bd8603af4827049578629cb">silent_dispatch</a>()</td><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html">tf::BasicTaskflow&lt; E &gt;</a></td><td class="entry"></td></tr>
138138
<tr><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html#a689a804c4d9f2afe06d558b4ef7e7d29">silent_dispatch</a>(C &amp;&amp;callable)</td><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html">tf::BasicTaskflow&lt; E &gt;</a></td><td class="entry"></td></tr>
139-
<tr class="even"><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html#a7285613836c840e22b8511d447734c87">silent_emplace</a>(C &amp;&amp;callable)</td><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></td><td class="entry"></td></tr>
140-
<tr><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html#acf423e2775a25c2b8be4dce7dae8880a">silent_emplace</a>(C &amp;&amp;... callables)</td><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></td><td class="entry"></td></tr>
141139
<tr class="even"><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html#a08d669f2286cb90fd5ba7dade1e93fef">transform_reduce</a>(I beg, I end, T &amp;result, B &amp;&amp;bop, U &amp;&amp;uop)</td><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></td><td class="entry"></td></tr>
142140
<tr><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html#a9b81ad3b206a63adff8b8bc423f8c425">transform_reduce</a>(I beg, I end, T &amp;result, B &amp;&amp;bop1, P &amp;&amp;bop2, U &amp;&amp;uop)</td><td class="entry"><a class="el" href="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></td><td class="entry"></td></tr>
143141
<tr class="even"><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>()</td><td class="entry"><a class="el" href="classtf_1_1BasicTaskflow.html">tf::BasicTaskflow&lt; E &gt;</a></td><td class="entry"></td></tr>

0 commit comments

Comments
 (0)