forked from taskflow/taskflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParallelIterations.html
More file actions
320 lines (307 loc) · 36.3 KB
/
Copy pathParallelIterations.html
File metadata and controls
320 lines (307 loc) · 36.3 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Taskflow Algorithms » Parallel Iterations | Taskflow QuickStart</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
<link rel="stylesheet" href="m-dark+documentation.compiled.css" />
<link rel="icon" href="favicon.ico" type="image/vnd.microsoft.icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#22272e" />
</head>
<body>
<header><nav id="navigation">
<div class="m-container">
<div class="m-row">
<span id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">
<a href="https://taskflow.github.io"><img src="taskflow_logo.png" alt="" />Taskflow</a> <span class="m-breadcrumb">|</span> <a href="index.html" class="m-thin">QuickStart</a>
</span>
<div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
<a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
<path id="m-doc-search-icon-path" d="m6 0c-3.31 0-6 2.69-6 6 0 3.31 2.69 6 6 6 1.49 0 2.85-0.541 3.89-1.44-0.0164 0.338 0.147 0.759 0.5 1.15l3.22 3.79c0.552 0.614 1.45 0.665 2 0.115 0.55-0.55 0.499-1.45-0.115-2l-3.79-3.22c-0.392-0.353-0.812-0.515-1.15-0.5 0.895-1.05 1.44-2.41 1.44-3.89 0-3.31-2.69-6-6-6zm0 1.56a4.44 4.44 0 0 1 4.44 4.44 4.44 4.44 0 0 1-4.44 4.44 4.44 4.44 0 0 1-4.44-4.44 4.44 4.44 0 0 1 4.44-4.44z"/>
</svg></a>
<a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
<a id="m-navbar-hide" href="#" title="Hide navigation"></a>
</div>
<div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
<div class="m-row">
<ol class="m-col-t-6 m-col-m-none">
<li><a href="pages.html">Handbook</a></li>
<li><a href="namespaces.html">Namespaces</a></li>
</ol>
<ol class="m-col-t-6 m-col-m-none" start="3">
<li><a href="annotated.html">Classes</a></li>
<li><a href="files.html">Files</a></li>
<li class="m-show-m"><a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
<use href="#m-doc-search-icon-path" />
</svg></a></li>
</ol>
</div>
</div>
</div>
</div>
</nav></header>
<main><article>
<div class="m-container m-container-inflatable">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<h1>
<span class="m-breadcrumb"><a href="Algorithms.html">Taskflow Algorithms</a> »</span>
Parallel Iterations
</h1>
<nav class="m-block m-default">
<h3>Contents</h3>
<ul>
<li><a href="#ParallelIterationsIncludeTheHeader">Include the Header</a></li>
<li><a href="#A1IndexBasedParallelFor">Create an Index-based Parallel-Iteration Task</a></li>
<li><a href="#ParallelForEachCaptureIndicesByReference">Capture Indices by Reference</a></li>
<li><a href="#A1IteratorBasedParallelFor">Create an Iterator-based Parallel-Iteration Task</a></li>
<li><a href="#ParallelForEachCaptureIteratorsByReference">Capture Iterators by Reference</a></li>
<li><a href="#ParallelIterationsConfigureAPartitioner">Configure a Partitioner</a></li>
</ul>
</nav>
<p>Taskflow provides template functions for constructing tasks to perform parallel iterations over ranges of items.</p><section id="ParallelIterationsIncludeTheHeader"><h2><a href="#ParallelIterationsIncludeTheHeader">Include the Header</a></h2><p>You need to include the header file, <code>taskflow/algorithm/for_each.hpp</code>, for using parallel-iteration algorithms.</p><pre class="m-code"><span class="cp">#include</span><span class="w"> </span><span class="cpf"><taskflow/algorithm/for_each.hpp></span><span class="cp"></span></pre></section><section id="A1IndexBasedParallelFor"><h2><a href="#A1IndexBasedParallelFor">Create an Index-based Parallel-Iteration Task</a></h2><p>Index-based parallel-for performs parallel iterations over a range <code>[first, last)</code> with the given <code>step</code> size. The task created by <a href="classtf_1_1FlowBuilder.html#a47ea2b35d0ec18afb35b45316939dc67" class="m-doc">tf::<wbr />Taskflow::<wbr />for_each_index(B first, E last, S step, C callable, P&& part)</a> represents parallel execution of the following loop:</p><pre class="m-code"><span class="c1">// positive step</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="n">first</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o"><</span><span class="n">last</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">+=</span><span class="n">step</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">callable</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="c1">// negative step</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="n">first</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">></span><span class="n">last</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">+=</span><span class="n">step</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">callable</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span></pre><p>We support only integer-based range. The range can go positive or negative direction.</p><pre class="m-code"><span class="n">taskflow</span><span class="p">.</span><span class="n">for_each_index</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="p">[](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">});</span><span class="w"> </span><span class="c1">// 50 loops with a + step</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">for_each_index</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">-2</span><span class="p">,</span><span class="w"> </span><span class="p">[](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">});</span><span class="w"> </span><span class="c1">// 50 loops with a - step</span></pre><p>Notice that either positive or negative direction is defined in terms of the range, <code>[first, last)</code>, where <code>end</code> is excluded. In the positive case, the 50 items are 0, 2, 4, 6, 8, ..., 96, 98. In the negative case, the 50 items are 100, 98, 96, 04, ... 4, 2. An example of the Taskflow graph for the positive case under 12 workers is depicted below:</p><div class="m-graph"><svg style="width: 86.300rem; height: 11.600rem;" viewBox="0.00 0.00 863.43 116.00">
<g transform="scale(1 1) rotate(0) translate(4 112)">
<title>Taskflow</title>
<g class="m-node m-flat">
<title>p0xce2720</title>
<ellipse cx="423" cy="-18" rx="97.2589" ry="18"/>
<text text-anchor="middle" x="423" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">[0, 100) with the step size of 2</text>
</g>
<g class="m-node m-flat">
<title>p0x7f322c000b50</title>
<ellipse cx="27" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="27" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_0</text>
</g>
<g class="m-edge">
<title>p0x7f322c000b50->p0xce2720</title>
<path d="M47.8553,-78.1921C52.7066,-75.8381 57.9365,-73.6012 63,-72 147.6005,-45.2478 247.6838,-31.5972 320.8225,-24.7239"/>
<polygon points="321.3192,-28.1932 330.9595,-23.7984 320.6826,-21.2222 321.3192,-28.1932"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c000c58</title>
<ellipse cx="99" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="99" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_1</text>
</g>
<g class="m-edge">
<title>p0x7f322c000c58->p0xce2720</title>
<path d="M119.8999,-78.3286C124.7488,-75.9675 129.9665,-73.6932 135,-72 198.3384,-50.6937 272.5072,-37.0348 329.714,-28.7851"/>
<polygon points="330.4163,-32.2207 339.8288,-27.3572 329.4377,-25.2895 330.4163,-32.2207"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c000d60</title>
<ellipse cx="171" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="171" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_2</text>
</g>
<g class="m-edge">
<title>p0x7f322c000d60->p0xce2720</title>
<path d="M191.978,-78.5501C196.8229,-76.1775 202.0192,-73.8425 207,-72 251.8059,-55.4252 303.6936,-42.2683 345.3819,-33.0922"/>
<polygon points="346.1717,-36.5023 355.2027,-30.9623 344.6881,-29.6614 346.1717,-36.5023"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c000e68</title>
<ellipse cx="243" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="243" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_3</text>
</g>
<g class="m-edge">
<title>p0x7f322c000e68->p0xce2720</title>
<path d="M264.5278,-78.7766C269.2525,-76.4429 274.2601,-74.0669 279,-72 307.6636,-59.5007 340.2392,-47.136 367.1484,-37.3988"/>
<polygon points="368.5609,-40.6104 376.7881,-33.9349 366.1937,-34.0228 368.5609,-40.6104"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c000f70</title>
<ellipse cx="315" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="315" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_4</text>
</g>
<g class="m-edge">
<title>p0x7f322c000f70->p0xce2720</title>
<path d="M334.3082,-77.1278C349.3248,-67.1168 370.5484,-52.9677 388.4691,-41.0206"/>
<polygon points="390.5804,-43.8196 396.9595,-35.3603 386.6975,-37.9952 390.5804,-43.8196"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c001078</title>
<ellipse cx="387" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="387" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_5</text>
</g>
<g class="m-edge">
<title>p0x7f322c001078->p0xce2720</title>
<path d="M395.7146,-72.5708C399.8228,-64.3544 404.8196,-54.3608 409.4089,-45.1821"/>
<polygon points="412.648,-46.5301 413.9897,-36.0206 406.387,-43.3996 412.648,-46.5301"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c001180</title>
<ellipse cx="459" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="459" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_6</text>
</g>
<g class="m-edge">
<title>p0x7f322c001180->p0xce2720</title>
<path d="M450.2854,-72.5708C446.1772,-64.3544 441.1804,-54.3608 436.5911,-45.1821"/>
<polygon points="439.613,-43.3996 432.0103,-36.0206 433.352,-46.5301 439.613,-43.3996"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c001288</title>
<ellipse cx="531" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="531" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_7</text>
</g>
<g class="m-edge">
<title>p0x7f322c001288->p0xce2720</title>
<path d="M511.6918,-77.1278C496.6752,-67.1168 475.4516,-52.9677 457.5309,-41.0206"/>
<polygon points="459.3025,-37.9952 449.0405,-35.3603 455.4196,-43.8196 459.3025,-37.9952"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c001390</title>
<ellipse cx="603" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="603" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_8</text>
</g>
<g class="m-edge">
<title>p0x7f322c001390->p0xce2720</title>
<path d="M581.4722,-78.7766C576.7475,-76.4429 571.7399,-74.0669 567,-72 538.3364,-59.5007 505.7608,-47.136 478.8516,-37.3988"/>
<polygon points="479.8063,-34.0228 469.2119,-33.9349 477.4391,-40.6104 479.8063,-34.0228"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c001498</title>
<ellipse cx="675" cy="-90" rx="27" ry="18"/>
<text text-anchor="middle" x="675" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_9</text>
</g>
<g class="m-edge">
<title>p0x7f322c001498->p0xce2720</title>
<path d="M654.022,-78.5501C649.1771,-76.1775 643.9808,-73.8425 639,-72 594.1941,-55.4252 542.3064,-42.2683 500.6181,-33.0922"/>
<polygon points="501.3119,-29.6614 490.7973,-30.9623 499.8283,-36.5023 501.3119,-29.6614"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c0015a0</title>
<ellipse cx="749" cy="-90" rx="29.3664" ry="18"/>
<text text-anchor="middle" x="749" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_10</text>
</g>
<g class="m-edge">
<title>p0x7f322c0015a0->p0xce2720</title>
<path d="M726.4807,-78.1714C721.4808,-75.8754 716.1381,-73.6678 711,-72 647.0962,-51.2575 572.4764,-37.5448 515.2055,-29.1293"/>
<polygon points="515.4804,-25.6329 505.0833,-27.6704 514.4817,-32.5613 515.4804,-25.6329"/>
</g>
<g class="m-node m-flat">
<title>p0x7f322c0016a8</title>
<ellipse cx="826" cy="-90" rx="29.3664" ry="18"/>
<text text-anchor="middle" x="826" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">pfg_11</text>
</g>
<g class="m-edge">
<title>p0x7f322c0016a8->p0xce2720</title>
<path d="M803.326,-78.2197C798.0747,-75.8642 792.4311,-73.6198 787,-72 700.4627,-46.191 598.515,-32.4199 524.5577,-25.2616"/>
<polygon points="524.5969,-21.7499 514.3123,-24.2949 523.9393,-28.7189 524.5969,-21.7499"/>
</g>
</g>
</svg>
</div></section><section id="ParallelForEachCaptureIndicesByReference"><h2><a href="#ParallelForEachCaptureIndicesByReference">Capture Indices by Reference</a></h2><p>You can pass indices by reference using <a href="https://en.cppreference.com/w/cpp/utility/functional/ref">std::<wbr />ref</a> to marshal parameter update between dependent tasks. This is especially useful when the range indices are unknown at the time of creating a for-each-index task, but is initialized from another task.</p><pre class="m-code"><span class="kt">int</span><span class="o">*</span><span class="w"> </span><span class="n">vec</span><span class="p">;</span><span class="w"></span>
<span class="kt">int</span><span class="w"> </span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">;</span><span class="w"></span>
<span class="k">auto</span><span class="w"> </span><span class="n">init</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&</span><span class="p">](){</span><span class="w"></span>
<span class="w"> </span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1000</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="n">vec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="p">[</span><span class="mi">1000</span><span class="p">];</span><span class="w"> </span>
<span class="p">});</span><span class="w"></span>
<span class="k">auto</span><span class="w"> </span><span class="n">pf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">for_each_index</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">first</span><span class="p">),</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">last</span><span class="p">),</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span>
<span class="w"> </span><span class="p">[</span><span class="o">&</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel iteration on index "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">vec</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">);</span><span class="w"></span>
<span class="c1">// wrong! must use std::ref, or first and last are captured by copy</span>
<span class="c1">// auto pf = taskflow.for_each_index(first, last, 1, [&](int i) {</span>
<span class="c1">// std::cout << "parallel iteration on index " << vec[i] << '\n';</span>
<span class="c1">// });</span>
<span class="n">init</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pf</span><span class="p">);</span><span class="w"></span></pre><p>When <code>init</code> finishes, the parallel-for task <code>pf</code> will see <code>first</code> as 0 and <code>last</code> as 1000 and performs parallel iterations over the 1000 items.</p></section><section id="A1IteratorBasedParallelFor"><h2><a href="#A1IteratorBasedParallelFor">Create an Iterator-based Parallel-Iteration Task</a></h2><p>Iterator-based parallel-for performs parallel iterations over a range specified by two <a href="https://en.cppreference.com/w/cpp/iterator/iterator">STL-styled iterators</a>, <code>first</code> and <code>last</code>. The task created by <a href="classtf_1_1FlowBuilder.html#a025717373e424a6ccf9a61163bdaa585" class="m-doc">tf::<wbr />Taskflow::<wbr />for_each(B first, E last, C callable, P&& part)</a> represents a parallel execution of the following loop:</p><pre class="m-code"><span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="n">first</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o"><</span><span class="n">last</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">callable</span><span class="p">(</span><span class="o">*</span><span class="n">i</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span></pre><p><a href="classtf_1_1FlowBuilder.html#a025717373e424a6ccf9a61163bdaa585" class="m-doc">tf::<wbr />Taskflow::<wbr />for_each(B first, E last, C callable, P&& part)</a> simultaneously applies the callable to the object obtained by dereferencing every iterator in the range <code>[first, last)</code>. It is user's responsibility for ensuring the range is valid within the execution of the parallel-for task. Iterators must have the post-increment operator ++ defined.</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">vec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">};</span><span class="w"></span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span><span class="w"> </span><span class="p">[](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">){</span><span class="w"> </span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel for on item "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"> </span>
<span class="p">});</span><span class="w"></span>
<span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="s">"hi"</span><span class="p">,</span><span class="w"> </span><span class="s">"from"</span><span class="p">,</span><span class="w"> </span><span class="s">"t"</span><span class="p">,</span><span class="w"> </span><span class="s">"a"</span><span class="p">,</span><span class="w"> </span><span class="s">"s"</span><span class="p">,</span><span class="w"> </span><span class="s">"k"</span><span class="p">,</span><span class="w"> </span><span class="s">"f"</span><span class="p">,</span><span class="w"> </span><span class="s">"low"</span><span class="p">};</span><span class="w"></span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="n">list</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span><span class="w"> </span><span class="p">[](</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span><span class="w"> </span><span class="n">str</span><span class="p">){</span><span class="w"> </span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel for on item "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">str</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"> </span>
<span class="p">});</span><span class="w"></span></pre></section><section id="ParallelForEachCaptureIteratorsByReference"><h2><a href="#ParallelForEachCaptureIteratorsByReference">Capture Iterators by Reference</a></h2><p>Similar to <a href="classtf_1_1FlowBuilder.html#a47ea2b35d0ec18afb35b45316939dc67" class="m-doc">tf::<wbr />Taskflow::<wbr />for_each_index</a>, iterators of <a href="classtf_1_1FlowBuilder.html#a025717373e424a6ccf9a61163bdaa585" class="m-doc">tf::<wbr />Taskflow::<wbr />for_each</a> are templated to allow capturing range parameters by reference, such that one task can set up the range before another task performs the parallel-for algorithm. For example:</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">vec</span><span class="p">;</span><span class="w"></span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>::</span><span class="n">iterator</span><span class="w"> </span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">;;</span><span class="w"></span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">init</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&</span><span class="p">](){</span><span class="w"></span>
<span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span><span class="w"></span>
<span class="w"> </span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span><span class="w"></span>
<span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">();</span><span class="w"></span>
<span class="p">});</span><span class="w"></span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">pf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">first</span><span class="p">),</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">last</span><span class="p">),</span><span class="w"> </span><span class="p">[</span><span class="o">&</span><span class="p">](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel iteration on item "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"></span>
<span class="p">});</span><span class="w"></span>
<span class="c1">// wrong! must use std::ref, or first and last are captured by copy</span>
<span class="c1">// tf::Task pf = taskflow.for_each(first, last, [&](int i) {</span>
<span class="c1">// std::cout << "parallel iteration on item " << i << '\n';</span>
<span class="c1">// });</span>
<span class="n">init</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pf</span><span class="p">);</span><span class="w"></span></pre><p>When <code>init</code> finishes, the parallel-for task <code>pf</code> will see <code>first</code> pointing to the beginning of <code>vec</code> and <code>last</code> pointing to the end of <code>vec</code> and performs parallel iterations over the 1000 items. The two tasks form an end-to-end task graph where the parameters of parallel-for are computed on the fly.</p></section><section id="ParallelIterationsConfigureAPartitioner"><h2><a href="#ParallelIterationsConfigureAPartitioner">Configure a Partitioner</a></h2><p>You can configure a partitioner for parallel-iteration tasks to run with different scheduling methods, such as guided partitioning, dynamic partitioning, and static partitioning. The following example creates two parallel-iteration tasks using two different partitioners, one with the static partitioning algorithm and another one with the guided partitioning algorithm:</p><pre class="m-code"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">vec</span><span class="p">(</span><span class="mi">1024</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="n">tf</span><span class="o">::</span><span class="n">ExecutionPolicy</span><span class="o"><</span><span class="n">tf</span><span class="o">::</span><span class="n">StaticPartitioner</span><span class="o">></span><span class="w"> </span><span class="n">static_partitioner</span><span class="p">;</span><span class="w"></span>
<span class="n">tf</span><span class="o">::</span><span class="n">ExecutionPolicy</span><span class="o"><</span><span class="n">tf</span><span class="o">::</span><span class="n">GuidedPartitioner</span><span class="o">></span><span class="w"> </span><span class="n">guided_partitioner</span><span class="p">;</span><span class="w"></span>
<span class="c1">// create a parallel-iteration task with static partitioner</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="w"></span>
<span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span><span class="w"> </span><span class="p">[</span><span class="o">&</span><span class="p">](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel iteration on item "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="p">},</span><span class="w"></span>
<span class="w"> </span><span class="n">static_partitioner</span><span class="w"></span>
<span class="p">);</span><span class="w"></span>
<span class="c1">// create a parallel-iteration task with guided partitioner</span>
<span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="w"></span>
<span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span><span class="w"> </span><span class="n">vec</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span><span class="w"> </span><span class="p">[</span><span class="o">&</span><span class="p">](</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"parallel iteration on item "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="p">},</span><span class="w"></span>
<span class="w"> </span><span class="n">guided_partitioner</span><span class="w"></span>
<span class="p">);</span><span class="w"></span></pre><aside class="m-note m-info"><h4>Note</h4><p>By default, parallel-iteration tasks use <a href="namespacetf.html#a77d193108ae375fdfc554e7f10bea23e" class="m-doc">tf::<wbr />DefaultPartitioner</a> if no partitioner is specified.</p></aside></section>
</div>
</div>
</div>
</article></main>
<div class="m-doc-search" id="search">
<a href="#!" onclick="return hideSearch()"></a>
<div class="m-container">
<div class="m-row">
<div class="m-col-m-8 m-push-m-2">
<div class="m-doc-search-header m-text m-small">
<div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
<div id="search-symbolcount">…</div>
</div>
<div class="m-doc-search-content">
<form>
<input type="search" name="q" id="search-input" placeholder="Loading …" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
</form>
<noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
<div id="search-help" class="m-text m-dim m-text-center">
<p class="m-noindent">Search for symbols, directories, files, pages or
modules. You can omit any prefix from the symbol or file path; adding a
<code>:</code> or <code>/</code> suffix lists all members of given symbol or
directory.</p>
<p class="m-noindent">Use <span class="m-label m-dim">↓</span>
/ <span class="m-label m-dim">↑</span> to navigate through the list,
<span class="m-label m-dim">Enter</span> to go.
<span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
copy a link to the result using <span class="m-label m-dim">⌘</span>
<span class="m-label m-dim">L</span> while <span class="m-label m-dim">⌘</span>
<span class="m-label m-dim">M</span> produces a Markdown link.</p>
</div>
<div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
<ul id="search-results"></ul>
</div>
</div>
</div>
</div>
</div>
<script src="search-v2.js"></script>
<script src="searchdata-v2.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">
<div class="m-col-l-10 m-push-l-1">
<p>Taskflow handbook is part of the <a href="https://taskflow.github.io">Taskflow project</a>, copyright © <a href="https://tsung-wei-huang.github.io/">Dr. Tsung-Wei Huang</a>, 2018–2023.<br />Generated by <a href="https://doxygen.org/">Doxygen</a> 1.8.14 and <a href="https://mcss.mosra.cz/">m.css</a>.</p>
</div>
</div>
</div>
</nav></footer>
</body>
</html>