forked from taskflow/taskflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic__taskflow_8hpp_source.html
More file actions
132 lines (130 loc) · 97 KB
/
basic__taskflow_8hpp_source.html
File metadata and controls
132 lines (130 loc) · 97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Cpp-Taskflow</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { init_search(); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname"><a href="https://github.com/cpp-taskflow/cpp-taskflow">Cpp-Taskflow</a>
 <span id="projectnumber">2.3.0</span>
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('basic__taskflow_8hpp_source.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">basic_taskflow.hpp</div> </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="comment">// 2019/04/09 - modified by Tsung-Wei Huang</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span> <span class="comment">// - removed silent_dispatch method</span></div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment">//</span></div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment">// 2019/03/12 - modified by Chun-Xun Lin</span></div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="comment">// - added framework</span></div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="comment">//</span></div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment">// 2019/02/11 - modified by Tsung-Wei Huang</span></div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment">// - refactored run_until</span></div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="comment">// - added allocator to topologies</span></div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="comment">// - changed to list for topologies</span></div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span> <span class="comment">//</span></div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="comment">// 2019/02/10 - modified by Chun-Xun Lin</span></div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span> <span class="comment">// - added run_n to execute framework</span></div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="comment">// - finished first peer-review with TW</span></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment">//</span></div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="comment">// 2018/07 - 2019/02/09 - missing logs</span></div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="comment">//</span></div><div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="comment">// 2018/06/30 - created by Tsung-Wei Huang</span></div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="comment">// - added BasicTaskflow template</span></div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span> </div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span> <span class="comment">// TODO items:</span></div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span> <span class="comment">// 1. come up with a better way to remove the "joined" links </span></div><div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="comment">// during the execution of a static node (1st layer)</span></div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="comment">//</span></div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="preprocessor">#pragma once</span></div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span> </div><div class="line"><a name="l00028"></a><span class="lineno"> 28</span> <span class="preprocessor">#include "topology.hpp"</span></div><div class="line"><a name="l00029"></a><span class="lineno"> 29</span> </div><div class="line"><a name="l00030"></a><span class="lineno"> 30</span> <span class="keyword">namespace </span><a class="code" href="namespacetf.html">tf</a> {</div><div class="line"><a name="l00031"></a><span class="lineno"> 31</span> </div><div class="line"><a name="l00043"></a><span class="lineno"> 43</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00044"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html"> 44</a></span> <span class="keyword">class </span><a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow</a> : <span class="keyword">public</span> <a class="code" href="classtf_1_1FlowBuilder.html">FlowBuilder</a> {</div><div class="line"><a name="l00045"></a><span class="lineno"> 45</span> </div><div class="line"><a name="l00046"></a><span class="lineno"> 46</span>  <span class="keyword">using</span> StaticWork = <span class="keyword">typename</span> Node::StaticWork;</div><div class="line"><a name="l00047"></a><span class="lineno"> 47</span>  <span class="keyword">using</span> DynamicWork = <span class="keyword">typename</span> Node::DynamicWork;</div><div class="line"><a name="l00048"></a><span class="lineno"> 48</span>  </div><div class="line"><a name="l00049"></a><span class="lineno"> 49</span>  <span class="keyword">struct </span>Closure {</div><div class="line"><a name="l00050"></a><span class="lineno"> 50</span> </div><div class="line"><a name="l00051"></a><span class="lineno"> 51</span>  <span class="keyword">friend</span> <span class="keyword">class </span><a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow</a>;</div><div class="line"><a name="l00052"></a><span class="lineno"> 52</span>  </div><div class="line"><a name="l00053"></a><span class="lineno"> 53</span>  Closure() = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00054"></a><span class="lineno"> 54</span>  Closure(<span class="keyword">const</span> Closure&) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00055"></a><span class="lineno"> 55</span>  Closure(<a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow</a>&, Node&);</div><div class="line"><a name="l00056"></a><span class="lineno"> 56</span> </div><div class="line"><a name="l00057"></a><span class="lineno"> 57</span>  Closure& operator = (<span class="keyword">const</span> Closure&) = <span class="keywordflow">default</span>;</div><div class="line"><a name="l00058"></a><span class="lineno"> 58</span>  </div><div class="line"><a name="l00059"></a><span class="lineno"> 59</span>  <span class="keywordtype">void</span> operator ()() <span class="keyword">const</span>;</div><div class="line"><a name="l00060"></a><span class="lineno"> 60</span> </div><div class="line"><a name="l00061"></a><span class="lineno"> 61</span>  <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow</a>* taskflow {<span class="keyword">nullptr</span>};</div><div class="line"><a name="l00062"></a><span class="lineno"> 62</span>  Node* node {<span class="keyword">nullptr</span>};</div><div class="line"><a name="l00063"></a><span class="lineno"> 63</span>  };</div><div class="line"><a name="l00064"></a><span class="lineno"> 64</span>  </div><div class="line"><a name="l00065"></a><span class="lineno"> 65</span>  <span class="keyword">public</span>:</div><div class="line"><a name="l00066"></a><span class="lineno"> 66</span>  </div><div class="line"><a name="l00072"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#afa5ea834928f68f950f59889c626c2ff"> 72</a></span>  <span class="keyword">using</span> <a class="code" href="classtf_1_1BasicTaskflow.html#afa5ea834928f68f950f59889c626c2ff">Executor</a> = E<Closure>;</div><div class="line"><a name="l00073"></a><span class="lineno"> 73</span>  </div><div class="line"><a name="l00077"></a><span class="lineno"> 77</span>  <span class="keyword">explicit</span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow</a>();</div><div class="line"><a name="l00078"></a><span class="lineno"> 78</span>  </div><div class="line"><a name="l00082"></a><span class="lineno"> 82</span>  <span class="keyword">explicit</span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow</a>(<span class="keywordtype">unsigned</span> N);</div><div class="line"><a name="l00083"></a><span class="lineno"> 83</span>  </div><div class="line"><a name="l00087"></a><span class="lineno"> 87</span>  <span class="keyword">explicit</span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow</a>(std::shared_ptr<Executor> executor);</div><div class="line"><a name="l00088"></a><span class="lineno"> 88</span>  </div><div class="line"><a name="l00095"></a><span class="lineno"> 95</span>  <a class="code" href="classtf_1_1BasicTaskflow.html#ae820a9ab3cad471a591da4de749752ae">~BasicTaskflow</a>();</div><div class="line"><a name="l00096"></a><span class="lineno"> 96</span>  </div><div class="line"><a name="l00102"></a><span class="lineno"> 102</span>  std::shared_ptr<Executor> <a class="code" href="classtf_1_1BasicTaskflow.html#abe76e5288016861aaf1dafc0218d3084">share_executor</a>();</div><div class="line"><a name="l00103"></a><span class="lineno"> 103</span>  </div><div class="line"><a name="l00109"></a><span class="lineno"> 109</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">dispatch</a>();</div><div class="line"><a name="l00110"></a><span class="lineno"> 110</span>  </div><div class="line"><a name="l00116"></a><span class="lineno"> 116</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> C></div><div class="line"><a name="l00117"></a><span class="lineno"> 117</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">dispatch</a>(C&&);</div><div class="line"><a name="l00118"></a><span class="lineno"> 118</span>  </div><div class="line"><a name="l00122"></a><span class="lineno"> 122</span>  <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>();</div><div class="line"><a name="l00123"></a><span class="lineno"> 123</span> </div><div class="line"><a name="l00128"></a><span class="lineno"> 128</span>  <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af">wait_for_topologies</a>();</div><div class="line"><a name="l00129"></a><span class="lineno"> 129</span>  </div><div class="line"><a name="l00135"></a><span class="lineno"> 135</span>  <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">dump</a>(std::ostream& ostream) <span class="keyword">const</span>;</div><div class="line"><a name="l00136"></a><span class="lineno"> 136</span> </div><div class="line"><a name="l00142"></a><span class="lineno"> 142</span>  <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78">dump_topologies</a>(std::ostream& ostream) <span class="keyword">const</span>;</div><div class="line"><a name="l00143"></a><span class="lineno"> 143</span>  </div><div class="line"><a name="l00147"></a><span class="lineno"> 147</span>  <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a18341302575dcb719e455d84a738273f">num_nodes</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00148"></a><span class="lineno"> 148</span> </div><div class="line"><a name="l00152"></a><span class="lineno"> 152</span>  <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a9cef9ee3d27ffc78bfa953c8ed25b559">num_workers</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00153"></a><span class="lineno"> 153</span> </div><div class="line"><a name="l00157"></a><span class="lineno"> 157</span>  <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a7e97ed52d9d0470d2751f32748adb253">num_topologies</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00158"></a><span class="lineno"> 158</span>  </div><div class="line"><a name="l00162"></a><span class="lineno"> 162</span>  std::string <a class="code" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">dump</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00163"></a><span class="lineno"> 163</span>  </div><div class="line"><a name="l00167"></a><span class="lineno"> 167</span>  std::string <a class="code" href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78">dump_topologies</a>() <span class="keyword">const</span>;</div><div class="line"><a name="l00168"></a><span class="lineno"> 168</span> </div><div class="line"><a name="l00176"></a><span class="lineno"> 176</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc">run</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework);</div><div class="line"><a name="l00177"></a><span class="lineno"> 177</span> </div><div class="line"><a name="l00186"></a><span class="lineno"> 186</span>  <span class="keyword">template</span><<span class="keyword">typename</span> C></div><div class="line"><a name="l00187"></a><span class="lineno"> 187</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc">run</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework, C&& callable);</div><div class="line"><a name="l00188"></a><span class="lineno"> 188</span> </div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">run_n</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework, <span class="keywordtype">size_t</span> N);</div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span> </div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span>  <span class="keyword">template</span><<span class="keyword">typename</span> C></div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">run_n</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework, <span class="keywordtype">size_t</span> N, C&& callable);</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span> </div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span>  <span class="keyword">template</span><<span class="keyword">typename</span> P></div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">run_until</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework, P&& predicate);</div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span> </div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span>  <span class="keyword">template</span><<span class="keyword">typename</span> P, <span class="keyword">typename</span> C></div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span>  std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">run_until</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& framework, P&& predicate, C&& callable);</div><div class="line"><a name="l00233"></a><span class="lineno"> 233</span> </div><div class="line"><a name="l00234"></a><span class="lineno"> 234</span>  <span class="keyword">private</span>:</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span>  </div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span>  Graph _graph;</div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span> </div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span>  std::shared_ptr<Executor> _executor;</div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span> </div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span>  <span class="comment">//std::list<Topology, SingularAllocator<Topology>> _topologies;</span></div><div class="line"><a name="l00241"></a><span class="lineno"> 241</span>  std::list<Topology> _topologies;</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span> </div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span>  <span class="keywordtype">void</span> _schedule(Node&);</div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span>  <span class="keywordtype">void</span> _schedule(PassiveVector<Node*>&);</div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span>  <span class="keywordtype">void</span> _set_module_node(Node&);</div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span> };</div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span> </div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span> <span class="comment">// ============================================================================</span></div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span> <span class="comment">// BasicTaskflow::Closure Method Definitions</span></div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span> <span class="comment">// ============================================================================</span></div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span> </div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span> <span class="comment">// Function: run</span></div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00254"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc"> 254</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc">BasicTaskflow<E>::run</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f) {</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span>  <span class="keywordflow">return</span> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">run_n</a>(f, 1, [](){});</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span> }</div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span> </div><div class="line"><a name="l00258"></a><span class="lineno"> 258</span> <span class="comment">// Function: run</span></div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00260"></a><span class="lineno"> 260</span> <span class="keyword">template</span> <<span class="keyword">typename</span> C></div><div class="line"><a name="l00261"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a876ef3bbdbae7333bd2c3bf0f36a865c"> 261</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc">BasicTaskflow<E>::run</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f, C&& c) {</div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span>  static_assert(std::is_invocable<C>::value);</div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span>  <span class="keywordflow">return</span> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">run_n</a>(f, 1, std::forward<C>(c));</div><div class="line"><a name="l00264"></a><span class="lineno"> 264</span> }</div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span> </div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span> <span class="comment">// Function: run_n</span></div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00268"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6"> 268</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">BasicTaskflow<E>::run_n</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f, <span class="keywordtype">size_t</span> repeat) {</div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span>  <span class="keywordflow">return</span> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">run_n</a>(f, repeat, [](){});</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span> }</div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span> </div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span> <span class="comment">// Function: run_n</span></div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00274"></a><span class="lineno"> 274</span> <span class="keyword">template</span> <<span class="keyword">typename</span> C></div><div class="line"><a name="l00275"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a006f2d8acf994a9c6e721b1bcc007b17"> 275</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">BasicTaskflow<E>::run_n</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f, <span class="keywordtype">size_t</span> repeat, C&& c) {</div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span>  <span class="keywordflow">return</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">run_until</a>(f, [repeat]() <span class="keyword">mutable</span> { <span class="keywordflow">return</span> repeat-- == 0; }, std::forward<C>(c));</div><div class="line"><a name="l00277"></a><span class="lineno"> 277</span> }</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span> </div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span> <span class="comment">// Function: run_until</span></div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span> <span class="keyword">template</span> <<span class="keyword">typename</span> P></div><div class="line"><a name="l00282"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0"> 282</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">BasicTaskflow<E>::run_until</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f, P&& predicate) {</div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>  <span class="keywordflow">return</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">run_until</a>(f, std::forward<P>(predicate), [](){});</div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span> }</div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span> </div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span> <span class="comment">// Function: run_until</span></div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span> <span class="keyword">template</span> <<span class="keyword">typename</span> P, <span class="keyword">typename</span> C></div><div class="line"><a name="l00289"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#aaa4618b734a976a39ca1cc47a8e44c4e"> 289</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">BasicTaskflow<E>::run_until</a>(<a class="code" href="classtf_1_1Framework.html">Framework</a>& f, P&& predicate, C&& c) {</div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span> </div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span>  <span class="comment">// Predicate must return a boolean value</span></div><div class="line"><a name="l00292"></a><span class="lineno"> 292</span>  static_assert(std::is_invocable_v<C> && std::is_invocable_v<P>);</div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span> </div><div class="line"><a name="l00294"></a><span class="lineno"> 294</span>  <span class="keywordflow">if</span>(std::invoke(predicate)) {</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span>  <span class="keywordflow">return</span> std::async(std::launch::deferred, [](){}).share();</div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span>  }</div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span>  </div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span>  <span class="comment">// create a topology for this run</span></div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span>  <span class="keyword">auto</span> &tpg = _topologies.emplace_back(f, std::forward<P>(predicate));</div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span> </div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span>  <span class="comment">// Iterative execution to avoid stack overflow</span></div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span>  <span class="keywordflow">if</span>(<a class="code" href="classtf_1_1BasicTaskflow.html#a9cef9ee3d27ffc78bfa953c8ed25b559">num_workers</a>() == 0) {</div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span> </div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span>  <span class="comment">// Clear last execution data & Build precedence between nodes and target</span></div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span>  tpg._bind(f._graph);</div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span> </div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span>  <span class="keywordflow">do</span> {</div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span>  _schedule(tpg._sources);</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span>  tpg._recover_num_sinks();</div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span>  } <span class="keywordflow">while</span>(!std::invoke(tpg._predicate));</div><div class="line"><a name="l00311"></a><span class="lineno"> 311</span> </div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span>  std::invoke(c);</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span>  tpg._promise.set_value();</div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span> </div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span>  <span class="keywordflow">return</span> tpg._future;</div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span>  }</div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span> </div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span>  <span class="comment">// Multi-threaded execution.</span></div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span>  std::scoped_lock lock(f._mtx);</div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span> </div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span>  f._topologies.push_back(&tpg);</div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span> </div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span>  <span class="keywordtype">bool</span> run_now = (f._topologies.size() == 1);</div><div class="line"><a name="l00324"></a><span class="lineno"> 324</span> </div><div class="line"><a name="l00325"></a><span class="lineno"> 325</span>  <span class="keywordflow">if</span>(run_now) {</div><div class="line"><a name="l00326"></a><span class="lineno"> 326</span>  tpg._bind(f._graph);</div><div class="line"><a name="l00327"></a><span class="lineno"> 327</span>  }</div><div class="line"><a name="l00328"></a><span class="lineno"> 328</span> </div><div class="line"><a name="l00329"></a><span class="lineno"> 329</span>  tpg._work = [&f, c=std::forward<C>(c), <span class="keyword">this</span>] () <span class="keyword">mutable</span> {</div><div class="line"><a name="l00330"></a><span class="lineno"> 330</span>  </div><div class="line"><a name="l00331"></a><span class="lineno"> 331</span>  <span class="comment">// case 1: we still need to run the topology again</span></div><div class="line"><a name="l00332"></a><span class="lineno"> 332</span>  <span class="keywordflow">if</span>(!std::invoke(f._topologies.front()->_predicate)) {</div><div class="line"><a name="l00333"></a><span class="lineno"> 333</span>  f._topologies.front()->_recover_num_sinks();</div><div class="line"><a name="l00334"></a><span class="lineno"> 334</span>  _schedule(f._topologies.front()->_sources); </div><div class="line"><a name="l00335"></a><span class="lineno"> 335</span>  }</div><div class="line"><a name="l00336"></a><span class="lineno"> 336</span>  <span class="comment">// case 2: the final run of this topology</span></div><div class="line"><a name="l00337"></a><span class="lineno"> 337</span>  <span class="keywordflow">else</span> {</div><div class="line"><a name="l00338"></a><span class="lineno"> 338</span>  std::invoke(c);</div><div class="line"><a name="l00339"></a><span class="lineno"> 339</span> </div><div class="line"><a name="l00340"></a><span class="lineno"> 340</span>  f._mtx.lock();</div><div class="line"><a name="l00341"></a><span class="lineno"> 341</span> </div><div class="line"><a name="l00342"></a><span class="lineno"> 342</span>  <span class="comment">// If there is another run (interleave between lock)</span></div><div class="line"><a name="l00343"></a><span class="lineno"> 343</span>  <span class="keywordflow">if</span>(f._topologies.size() > 1) {</div><div class="line"><a name="l00344"></a><span class="lineno"> 344</span> </div><div class="line"><a name="l00345"></a><span class="lineno"> 345</span>  <span class="comment">// Set the promise</span></div><div class="line"><a name="l00346"></a><span class="lineno"> 346</span>  f._topologies.front()->_promise.set_value();</div><div class="line"><a name="l00347"></a><span class="lineno"> 347</span>  f._topologies.pop_front();</div><div class="line"><a name="l00348"></a><span class="lineno"> 348</span>  f._topologies.front()->_bind(f._graph);</div><div class="line"><a name="l00349"></a><span class="lineno"> 349</span>  f._mtx.unlock();</div><div class="line"><a name="l00350"></a><span class="lineno"> 350</span>  _schedule(f._topologies.front()->_sources);</div><div class="line"><a name="l00351"></a><span class="lineno"> 351</span>  }</div><div class="line"><a name="l00352"></a><span class="lineno"> 352</span>  <span class="keywordflow">else</span> {</div><div class="line"><a name="l00353"></a><span class="lineno"> 353</span>  assert(f._topologies.size() == 1);</div><div class="line"><a name="l00354"></a><span class="lineno"> 354</span>  <span class="comment">// Need to back up the promise first here becuz framework might be </span></div><div class="line"><a name="l00355"></a><span class="lineno"> 355</span>  <span class="comment">// destroy before taskflow leaves</span></div><div class="line"><a name="l00356"></a><span class="lineno"> 356</span>  <span class="keyword">auto</span> &p = f._topologies.front()->_promise; </div><div class="line"><a name="l00357"></a><span class="lineno"> 357</span>  f._topologies.pop_front();</div><div class="line"><a name="l00358"></a><span class="lineno"> 358</span>  f._mtx.unlock();</div><div class="line"><a name="l00359"></a><span class="lineno"> 359</span>  </div><div class="line"><a name="l00360"></a><span class="lineno"> 360</span>  <span class="comment">// We set the promise in the end in case framework leaves before taskflow</span></div><div class="line"><a name="l00361"></a><span class="lineno"> 361</span>  p.set_value();</div><div class="line"><a name="l00362"></a><span class="lineno"> 362</span>  }</div><div class="line"><a name="l00363"></a><span class="lineno"> 363</span>  }</div><div class="line"><a name="l00364"></a><span class="lineno"> 364</span>  };</div><div class="line"><a name="l00365"></a><span class="lineno"> 365</span> </div><div class="line"><a name="l00366"></a><span class="lineno"> 366</span>  <span class="keywordflow">if</span>(run_now) {</div><div class="line"><a name="l00367"></a><span class="lineno"> 367</span>  _schedule(tpg._sources);</div><div class="line"><a name="l00368"></a><span class="lineno"> 368</span>  }</div><div class="line"><a name="l00369"></a><span class="lineno"> 369</span> </div><div class="line"><a name="l00370"></a><span class="lineno"> 370</span>  <span class="keywordflow">return</span> tpg._future;</div><div class="line"><a name="l00371"></a><span class="lineno"> 371</span> }</div><div class="line"><a name="l00372"></a><span class="lineno"> 372</span> </div><div class="line"><a name="l00373"></a><span class="lineno"> 373</span> <span class="comment">// Constructor</span></div><div class="line"><a name="l00374"></a><span class="lineno"> 374</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00375"></a><span class="lineno"> 375</span> <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow<E>::Closure::Closure</a>(<a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow</a>& t, Node& n) : </div><div class="line"><a name="l00376"></a><span class="lineno"> 376</span>  taskflow{&t}, node {&n} {</div><div class="line"><a name="l00377"></a><span class="lineno"> 377</span> }</div><div class="line"><a name="l00378"></a><span class="lineno"> 378</span> </div><div class="line"><a name="l00379"></a><span class="lineno"> 379</span> <span class="comment">// Operator ()</span></div><div class="line"><a name="l00380"></a><span class="lineno"> 380</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00381"></a><span class="lineno"> 381</span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow<E>::Closure::operator () </a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00382"></a><span class="lineno"> 382</span> </div><div class="line"><a name="l00383"></a><span class="lineno"> 383</span>  <span class="comment">// Here we need to fetch the num_successors first to avoid the invalid memory</span></div><div class="line"><a name="l00384"></a><span class="lineno"> 384</span>  <span class="comment">// access caused by topology clear.</span></div><div class="line"><a name="l00385"></a><span class="lineno"> 385</span>  <span class="keyword">const</span> <span class="keyword">auto</span> num_successors = node->num_successors();</div><div class="line"><a name="l00386"></a><span class="lineno"> 386</span>  </div><div class="line"><a name="l00387"></a><span class="lineno"> 387</span>  <span class="comment">// regular node type</span></div><div class="line"><a name="l00388"></a><span class="lineno"> 388</span>  <span class="comment">// The default node work type. We only need to execute the callback if any.</span></div><div class="line"><a name="l00389"></a><span class="lineno"> 389</span>  <span class="keywordflow">if</span>(<span class="keyword">auto</span> index=node->_work.index(); index == 0) {</div><div class="line"><a name="l00390"></a><span class="lineno"> 390</span>  <span class="keywordflow">if</span>(node->_module != <span class="keyword">nullptr</span>) {</div><div class="line"><a name="l00391"></a><span class="lineno"> 391</span>  <span class="keywordtype">bool</span> first_time = !node->is_spawned();</div><div class="line"><a name="l00392"></a><span class="lineno"> 392</span>  std::invoke(std::get<StaticWork>(node->_work));</div><div class="line"><a name="l00393"></a><span class="lineno"> 393</span>  <span class="keywordflow">if</span>(first_time) {</div><div class="line"><a name="l00394"></a><span class="lineno"> 394</span>  return ;</div><div class="line"><a name="l00395"></a><span class="lineno"> 395</span>  }</div><div class="line"><a name="l00396"></a><span class="lineno"> 396</span>  }</div><div class="line"><a name="l00397"></a><span class="lineno"> 397</span>  <span class="keywordflow">else</span> {</div><div class="line"><a name="l00398"></a><span class="lineno"> 398</span>  <span class="keywordflow">if</span>(<span class="keyword">auto</span> &f = std::get<StaticWork>(node->_work); f != <span class="keyword">nullptr</span>){</div><div class="line"><a name="l00399"></a><span class="lineno"> 399</span>  std::invoke(f);</div><div class="line"><a name="l00400"></a><span class="lineno"> 400</span>  }</div><div class="line"><a name="l00401"></a><span class="lineno"> 401</span>  }</div><div class="line"><a name="l00402"></a><span class="lineno"> 402</span>  }</div><div class="line"><a name="l00403"></a><span class="lineno"> 403</span>  <span class="comment">// subflow node type </span></div><div class="line"><a name="l00404"></a><span class="lineno"> 404</span>  <span class="keywordflow">else</span> {</div><div class="line"><a name="l00405"></a><span class="lineno"> 405</span>  </div><div class="line"><a name="l00406"></a><span class="lineno"> 406</span>  <span class="comment">// Clear the subgraph before the task execution</span></div><div class="line"><a name="l00407"></a><span class="lineno"> 407</span>  <span class="keywordflow">if</span>(!node->is_spawned()) {</div><div class="line"><a name="l00408"></a><span class="lineno"> 408</span>  node->_subgraph.emplace();</div><div class="line"><a name="l00409"></a><span class="lineno"> 409</span>  }</div><div class="line"><a name="l00410"></a><span class="lineno"> 410</span>  </div><div class="line"><a name="l00411"></a><span class="lineno"> 411</span>  <a class="code" href="classtf_1_1SubflowBuilder.html">SubflowBuilder</a> fb(*(node->_subgraph));</div><div class="line"><a name="l00412"></a><span class="lineno"> 412</span> </div><div class="line"><a name="l00413"></a><span class="lineno"> 413</span>  std::invoke(std::get<DynamicWork>(node->_work), fb);</div><div class="line"><a name="l00414"></a><span class="lineno"> 414</span>  </div><div class="line"><a name="l00415"></a><span class="lineno"> 415</span>  <span class="comment">// Need to create a subflow if first time & subgraph is not empty </span></div><div class="line"><a name="l00416"></a><span class="lineno"> 416</span>  <span class="keywordflow">if</span>(!node->is_spawned()) {</div><div class="line"><a name="l00417"></a><span class="lineno"> 417</span>  node->set_spawned();</div><div class="line"><a name="l00418"></a><span class="lineno"> 418</span>  <span class="keywordflow">if</span>(!node->_subgraph->empty()) {</div><div class="line"><a name="l00419"></a><span class="lineno"> 419</span>  <span class="comment">// For storing the source nodes</span></div><div class="line"><a name="l00420"></a><span class="lineno"> 420</span>  PassiveVector<Node*> src; </div><div class="line"><a name="l00421"></a><span class="lineno"> 421</span>  <span class="keywordflow">for</span>(<span class="keyword">auto</span>& n : *(node->_subgraph)) {</div><div class="line"><a name="l00422"></a><span class="lineno"> 422</span>  n._topology = node->_topology;</div><div class="line"><a name="l00423"></a><span class="lineno"> 423</span>  n.set_subtask();</div><div class="line"><a name="l00424"></a><span class="lineno"> 424</span>  <span class="keywordflow">if</span>(n.num_successors() == 0) {</div><div class="line"><a name="l00425"></a><span class="lineno"> 425</span>  <span class="keywordflow">if</span>(fb.<a class="code" href="classtf_1_1SubflowBuilder.html#a39793fbfee4d3fe01541cfd04bf1a5c7">detached</a>()) {</div><div class="line"><a name="l00426"></a><span class="lineno"> 426</span>  node->_topology->_num_sinks ++;</div><div class="line"><a name="l00427"></a><span class="lineno"> 427</span>  }</div><div class="line"><a name="l00428"></a><span class="lineno"> 428</span>  <span class="keywordflow">else</span> {</div><div class="line"><a name="l00429"></a><span class="lineno"> 429</span>  n.precede(*node);</div><div class="line"><a name="l00430"></a><span class="lineno"> 430</span>  }</div><div class="line"><a name="l00431"></a><span class="lineno"> 431</span>  }</div><div class="line"><a name="l00432"></a><span class="lineno"> 432</span>  <span class="keywordflow">if</span>(n.num_dependents() == 0) {</div><div class="line"><a name="l00433"></a><span class="lineno"> 433</span>  src.push_back(&n);</div><div class="line"><a name="l00434"></a><span class="lineno"> 434</span>  }</div><div class="line"><a name="l00435"></a><span class="lineno"> 435</span>  }</div><div class="line"><a name="l00436"></a><span class="lineno"> 436</span> </div><div class="line"><a name="l00437"></a><span class="lineno"> 437</span>  taskflow->_schedule(src);</div><div class="line"><a name="l00438"></a><span class="lineno"> 438</span> </div><div class="line"><a name="l00439"></a><span class="lineno"> 439</span>  <span class="keywordflow">if</span>(!fb.<a class="code" href="classtf_1_1SubflowBuilder.html#a39793fbfee4d3fe01541cfd04bf1a5c7">detached</a>()) {</div><div class="line"><a name="l00440"></a><span class="lineno"> 440</span>  <span class="keywordflow">return</span>;</div><div class="line"><a name="l00441"></a><span class="lineno"> 441</span>  }</div><div class="line"><a name="l00442"></a><span class="lineno"> 442</span>  }</div><div class="line"><a name="l00443"></a><span class="lineno"> 443</span>  }</div><div class="line"><a name="l00444"></a><span class="lineno"> 444</span>  } <span class="comment">// End of DynamicWork -----------------------------------------------------</span></div><div class="line"><a name="l00445"></a><span class="lineno"> 445</span>  </div><div class="line"><a name="l00446"></a><span class="lineno"> 446</span>  <span class="comment">// Recover the runtime change due to dynamic tasking except the target & spawn tasks </span></div><div class="line"><a name="l00447"></a><span class="lineno"> 447</span>  <span class="comment">// This must be done before scheduling the successors, otherwise this might cause </span></div><div class="line"><a name="l00448"></a><span class="lineno"> 448</span>  <span class="comment">// race condition on the _dependents</span></div><div class="line"><a name="l00449"></a><span class="lineno"> 449</span>  <span class="comment">//if(num_successors && !node->_subtask) {</span></div><div class="line"><a name="l00450"></a><span class="lineno"> 450</span>  <span class="keywordflow">if</span>(!node->is_subtask()) {</div><div class="line"><a name="l00451"></a><span class="lineno"> 451</span>  <span class="comment">// Only dynamic tasking needs to restore _dependents</span></div><div class="line"><a name="l00452"></a><span class="lineno"> 452</span>  <span class="comment">// TODO:</span></div><div class="line"><a name="l00453"></a><span class="lineno"> 453</span>  <span class="keywordflow">if</span>(node->_work.index() == 1 && !node->_subgraph->empty()) {</div><div class="line"><a name="l00454"></a><span class="lineno"> 454</span>  <span class="keywordflow">while</span>(!node->_dependents.empty() && node->_dependents.back()->is_subtask()) {</div><div class="line"><a name="l00455"></a><span class="lineno"> 455</span>  node->_dependents.pop_back();</div><div class="line"><a name="l00456"></a><span class="lineno"> 456</span>  }</div><div class="line"><a name="l00457"></a><span class="lineno"> 457</span>  }</div><div class="line"><a name="l00458"></a><span class="lineno"> 458</span>  node->_num_dependents = <span class="keyword">static_cast<</span><span class="keywordtype">int</span><span class="keyword">></span>(node->_dependents.size());</div><div class="line"><a name="l00459"></a><span class="lineno"> 459</span>  node->unset_spawned();</div><div class="line"><a name="l00460"></a><span class="lineno"> 460</span>  }</div><div class="line"><a name="l00461"></a><span class="lineno"> 461</span> </div><div class="line"><a name="l00462"></a><span class="lineno"> 462</span>  <span class="comment">// At this point, the node storage might be destructed.</span></div><div class="line"><a name="l00463"></a><span class="lineno"> 463</span>  <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i=0; i<num_successors; ++i) {</div><div class="line"><a name="l00464"></a><span class="lineno"> 464</span>  <span class="keywordflow">if</span>(--(node->_successors[i]->_num_dependents) == 0) {</div><div class="line"><a name="l00465"></a><span class="lineno"> 465</span>  taskflow->_schedule(*(node->_successors[i]));</div><div class="line"><a name="l00466"></a><span class="lineno"> 466</span>  }</div><div class="line"><a name="l00467"></a><span class="lineno"> 467</span>  }</div><div class="line"><a name="l00468"></a><span class="lineno"> 468</span> </div><div class="line"><a name="l00469"></a><span class="lineno"> 469</span>  <span class="comment">// A node without any successor should check the termination of topology</span></div><div class="line"><a name="l00470"></a><span class="lineno"> 470</span>  <span class="keywordflow">if</span>(num_successors == 0) {</div><div class="line"><a name="l00471"></a><span class="lineno"> 471</span>  <span class="keywordflow">if</span>(--(node->_topology->_num_sinks) == 0) {</div><div class="line"><a name="l00472"></a><span class="lineno"> 472</span> </div><div class="line"><a name="l00473"></a><span class="lineno"> 473</span>  <span class="comment">// This is the last executing node </span></div><div class="line"><a name="l00474"></a><span class="lineno"> 474</span>  <span class="keywordtype">bool</span> is_framework = node->_topology->_handle.index() == 1;</div><div class="line"><a name="l00475"></a><span class="lineno"> 475</span>  <span class="keywordflow">if</span>(node->_topology->_work != <span class="keyword">nullptr</span>) {</div><div class="line"><a name="l00476"></a><span class="lineno"> 476</span>  std::invoke(node->_topology->_work);</div><div class="line"><a name="l00477"></a><span class="lineno"> 477</span>  }</div><div class="line"><a name="l00478"></a><span class="lineno"> 478</span>  <span class="keywordflow">if</span>(!is_framework) {</div><div class="line"><a name="l00479"></a><span class="lineno"> 479</span>  node->_topology->_promise.set_value();</div><div class="line"><a name="l00480"></a><span class="lineno"> 480</span>  }</div><div class="line"><a name="l00481"></a><span class="lineno"> 481</span>  }</div><div class="line"><a name="l00482"></a><span class="lineno"> 482</span>  }</div><div class="line"><a name="l00483"></a><span class="lineno"> 483</span> }</div><div class="line"><a name="l00484"></a><span class="lineno"> 484</span> </div><div class="line"><a name="l00485"></a><span class="lineno"> 485</span> <span class="comment">// ============================================================================</span></div><div class="line"><a name="l00486"></a><span class="lineno"> 486</span> <span class="comment">// BasicTaskflow Method Definitions</span></div><div class="line"><a name="l00487"></a><span class="lineno"> 487</span> <span class="comment">// ============================================================================</span></div><div class="line"><a name="l00488"></a><span class="lineno"> 488</span> </div><div class="line"><a name="l00489"></a><span class="lineno"> 489</span> <span class="comment">// Constructor</span></div><div class="line"><a name="l00490"></a><span class="lineno"> 490</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00491"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71"> 491</a></span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow<E>::BasicTaskflow</a>() : </div><div class="line"><a name="l00492"></a><span class="lineno"> 492</span>  <a class="code" href="classtf_1_1FlowBuilder.html">FlowBuilder</a> {_graph},</div><div class="line"><a name="l00493"></a><span class="lineno"> 493</span>  _executor {std::make_shared<Executor>(std::thread::hardware_concurrency())} {</div><div class="line"><a name="l00494"></a><span class="lineno"> 494</span> }</div><div class="line"><a name="l00495"></a><span class="lineno"> 495</span> </div><div class="line"><a name="l00496"></a><span class="lineno"> 496</span> <span class="comment">// Constructor</span></div><div class="line"><a name="l00497"></a><span class="lineno"> 497</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00498"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#abfad9343208ba7fa8238e544511b5e8f"> 498</a></span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow<E>::BasicTaskflow</a>(<span class="keywordtype">unsigned</span> N) : </div><div class="line"><a name="l00499"></a><span class="lineno"> 499</span>  <a class="code" href="classtf_1_1FlowBuilder.html">FlowBuilder</a> {_graph},</div><div class="line"><a name="l00500"></a><span class="lineno"> 500</span>  _executor {std::make_shared<Executor>(N)} {</div><div class="line"><a name="l00501"></a><span class="lineno"> 501</span> }</div><div class="line"><a name="l00502"></a><span class="lineno"> 502</span> </div><div class="line"><a name="l00503"></a><span class="lineno"> 503</span> <span class="comment">// Constructor</span></div><div class="line"><a name="l00504"></a><span class="lineno"> 504</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00505"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#aee86bd515327964e08b11ca842fe6acd"> 505</a></span> <a class="code" href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">BasicTaskflow<E>::BasicTaskflow</a>(std::shared_ptr<Executor> e) :</div><div class="line"><a name="l00506"></a><span class="lineno"> 506</span>  <a class="code" href="classtf_1_1FlowBuilder.html">FlowBuilder</a> {_graph},</div><div class="line"><a name="l00507"></a><span class="lineno"> 507</span>  _executor {std::move(e)} {</div><div class="line"><a name="l00508"></a><span class="lineno"> 508</span> </div><div class="line"><a name="l00509"></a><span class="lineno"> 509</span>  <span class="keywordflow">if</span>(_executor == <span class="keyword">nullptr</span>) {</div><div class="line"><a name="l00510"></a><span class="lineno"> 510</span>  TF_THROW(Error::EXECUTOR, </div><div class="line"><a name="l00511"></a><span class="lineno"> 511</span>  <span class="stringliteral">"failed to construct taskflow (executor cannot be null)"</span></div><div class="line"><a name="l00512"></a><span class="lineno"> 512</span>  );</div><div class="line"><a name="l00513"></a><span class="lineno"> 513</span>  }</div><div class="line"><a name="l00514"></a><span class="lineno"> 514</span> }</div><div class="line"><a name="l00515"></a><span class="lineno"> 515</span> </div><div class="line"><a name="l00516"></a><span class="lineno"> 516</span> <span class="comment">// Destructor</span></div><div class="line"><a name="l00517"></a><span class="lineno"> 517</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00518"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#ae820a9ab3cad471a591da4de749752ae"> 518</a></span> <a class="code" href="classtf_1_1BasicTaskflow.html#ae820a9ab3cad471a591da4de749752ae">BasicTaskflow<E>::~BasicTaskflow</a>() {</div><div class="line"><a name="l00519"></a><span class="lineno"> 519</span>  <a class="code" href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af">wait_for_topologies</a>();</div><div class="line"><a name="l00520"></a><span class="lineno"> 520</span> }</div><div class="line"><a name="l00521"></a><span class="lineno"> 521</span> </div><div class="line"><a name="l00522"></a><span class="lineno"> 522</span> <span class="comment">// Function: num_nodes</span></div><div class="line"><a name="l00523"></a><span class="lineno"> 523</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00524"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a18341302575dcb719e455d84a738273f"> 524</a></span> <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a18341302575dcb719e455d84a738273f">BasicTaskflow<E>::num_nodes</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00525"></a><span class="lineno"> 525</span>  <span class="keywordflow">return</span> _graph.size();</div><div class="line"><a name="l00526"></a><span class="lineno"> 526</span> }</div><div class="line"><a name="l00527"></a><span class="lineno"> 527</span> </div><div class="line"><a name="l00528"></a><span class="lineno"> 528</span> <span class="comment">// Function: num_workers</span></div><div class="line"><a name="l00529"></a><span class="lineno"> 529</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00530"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a9cef9ee3d27ffc78bfa953c8ed25b559"> 530</a></span> <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a9cef9ee3d27ffc78bfa953c8ed25b559">BasicTaskflow<E>::num_workers</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00531"></a><span class="lineno"> 531</span>  <span class="keywordflow">return</span> _executor->num_workers();</div><div class="line"><a name="l00532"></a><span class="lineno"> 532</span> }</div><div class="line"><a name="l00533"></a><span class="lineno"> 533</span> </div><div class="line"><a name="l00534"></a><span class="lineno"> 534</span> <span class="comment">// Function: num_topologies</span></div><div class="line"><a name="l00535"></a><span class="lineno"> 535</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00536"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a7e97ed52d9d0470d2751f32748adb253"> 536</a></span> <span class="keywordtype">size_t</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a7e97ed52d9d0470d2751f32748adb253">BasicTaskflow<E>::num_topologies</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00537"></a><span class="lineno"> 537</span>  <span class="keywordflow">return</span> _topologies.size();</div><div class="line"><a name="l00538"></a><span class="lineno"> 538</span> }</div><div class="line"><a name="l00539"></a><span class="lineno"> 539</span> </div><div class="line"><a name="l00540"></a><span class="lineno"> 540</span> <span class="comment">// Function: share_executor</span></div><div class="line"><a name="l00541"></a><span class="lineno"> 541</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00542"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#abe76e5288016861aaf1dafc0218d3084"> 542</a></span> std::shared_ptr<typename BasicTaskflow<E>::Executor> <a class="code" href="classtf_1_1BasicTaskflow.html#abe76e5288016861aaf1dafc0218d3084">BasicTaskflow<E>::share_executor</a>() {</div><div class="line"><a name="l00543"></a><span class="lineno"> 543</span>  <span class="keywordflow">return</span> _executor;</div><div class="line"><a name="l00544"></a><span class="lineno"> 544</span> }</div><div class="line"><a name="l00545"></a><span class="lineno"> 545</span> </div><div class="line"><a name="l00546"></a><span class="lineno"> 546</span> <span class="comment">// Procedure: dispatch </span></div><div class="line"><a name="l00547"></a><span class="lineno"> 547</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00548"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5"> 548</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">BasicTaskflow<E>::dispatch</a>() {</div><div class="line"><a name="l00549"></a><span class="lineno"> 549</span> </div><div class="line"><a name="l00550"></a><span class="lineno"> 550</span>  <span class="keywordflow">if</span>(_graph.empty()) {</div><div class="line"><a name="l00551"></a><span class="lineno"> 551</span>  <span class="keywordflow">return</span> std::async(std::launch::deferred, [](){}).share();</div><div class="line"><a name="l00552"></a><span class="lineno"> 552</span>  }</div><div class="line"><a name="l00553"></a><span class="lineno"> 553</span> </div><div class="line"><a name="l00554"></a><span class="lineno"> 554</span>  <span class="keyword">auto</span>& topology = _topologies.emplace_back(std::move(_graph));</div><div class="line"><a name="l00555"></a><span class="lineno"> 555</span>  </div><div class="line"><a name="l00556"></a><span class="lineno"> 556</span>  _schedule(topology._sources);</div><div class="line"><a name="l00557"></a><span class="lineno"> 557</span> </div><div class="line"><a name="l00558"></a><span class="lineno"> 558</span>  <span class="keywordflow">return</span> topology._future;</div><div class="line"><a name="l00559"></a><span class="lineno"> 559</span> }</div><div class="line"><a name="l00560"></a><span class="lineno"> 560</span> </div><div class="line"><a name="l00561"></a><span class="lineno"> 561</span> </div><div class="line"><a name="l00562"></a><span class="lineno"> 562</span> <span class="comment">// Procedure: dispatch with registered callback</span></div><div class="line"><a name="l00563"></a><span class="lineno"> 563</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00564"></a><span class="lineno"> 564</span> <span class="keyword">template</span> <<span class="keyword">typename</span> C></div><div class="line"><a name="l00565"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#ae644520b734078d061e3ceafc7d982ad"> 565</a></span> std::shared_future<void> <a class="code" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">BasicTaskflow<E>::dispatch</a>(C&& c) {</div><div class="line"><a name="l00566"></a><span class="lineno"> 566</span> </div><div class="line"><a name="l00567"></a><span class="lineno"> 567</span>  <span class="keywordflow">if</span>(_graph.empty()) {</div><div class="line"><a name="l00568"></a><span class="lineno"> 568</span>  c();</div><div class="line"><a name="l00569"></a><span class="lineno"> 569</span>  <span class="keywordflow">return</span> std::async(std::launch::deferred, [](){}).share();</div><div class="line"><a name="l00570"></a><span class="lineno"> 570</span>  }</div><div class="line"><a name="l00571"></a><span class="lineno"> 571</span> </div><div class="line"><a name="l00572"></a><span class="lineno"> 572</span>  <span class="keyword">auto</span>& topology = _topologies.emplace_back(std::move(_graph), std::forward<C>(c));</div><div class="line"><a name="l00573"></a><span class="lineno"> 573</span> </div><div class="line"><a name="l00574"></a><span class="lineno"> 574</span>  _schedule(topology._sources);</div><div class="line"><a name="l00575"></a><span class="lineno"> 575</span> </div><div class="line"><a name="l00576"></a><span class="lineno"> 576</span>  <span class="keywordflow">return</span> topology._future;</div><div class="line"><a name="l00577"></a><span class="lineno"> 577</span> }</div><div class="line"><a name="l00578"></a><span class="lineno"> 578</span> </div><div class="line"><a name="l00579"></a><span class="lineno"> 579</span> <span class="comment">// Procedure: wait_for_all</span></div><div class="line"><a name="l00580"></a><span class="lineno"> 580</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00581"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e"> 581</a></span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">BasicTaskflow<E>::wait_for_all</a>() {</div><div class="line"><a name="l00582"></a><span class="lineno"> 582</span>  <span class="keywordflow">if</span>(!_graph.empty()) {</div><div class="line"><a name="l00583"></a><span class="lineno"> 583</span>  <a class="code" href="classtf_1_1BasicTaskflow.html#a848e425f67b49a8a7ac21f6b791999c5">dispatch</a>();</div><div class="line"><a name="l00584"></a><span class="lineno"> 584</span>  }</div><div class="line"><a name="l00585"></a><span class="lineno"> 585</span>  <a class="code" href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af">wait_for_topologies</a>();</div><div class="line"><a name="l00586"></a><span class="lineno"> 586</span> }</div><div class="line"><a name="l00587"></a><span class="lineno"> 587</span> </div><div class="line"><a name="l00588"></a><span class="lineno"> 588</span> <span class="comment">// Procedure: wait_for_topologies</span></div><div class="line"><a name="l00589"></a><span class="lineno"> 589</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00590"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af"> 590</a></span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a8f0ce2026118e97b83cbd727ed0932af">BasicTaskflow<E>::wait_for_topologies</a>() {</div><div class="line"><a name="l00591"></a><span class="lineno"> 591</span>  <span class="keywordflow">for</span>(<span class="keyword">auto</span>& t: _topologies){</div><div class="line"><a name="l00592"></a><span class="lineno"> 592</span>  t._future.get();</div><div class="line"><a name="l00593"></a><span class="lineno"> 593</span>  }</div><div class="line"><a name="l00594"></a><span class="lineno"> 594</span>  _topologies.clear();</div><div class="line"><a name="l00595"></a><span class="lineno"> 595</span> }</div><div class="line"><a name="l00596"></a><span class="lineno"> 596</span> </div><div class="line"><a name="l00597"></a><span class="lineno"> 597</span> <span class="comment">// Procedure: _schedule</span></div><div class="line"><a name="l00598"></a><span class="lineno"> 598</span> <span class="comment">// The main procedure to schedule a give task node.</span></div><div class="line"><a name="l00599"></a><span class="lineno"> 599</span> <span class="comment">// Each task node has two types of tasks - regular and subflow.</span></div><div class="line"><a name="l00600"></a><span class="lineno"> 600</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00601"></a><span class="lineno"> 601</span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow<E>::_schedule</a>(Node& node) {</div><div class="line"><a name="l00602"></a><span class="lineno"> 602</span>  <span class="keywordflow">if</span>(node._module != <span class="keyword">nullptr</span> && !node.is_spawned()) {</div><div class="line"><a name="l00603"></a><span class="lineno"> 603</span>  _set_module_node(node);</div><div class="line"><a name="l00604"></a><span class="lineno"> 604</span>  }</div><div class="line"><a name="l00605"></a><span class="lineno"> 605</span>  _executor->emplace(*<span class="keyword">this</span>, node);</div><div class="line"><a name="l00606"></a><span class="lineno"> 606</span> }</div><div class="line"><a name="l00607"></a><span class="lineno"> 607</span> </div><div class="line"><a name="l00608"></a><span class="lineno"> 608</span> </div><div class="line"><a name="l00609"></a><span class="lineno"> 609</span> <span class="comment">// Procedure: _schedule</span></div><div class="line"><a name="l00610"></a><span class="lineno"> 610</span> <span class="comment">// The main procedure to schedule a set of task nodes.</span></div><div class="line"><a name="l00611"></a><span class="lineno"> 611</span> <span class="comment">// Each task node has two types of tasks - regular and subflow.</span></div><div class="line"><a name="l00612"></a><span class="lineno"> 612</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00613"></a><span class="lineno"> 613</span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow<E>::_schedule</a>(PassiveVector<Node*>& nodes) {</div><div class="line"><a name="l00614"></a><span class="lineno"> 614</span>  std::vector<Closure> closures;</div><div class="line"><a name="l00615"></a><span class="lineno"> 615</span>  closures.reserve(nodes.size());</div><div class="line"><a name="l00616"></a><span class="lineno"> 616</span>  <span class="keywordflow">for</span>(<span class="keyword">auto</span> src : nodes) {</div><div class="line"><a name="l00617"></a><span class="lineno"> 617</span>  <span class="keywordflow">if</span>(src->_module != <span class="keyword">nullptr</span> && !src->is_spawned()) {</div><div class="line"><a name="l00618"></a><span class="lineno"> 618</span>  _set_module_node(*src);</div><div class="line"><a name="l00619"></a><span class="lineno"> 619</span>  }</div><div class="line"><a name="l00620"></a><span class="lineno"> 620</span>  closures.emplace_back(*<span class="keyword">this</span>, *src);</div><div class="line"><a name="l00621"></a><span class="lineno"> 621</span>  }</div><div class="line"><a name="l00622"></a><span class="lineno"> 622</span>  _executor->batch(closures);</div><div class="line"><a name="l00623"></a><span class="lineno"> 623</span> }</div><div class="line"><a name="l00624"></a><span class="lineno"> 624</span> </div><div class="line"><a name="l00625"></a><span class="lineno"> 625</span> </div><div class="line"><a name="l00626"></a><span class="lineno"> 626</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00627"></a><span class="lineno"> 627</span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html">BasicTaskflow<E>::_set_module_node</a>(Node& node) {</div><div class="line"><a name="l00628"></a><span class="lineno"> 628</span> </div><div class="line"><a name="l00629"></a><span class="lineno"> 629</span>  node._work = [&node, <span class="keyword">this</span>, tgt{PassiveVector<Node*>()}] () <span class="keyword">mutable</span> {</div><div class="line"><a name="l00630"></a><span class="lineno"> 630</span> </div><div class="line"><a name="l00631"></a><span class="lineno"> 631</span>  <span class="comment">// second time to enter this context</span></div><div class="line"><a name="l00632"></a><span class="lineno"> 632</span>  <span class="keywordflow">if</span>(node.is_spawned()) {</div><div class="line"><a name="l00633"></a><span class="lineno"> 633</span>  node._dependents.resize(node._dependents.size()-tgt.size());</div><div class="line"><a name="l00634"></a><span class="lineno"> 634</span>  <span class="keywordflow">for</span>(<span class="keyword">auto</span>& t: tgt) {</div><div class="line"><a name="l00635"></a><span class="lineno"> 635</span>  t->_successors.clear();</div><div class="line"><a name="l00636"></a><span class="lineno"> 636</span>  }</div><div class="line"><a name="l00637"></a><span class="lineno"> 637</span>  return ;</div><div class="line"><a name="l00638"></a><span class="lineno"> 638</span>  }</div><div class="line"><a name="l00639"></a><span class="lineno"> 639</span> </div><div class="line"><a name="l00640"></a><span class="lineno"> 640</span>  <span class="comment">// first time to enter this context</span></div><div class="line"><a name="l00641"></a><span class="lineno"> 641</span>  node.set_spawned();</div><div class="line"><a name="l00642"></a><span class="lineno"> 642</span> </div><div class="line"><a name="l00643"></a><span class="lineno"> 643</span>  PassiveVector<Node*> src;</div><div class="line"><a name="l00644"></a><span class="lineno"> 644</span> </div><div class="line"><a name="l00645"></a><span class="lineno"> 645</span>  <span class="keywordflow">for</span>(<span class="keyword">auto</span> &n: node._module->_graph) {</div><div class="line"><a name="l00646"></a><span class="lineno"> 646</span>  n._topology = node._topology;</div><div class="line"><a name="l00647"></a><span class="lineno"> 647</span>  <span class="keywordflow">if</span>(n.num_dependents() == 0) {</div><div class="line"><a name="l00648"></a><span class="lineno"> 648</span>  src.push_back(&n);</div><div class="line"><a name="l00649"></a><span class="lineno"> 649</span>  }</div><div class="line"><a name="l00650"></a><span class="lineno"> 650</span>  <span class="keywordflow">if</span>(n.num_successors() == 0) {</div><div class="line"><a name="l00651"></a><span class="lineno"> 651</span>  n.<a class="code" href="classtf_1_1FlowBuilder.html#af7c4a5d732d49bd63d554a92cd240f3f">precede</a>(node);</div><div class="line"><a name="l00652"></a><span class="lineno"> 652</span>  tgt.push_back(&n);</div><div class="line"><a name="l00653"></a><span class="lineno"> 653</span>  }</div><div class="line"><a name="l00654"></a><span class="lineno"> 654</span>  }</div><div class="line"><a name="l00655"></a><span class="lineno"> 655</span> </div><div class="line"><a name="l00656"></a><span class="lineno"> 656</span>  _schedule(src);</div><div class="line"><a name="l00657"></a><span class="lineno"> 657</span>  };</div><div class="line"><a name="l00658"></a><span class="lineno"> 658</span> }</div><div class="line"><a name="l00659"></a><span class="lineno"> 659</span> </div><div class="line"><a name="l00660"></a><span class="lineno"> 660</span> </div><div class="line"><a name="l00661"></a><span class="lineno"> 661</span> <span class="comment">// Function: dump_topologies</span></div><div class="line"><a name="l00662"></a><span class="lineno"> 662</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00663"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78"> 663</a></span> std::string <a class="code" href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78">BasicTaskflow<E>::dump_topologies</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00664"></a><span class="lineno"> 664</span>  </div><div class="line"><a name="l00665"></a><span class="lineno"> 665</span>  std::ostringstream os;</div><div class="line"><a name="l00666"></a><span class="lineno"> 666</span> </div><div class="line"><a name="l00667"></a><span class="lineno"> 667</span>  <span class="keywordflow">for</span>(<span class="keyword">const</span> <span class="keyword">auto</span>& tpg : _topologies) {</div><div class="line"><a name="l00668"></a><span class="lineno"> 668</span>  tpg.dump(os);</div><div class="line"><a name="l00669"></a><span class="lineno"> 669</span>  }</div><div class="line"><a name="l00670"></a><span class="lineno"> 670</span>  </div><div class="line"><a name="l00671"></a><span class="lineno"> 671</span>  <span class="keywordflow">return</span> os.str();</div><div class="line"><a name="l00672"></a><span class="lineno"> 672</span> }</div><div class="line"><a name="l00673"></a><span class="lineno"> 673</span> </div><div class="line"><a name="l00674"></a><span class="lineno"> 674</span> <span class="comment">// Function: dump_topologies</span></div><div class="line"><a name="l00675"></a><span class="lineno"> 675</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00676"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#af17f2410531dfd08b0e55ef80a8f828d"> 676</a></span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78">BasicTaskflow<E>::dump_topologies</a>(std::ostream& os)<span class="keyword"> const </span>{</div><div class="line"><a name="l00677"></a><span class="lineno"> 677</span>  <span class="keywordflow">for</span>(<span class="keyword">const</span> <span class="keyword">auto</span>& tpg : _topologies) {</div><div class="line"><a name="l00678"></a><span class="lineno"> 678</span>  tpg.dump(os);</div><div class="line"><a name="l00679"></a><span class="lineno"> 679</span>  }</div><div class="line"><a name="l00680"></a><span class="lineno"> 680</span> }</div><div class="line"><a name="l00681"></a><span class="lineno"> 681</span> </div><div class="line"><a name="l00682"></a><span class="lineno"> 682</span> <span class="comment">// Function: dump</span></div><div class="line"><a name="l00683"></a><span class="lineno"> 683</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00684"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#adac448e1cc44307856b3116d7ed5490f"> 684</a></span> <span class="keywordtype">void</span> <a class="code" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">BasicTaskflow<E>::dump</a>(std::ostream& os)<span class="keyword"> const </span>{</div><div class="line"><a name="l00685"></a><span class="lineno"> 685</span> </div><div class="line"><a name="l00686"></a><span class="lineno"> 686</span>  os << <span class="stringliteral">"digraph Taskflow {\n"</span>;</div><div class="line"><a name="l00687"></a><span class="lineno"> 687</span>  </div><div class="line"><a name="l00688"></a><span class="lineno"> 688</span>  <span class="keywordflow">for</span>(<span class="keyword">const</span> <span class="keyword">auto</span>& node : _graph) {</div><div class="line"><a name="l00689"></a><span class="lineno"> 689</span>  node.dump(os);</div><div class="line"><a name="l00690"></a><span class="lineno"> 690</span>  }</div><div class="line"><a name="l00691"></a><span class="lineno"> 691</span> </div><div class="line"><a name="l00692"></a><span class="lineno"> 692</span>  os << <span class="stringliteral">"}\n"</span>;</div><div class="line"><a name="l00693"></a><span class="lineno"> 693</span> }</div><div class="line"><a name="l00694"></a><span class="lineno"> 694</span> </div><div class="line"><a name="l00695"></a><span class="lineno"> 695</span> <span class="comment">// Function: dump</span></div><div class="line"><a name="l00696"></a><span class="lineno"> 696</span> <span class="comment">// Dumps the taskflow in graphviz. </span></div><div class="line"><a name="l00697"></a><span class="lineno"> 697</span> <span class="comment">// The result can be viewed at http://www.webgraphviz.com/.</span></div><div class="line"><a name="l00698"></a><span class="lineno"> 698</span> <span class="keyword">template</span> <<span class="keyword">template</span> <<span class="keyword">typename</span>...> <span class="keyword">typename</span> E></div><div class="line"><a name="l00699"></a><span class="lineno"><a class="line" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722"> 699</a></span> std::string <a class="code" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">BasicTaskflow<E>::dump</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00700"></a><span class="lineno"> 700</span>  std::ostringstream os;</div><div class="line"><a name="l00701"></a><span class="lineno"> 701</span>  <a class="code" href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">dump</a>(os); </div><div class="line"><a name="l00702"></a><span class="lineno"> 702</span>  <span class="keywordflow">return</span> os.str();</div><div class="line"><a name="l00703"></a><span class="lineno"> 703</span> }</div><div class="line"><a name="l00704"></a><span class="lineno"> 704</span> </div><div class="line"><a name="l00705"></a><span class="lineno"> 705</span> </div><div class="line"><a name="l00706"></a><span class="lineno"> 706</span> } <span class="comment">// end of namespace tf ----------------------------------------------------</span></div><div class="line"><a name="l00707"></a><span class="lineno"> 707</span> </div><div class="ttc" id="classtf_1_1BasicTaskflow_html_a3a24f26ead77969d133d72372df456e0"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a3a24f26ead77969d133d72372df456e0">tf::BasicTaskflow::run_until</a></div><div class="ttdeci">std::shared_future< void > run_until(Framework &framework, P &&predicate)</div><div class="ttdoc">runs the framework multiple times until the predicate becomes true and invoke a callback ...</div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:282</div></div>
<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:44</div></div>
<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< Executor > 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:542</div></div>
<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:783</div></div>
<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:524</div></div>
<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< void > dispatch()</div><div class="ttdoc">dispatches the present graph to threads and returns immediately </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:548</div></div>
<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>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_abe9f7964777c2d65052b2dda7307efb6"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#abe9f7964777c2d65052b2dda7307efb6">tf::BasicTaskflow::run_n</a></div><div class="ttdeci">std::shared_future< void > run_n(Framework &framework, size_t N)</div><div class="ttdoc">runs the framework for N times </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:268</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_ab077a9419b9cb6cbc9f9647c621c8c71"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#ab077a9419b9cb6cbc9f9647c621c8c71">tf::BasicTaskflow::BasicTaskflow</a></div><div class="ttdeci">BasicTaskflow()</div><div class="ttdoc">constructs the taskflow with std::thread::hardware_concurrency worker threads </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:491</div></div>
<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:18</div></div>
<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:731</div></div>
<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:536</div></div>
<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:590</div></div>
<div class="ttc" id="classtf_1_1FlowBuilder_html_af7c4a5d732d49bd63d554a92cd240f3f"><div class="ttname"><a href="classtf_1_1FlowBuilder.html#af7c4a5d732d49bd63d554a92cd240f3f">tf::FlowBuilder::precede</a></div><div class="ttdeci">void precede(Task A, Task B)</div><div class="ttdoc">adds a dependency link from task A to task B </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:285</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_afc7f9ac974ee803b2d3b5577a6c8a2bc"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#afc7f9ac974ee803b2d3b5577a6c8a2bc">tf::BasicTaskflow::run</a></div><div class="ttdeci">std::shared_future< void > run(Framework &framework)</div><div class="ttdoc">runs the framework once </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:254</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a37ef86998f23ee7315be032c40fe815e"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">tf::BasicTaskflow::wait_for_all</a></div><div class="ttdeci">void wait_for_all()</div><div class="ttdoc">dispatches the present graph to threads and wait for all topologies to complete </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:581</div></div>
<div class="ttc" id="classtf_1_1FlowBuilder_html"><div class="ttname"><a href="classtf_1_1FlowBuilder.html">tf::FlowBuilder</a></div><div class="ttdoc">Building blocks of a task dependency graph. </div><div class="ttdef"><b>Definition:</b> flow_builder.hpp:13</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a9cef9ee3d27ffc78bfa953c8ed25b559"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a9cef9ee3d27ffc78bfa953c8ed25b559">tf::BasicTaskflow::num_workers</a></div><div class="ttdeci">size_t num_workers() const</div><div class="ttdoc">queries the number of worker threads in the associated executor </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:530</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_afa5ea834928f68f950f59889c626c2ff"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#afa5ea834928f68f950f59889c626c2ff">tf::BasicTaskflow::Executor</a></div><div class="ttdeci">E< Closure > Executor</div><div class="ttdoc">alias of executor type </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:72</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_ae820a9ab3cad471a591da4de749752ae"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#ae820a9ab3cad471a591da4de749752ae">tf::BasicTaskflow::~BasicTaskflow</a></div><div class="ttdeci">~BasicTaskflow()</div><div class="ttdoc">destructs the taskflow </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:518</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_a913a31040546bcf9d6e044580d170722"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#a913a31040546bcf9d6e044580d170722">tf::BasicTaskflow::dump</a></div><div class="ttdeci">std::string dump() const</div><div class="ttdoc">dumps the present task dependency graph in DOT format to a std::string </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:699</div></div>
<div class="ttc" id="classtf_1_1BasicTaskflow_html_ae4c67b7bc87564e8b5b309837f4b6d78"><div class="ttname"><a href="classtf_1_1BasicTaskflow.html#ae4c67b7bc87564e8b5b309837f4b6d78">tf::BasicTaskflow::dump_topologies</a></div><div class="ttdeci">std::string dump_topologies() const</div><div class="ttdoc">dumps the existing topologies in DOT format to a std::string </div><div class="ttdef"><b>Definition:</b> basic_taskflow.hpp:663</div></div>
</div><!-- fragment --></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="dir_88dad41ea55ca2177e141d32a93e931c.html">taskflow</a></li><li class="navelem"><a class="el" href="dir_673055edecdb89adebf808cf469a0c15.html">graph</a></li><li class="navelem"><b>basic_taskflow.hpp</b></li>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
</ul>
</div>
</body>
</html>