You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
+[Example 2: Connect Two Dependency Graphs](#Example-2-Connect-Two-Dependency-Graphs)
13
14
14
15
# Graph and Topology
15
16
@@ -174,5 +175,74 @@ Notice in Line 24 the counter ends up with 20.
174
175
The destructor of a taskflow object will not leave until all running
175
176
topologies finish.
176
177
178
+
# Example 2: Connect Two Dependency Graphs
179
+
180
+
The example demonstrates how to use the `std::future` to manually impose a dependency link
181
+
on two dispatched graphs.
182
+
183
+
```cpp
184
+
1: #include <taskflow/taskflow.hpp>
185
+
2:
186
+
3: int main() {
187
+
4:
188
+
5: tf::Taskflow tf(4);
189
+
6:
190
+
7: std::vector<int> items; // uninitialized
191
+
8: int sum; // uninitialized
192
+
9:
193
+
10: // the first dependency graph
194
+
11: // task C to resize the item vector
195
+
12: auto A = tf.silent_emplace([&] () { items.resize(1024); });
196
+
13:
197
+
14: // task B to initialize the item vector
198
+
15: auto B = tf.silent_emplace([&] () { std::iota(items.begin(), items.end(), 0); });
199
+
16:
200
+
17: // A must run before B
201
+
18: A.precede(B);
202
+
19:
203
+
20: // dispatch the graph asynchronously and obtain the future to access its status
204
+
21: auto fu1 = tf.dispatch();
205
+
22:
206
+
23: // the second dependency graph
207
+
24: // task C to overlap the exeuction of the first graph
208
+
25: auto C = tf.silent_emplace([&] () {
209
+
26: sum = 0; // in practice, this can be some expensive initializations
210
+
27: });
211
+
28:
212
+
29: // task D can't start until the first graph completes
213
+
30: auto D = tf.silent_emplace([&] () {
214
+
31: fu1.get();
215
+
32: for(auto item : items) {
216
+
33: sum += item;
217
+
34: }
218
+
35: });
219
+
36:
220
+
37: C.precede(D);
221
+
38:
222
+
39: auto fu2 = tf.dispatch();
223
+
40:
224
+
41: // wait on the second dependency graph to finish
225
+
42: fu2.get();
226
+
43:
227
+
44: assert(sum == (0 + 1023) * 1024 / 2);
228
+
45:
229
+
46: return 0;
230
+
47: }
231
+
```
232
+
233
+
Debrief:
234
+
+ Line 5 creates a taskflow object with four worker threads
235
+
+ Line 7-8 creates a vector of integer items and an integer variable to store the summation value
236
+
+ Line 10-21 creates a dependency graph that resizes the vector size and fills it with sequentially increasing values starting with zero
237
+
+ Line 23-39 creates another dependency graph that sums up the values in the vector
238
+
+ Line 25-27 creates a task that initializes the variable `sum` to zero, and overlaps its execution with the first dependency graph
239
+
+ Line 30-35 creates a task that blocks until the first dependency graph completes and then sums up all integer values in the propertly initialized vector
240
+
+ Line 42 blocks until the second dependency graph finishes
241
+
+ Line 44 puts an assertion guard on the final summation value
242
+
243
+
By the time the second dependency graph finishes,
244
+
the first dependency graph must have already finished due to Line 31.
245
+
The result of the variable `sum` ends up being the summation over
0 commit comments