mesytec-mnode/external/taskflow-3.8.0/docs/TaskParallelPipeline.html
2025-01-04 01:25:05 +01:00

1292 lines
160 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Taskflow Algorithms &raquo; Task-parallel Pipeline | 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> &raquo;</span>
Task-parallel Pipeline
</h1>
<nav class="m-block m-default">
<h3>Contents</h3>
<ul>
<li><a href="#TaskParallelPipelineIncludeHeaderFile">Include the Header</a></li>
<li><a href="#UnderstandPipelineScheduling">Understand the Pipeline Scheduling Framework</a></li>
<li><a href="#CreateATaskParallelPipelineModuleTask">Create a Task-parallel Pipeline Module Task</a></li>
<li>
<a href="#ConnectWithTasks">Connect Pipeline with Other Tasks</a>
<ul>
<li><a href="#IterateAPipeline">Example 1: Iterate a Pipeline</a></li>
<li><a href="#ConcatenateTwoPipelines">Example 2: Concatenate Two Pipelines</a></li>
<li><a href="#DefineMultipleTaskParallelPipelines">Example 3: Define Multiple Parallel Pipelines</a></li>
</ul>
</li>
<li><a href="#ResetPipeline">Reset a Pipeline</a></li>
<li><a href="#TaskParallelPipelineLearnMore">Learn More about Taskflow Pipeline</a></li>
</ul>
</nav>
<p>Taskflow provides a <em>task-parallel</em> pipeline programming framework for you to implement a pipeline algorithm. Pipeline parallelism refers to a parallel execution of multiple data tokens through a linear chain of pipes or stages. Each stage processes the data token sent from the previous stage, applies the given callable to that data token, and then sends the result to the next stage. Multiple data tokens can be processed simultaneously across different stages.</p><section id="TaskParallelPipelineIncludeHeaderFile"><h2><a href="#TaskParallelPipelineIncludeHeaderFile">Include the Header</a></h2><p>You need to include the header file, <code>taskflow/algorithm/pipeline.hpp</code>, for implementing task-parallel pipeline algorithms.</p><pre class="m-code"><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;taskflow/algorithm/pipeline.hpp&gt;</span></pre></section><section id="UnderstandPipelineScheduling"><h2><a href="#UnderstandPipelineScheduling">Understand the Pipeline Scheduling Framework</a></h2><p>A <a href="classtf_1_1Pipeline.html" class="m-doc">tf::<wbr />Pipeline</a> object is a <em>composable</em> graph to create a <em>pipeline scheduling framework</em> through a module task in a taskflow (see <a href="ComposableTasking.html" class="m-doc">Composable Tasking</a>). Unlike the conventional pipeline programming frameworks (e.g., Intel TBB Parallel Pipeline), Taskflow&#x27;s pipeline algorithm does not provide any data abstraction, which often restricts users from optimizing data layouts in their applications, but a flexible framework for users to customize their application data atop an efficient pipeline scheduling framework.</p><div class="m-graph"><svg style="width: 24.200rem; height: 33.200rem;" viewBox="0.00 0.00 242.00 332.00">
<g transform="scale(1 1) rotate(0) translate(4 328)">
<title>Taskflow</title>
<g class="m-cluster">
<title>cluster0</title>
<polygon stroke-dasharray="5,2" points="8,-245 8,-316 226,-316 226,-245 8,-245"/>
<text text-anchor="middle" x="117" y="-304" font-family="Helvetica,sans-Serif" font-size="10.00">line 0</text>
</g>
<g class="m-cluster">
<title>cluster1</title>
<polygon stroke-dasharray="5,2" points="8,-166 8,-237 226,-237 226,-166 8,-166"/>
<text text-anchor="middle" x="117" y="-225" font-family="Helvetica,sans-Serif" font-size="10.00">line 1</text>
</g>
<g class="m-cluster">
<title>cluster2</title>
<polygon stroke-dasharray="5,2" points="8,-87 8,-158 226,-158 226,-87 8,-87"/>
<text text-anchor="middle" x="117" y="-146" font-family="Helvetica,sans-Serif" font-size="10.00">line 2</text>
</g>
<g class="m-cluster">
<title>cluster3</title>
<polygon stroke-dasharray="5,2" points="8,-8 8,-79 226,-79 226,-8 8,-8"/>
<text text-anchor="middle" x="117" y="-67" font-family="Helvetica,sans-Serif" font-size="10.00">line 3</text>
</g>
<g class="m-node m-flat">
<title>p00</title>
<ellipse cx="44" cy="-271" rx="27.84" ry="18"/>
<text text-anchor="middle" x="44" y="-268.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;0</text>
</g>
<g class="m-node m-flat">
<title>p10</title>
<ellipse cx="44" cy="-192" rx="27.84" ry="18"/>
<text text-anchor="middle" x="44" y="-189.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;0</text>
</g>
<g class="m-edge">
<title>p00&#45;&gt;p10</title>
<path d="M44,-252.91C44,-243.34 44,-231.18 44,-220.32"/>
<polygon points="47.5,-220.04 44,-210.04 40.5,-220.04 47.5,-220.04"/>
</g>
<g class="m-node m-flat">
<title>p01</title>
<ellipse cx="117" cy="-271" rx="27.84" ry="18"/>
<text text-anchor="middle" x="117" y="-268.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;1</text>
</g>
<g class="m-edge">
<title>p00&#45;&gt;p01</title>
<path d="M71.95,-271C74.28,-271 76.62,-271 78.95,-271"/>
<polygon points="79.19,-274.5 89.19,-271 79.19,-267.5 79.19,-274.5"/>
</g>
<g class="m-node m-flat">
<title>p20</title>
<ellipse cx="44" cy="-113" rx="27.84" ry="18"/>
<text text-anchor="middle" x="44" y="-110.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;0</text>
</g>
<g class="m-edge">
<title>p10&#45;&gt;p20</title>
<path d="M44,-173.91C44,-164.34 44,-152.18 44,-141.32"/>
<polygon points="47.5,-141.04 44,-131.04 40.5,-141.04 47.5,-141.04"/>
</g>
<g class="m-node m-flat">
<title>p11</title>
<ellipse cx="117" cy="-192" rx="27.84" ry="18"/>
<text text-anchor="middle" x="117" y="-189.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;1</text>
</g>
<g class="m-edge">
<title>p10&#45;&gt;p11</title>
<path d="M71.95,-192C74.28,-192 76.62,-192 78.95,-192"/>
<polygon points="79.19,-195.5 89.19,-192 79.19,-188.5 79.19,-195.5"/>
</g>
<g class="m-node m-flat">
<title>p30</title>
<ellipse cx="44" cy="-34" rx="27.84" ry="18"/>
<text text-anchor="middle" x="44" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;0</text>
</g>
<g class="m-edge">
<title>p20&#45;&gt;p30</title>
<path d="M44,-94.91C44,-85.34 44,-73.18 44,-62.32"/>
<polygon points="47.5,-62.04 44,-52.04 40.5,-62.04 47.5,-62.04"/>
</g>
<g class="m-node m-flat">
<title>p21</title>
<ellipse cx="117" cy="-113" rx="27.84" ry="18"/>
<text text-anchor="middle" x="117" y="-110.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;1</text>
</g>
<g class="m-edge">
<title>p20&#45;&gt;p21</title>
<path d="M71.95,-113C74.28,-113 76.62,-113 78.95,-113"/>
<polygon points="79.19,-116.5 89.19,-113 79.19,-109.5 79.19,-116.5"/>
</g>
<g class="m-node m-flat">
<title>p31</title>
<ellipse cx="117" cy="-34" rx="27.84" ry="18"/>
<text text-anchor="middle" x="117" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;1</text>
</g>
<g class="m-edge">
<title>p30&#45;&gt;p31</title>
<path d="M71.95,-34C74.28,-34 76.62,-34 78.95,-34"/>
<polygon points="79.19,-37.5 89.19,-34 79.19,-30.5 79.19,-37.5"/>
</g>
<g class="m-node m-flat">
<title>p02</title>
<ellipse cx="190" cy="-271" rx="27.84" ry="18"/>
<text text-anchor="middle" x="190" y="-268.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;2</text>
</g>
<g class="m-edge">
<title>p01&#45;&gt;p02</title>
<path d="M144.95,-271C147.28,-271 149.62,-271 151.95,-271"/>
<polygon points="152.19,-274.5 162.19,-271 152.19,-267.5 152.19,-274.5"/>
</g>
<g class="m-node m-flat">
<title>p12</title>
<ellipse cx="190" cy="-192" rx="27.84" ry="18"/>
<text text-anchor="middle" x="190" y="-189.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;2</text>
</g>
<g class="m-edge">
<title>p11&#45;&gt;p12</title>
<path d="M144.95,-192C147.28,-192 149.62,-192 151.95,-192"/>
<polygon points="152.19,-195.5 162.19,-192 152.19,-188.5 152.19,-195.5"/>
</g>
<g class="m-node m-flat">
<title>p22</title>
<ellipse cx="190" cy="-113" rx="27.84" ry="18"/>
<text text-anchor="middle" x="190" y="-110.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;2</text>
</g>
<g class="m-edge">
<title>p21&#45;&gt;p22</title>
<path d="M144.95,-113C147.28,-113 149.62,-113 151.95,-113"/>
<polygon points="152.19,-116.5 162.19,-113 152.19,-109.5 152.19,-116.5"/>
</g>
<g class="m-node m-flat">
<title>p32</title>
<ellipse cx="190" cy="-34" rx="27.84" ry="18"/>
<text text-anchor="middle" x="190" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipe&#45;2</text>
</g>
<g class="m-edge">
<title>p31&#45;&gt;p32</title>
<path d="M144.95,-34C147.28,-34 149.62,-34 151.95,-34"/>
<polygon points="152.19,-37.5 162.19,-34 152.19,-30.5 152.19,-37.5"/>
</g>
<g class="m-edge">
<title>p02&#45;&gt;p12</title>
<path d="M190,-252.91C190,-243.34 190,-231.18 190,-220.32"/>
<polygon points="193.5,-220.04 190,-210.04 186.5,-220.04 193.5,-220.04"/>
</g>
<g class="m-edge">
<title>p12&#45;&gt;p22</title>
<path d="M190,-173.91C190,-164.34 190,-152.18 190,-141.32"/>
<polygon points="193.5,-141.04 190,-131.04 186.5,-141.04 193.5,-141.04"/>
</g>
<g class="m-edge">
<title>p22&#45;&gt;p32</title>
<path d="M190,-94.91C190,-85.34 190,-73.18 190,-62.32"/>
<polygon points="193.5,-62.04 190,-52.04 186.5,-62.04 193.5,-62.04"/>
</g>
</g>
</svg>
</div><p>The figure above gives an example of our pipeline scheduling framework. The framework consists of three <em>pipes</em> (serial-parallel-serial stages) and four <em>lines</em> (maximum parallelism), where each line processes at most one data token. A pipeline of three pipes and four lines will propagate each data token through a sequential chain of three pipes and can simultaneously process up to four data tokens at the four lines. Each edge represents a task dependency. For example, the edge from <code>pipe-0</code> to <code>pipe-1</code> in line <code>0</code> represents the task dependency between the first and the second pipes in the first line; the edge from <code>pipe-0</code> in line <code>0</code> to <code>pipe-0</code> in line <code>1</code> represents the task dependency between two adjacent lines when processing two data tokens at the same pipe. Each pipe can be either a <em>serial</em> type or a <em>parallel</em> type, where a serial pipe processes data tokens sequentially and a parallel pipe processes different data tokens simultaneously.</p><aside class="m-note m-info"><h4>Note</h4><p>Due to the nature of pipeline, Taskflow requires the first pipe to be a serial type. The pipeline scheduling algorithm operates in a circular fashion with a factor of line count.</p></aside></section><section id="CreateATaskParallelPipelineModuleTask"><h2><a href="#CreateATaskParallelPipelineModuleTask">Create a Task-parallel Pipeline Module Task</a></h2><p>Taskflow leverages modern C++ and template techniques to strike a balance between the <em>expressiveness</em> and <em>generality</em> in designing the pipeline programming model. In general, there are three steps to create a task-parallel pipeline application:</p><ol><li>Define the pipeline structure (e.g., pipe type, pipe callable, stopping rule, line count)</li><li>Define the data storage and layout, if needed for the application</li><li>Define the pipeline taskflow graph using composition</li></ol><p>The following code creates a pipeline scheduling framework using the example from the previous section. The framework schedules a total of five <em>scheduling tokens</em> labeled from 0 to 4. The first pipe stores the token identifier in a custom data storage, <code>buffer</code>, and each of the rest pipes adds one to the input data from the result of the previous pipe and stores the result into the corresponding line entry in the buffer.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span><span class="w"> </span><span class="c1">// maximum parallelism - each line processes one token at a time</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_lines</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w"> </span><span class="c1">// custom data storage</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer</span><span class="p">;</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span>
<span class="mi">10</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline consists of three pipes (serial-parallel-serial)</span>
<span class="mi">11</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">12</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">13</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">14</span><span class="o">:</span><span class="w"> </span><span class="c1">// generate only 5 scheduling tokens</span>
<span class="mi">15</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">16</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">17</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">18</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">19</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">20</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipe 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="mi">21</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">();</span>
<span class="mi">22</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">23</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">24</span><span class="o">:</span>
<span class="mi">25</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">26</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">27</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipe 1: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="mi">28</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">29</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">30</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">31</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">32</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">33</span><span class="o">:</span>
<span class="mi">34</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">35</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">36</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipe 2: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="mi">37</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">38</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">39</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">40</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">41</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">42</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">43</span><span class="o">:</span>
<span class="mi">44</span><span class="o">:</span><span class="w"> </span><span class="c1">// build the pipeline graph using composition</span>
<span class="mi">45</span><span class="o">:</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">pipeline</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">composed_of</span><span class="p">(</span><span class="n">pl</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="mi">46</span><span class="o">:</span>
<span class="mi">47</span><span class="o">:</span><span class="w"> </span><span class="c1">// execute the taskflow</span>
<span class="mi">48</span><span class="o">:</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>Debrief:</p><ul><li>Lines 4-5 define the structure of the pipeline scheduling framework</li><li>Line 8 defines the data storage as an one-dimensional array of <code>num_lines</code> integers</li><li>Line 12 defines the number of lines in the pipeline</li><li>Lines 13-23 define the first serial pipe, which will stop the pipeline scheduling at the fifth token</li><li>Lines 25-32 define the second parallel pipe</li><li>Lines 34-41 define the third serial pipe</li><li>Line 45 defines the pipeline taskflow graph using composition</li><li>Line 48 executes the taskflow</li></ul><p>Taskflow leverages <a href="RuntimeTasking.html" class="m-doc">Interact with the Runtime</a> and <a href="ComposableTasking.html" class="m-doc">Composable Tasking</a> to implement the pipeline scheduling framework. The taskflow graph of this pipeline example is shown as follows, where 1) one condition task is used to decide which runtime task to run and 2) four runtime tasks are used to schedule tokens at four parallel lines, respectively.</p><div class="m-graph"><svg style="width: 41.600rem; height: 17.800rem;" viewBox="0.00 0.00 416.00 178.00">
<g transform="scale(1 1) rotate(0) translate(4 174)">
<title>Taskflow</title>
<g class="m-cluster">
<title>cluster_p0x7ffc47e53358</title>
<polygon points="8,-91 8,-162 106,-162 106,-91 8,-91"/>
<text text-anchor="middle" x="57" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7ffc47e53220</title>
<polygon points="114,-8 114,-162 400,-162 400,-8 114,-8"/>
<text text-anchor="middle" x="257" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">m1</text>
</g>
<g class="m-node m-flat">
<title>p0x1878a88</title>
<polygon points="98,-135 20,-135 16,-131 16,-99 94,-99 98,-103 98,-135"/>
<polyline points="94,-131 16,-131 "/>
<polyline points="94,-131 94,-99 "/>
<polyline points="94,-131 98,-135 "/>
<text text-anchor="middle" x="57" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline [m1]</text>
</g>
<g class="m-node">
<title>p0x1878600</title>
<polygon points="256,-135 222.9,-117 256,-99 289.1,-117 256,-135"/>
<text text-anchor="middle" x="256" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0x18786e8</title>
<polygon points="176,-52 122,-52 122,-48 118,-48 118,-44 122,-44 122,-24 118,-24 118,-20 122,-20 122,-16 176,-16 176,-52"/>
<polyline points="122,-48 126,-48 126,-44 122,-44 "/>
<polyline points="122,-24 126,-24 126,-20 122,-20 "/>
<text text-anchor="middle" x="149" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0x1878600&#45;&gt;p0x18786e8</title>
<path stroke-dasharray="5,2" d="M242.88,-106.07C227.21,-94.21 200.5,-73.99 179.57,-58.14"/>
<polygon points="181.66,-55.34 171.58,-52.09 177.44,-60.92 181.66,-55.34"/>
<text text-anchor="middle" x="211.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0x18787d0</title>
<polygon points="248,-52 194,-52 194,-48 190,-48 190,-44 194,-44 194,-24 190,-24 190,-20 194,-20 194,-16 248,-16 248,-52"/>
<polyline points="194,-48 198,-48 198,-44 194,-44 "/>
<polyline points="194,-24 198,-24 198,-20 194,-20 "/>
<text text-anchor="middle" x="221" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0x1878600&#45;&gt;p0x18787d0</title>
<path stroke-dasharray="5,2" d="M249.9,-101.89C245.08,-90.73 238.21,-74.83 232.38,-61.34"/>
<polygon points="235.54,-59.83 228.36,-52.04 229.11,-62.6 235.54,-59.83"/>
<text text-anchor="middle" x="243.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0x18788b8</title>
<polygon points="320,-52 266,-52 266,-48 262,-48 262,-44 266,-44 266,-24 262,-24 262,-20 266,-20 266,-16 320,-16 320,-52"/>
<polyline points="266,-48 270,-48 270,-44 266,-44 "/>
<polyline points="266,-24 270,-24 270,-20 266,-20 "/>
<text text-anchor="middle" x="293" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0x1878600&#45;&gt;p0x18788b8</title>
<path stroke-dasharray="5,2" d="M262.28,-102.26C267.35,-91.15 274.65,-75.16 280.86,-61.57"/>
<polygon points="284.17,-62.75 285.15,-52.2 277.81,-59.84 284.17,-62.75"/>
<text text-anchor="middle" x="279.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0x18789a0</title>
<polygon points="392,-52 338,-52 338,-48 334,-48 334,-44 338,-44 338,-24 334,-24 334,-20 338,-20 338,-16 392,-16 392,-52"/>
<polyline points="338,-48 342,-48 342,-44 338,-44 "/>
<polyline points="338,-24 342,-24 342,-20 338,-20 "/>
<text text-anchor="middle" x="365" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0x1878600&#45;&gt;p0x18789a0</title>
<path stroke-dasharray="5,2" d="M269.37,-106.07C285.32,-94.21 312.53,-73.99 333.86,-58.14"/>
<polygon points="336.06,-60.87 342,-52.09 331.89,-55.25 336.06,-60.87"/>
<text text-anchor="middle" x="320.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
</g>
</svg>
</div><p>In this example, we customize the data storage, <code>buffer</code>, as an one-dimensional array of 4 integers, since the pipeline structure defines only four parallel lines. Each entry of <code>buffer</code> stores stores the data being processed in the corresponding line. For example, <code>buffer[1]</code> stores the processed data at line <code>1</code>. The following figure shows the data layout of <code>buffer</code>.</p><div class="m-graph"><svg style="width: 19.900rem; height: 8.500rem;" viewBox="0.00 0.00 199.00 85.00">
<g transform="scale(1 1) rotate(0) translate(4 81)">
<title>structs</title>
<g class="m-node m-flat">
<title>struct1</title>
<polygon points="0,-0.5 0,-76.5 191,-76.5 191,-0.5 0,-0.5"/>
<text text-anchor="middle" x="95.5" y="-64.5" font-family="Helvetica,sans-Serif" font-size="10.00">buffer[0] (processes token at line 0)</text>
<polyline points="0,-57.5 191,-57.5 "/>
<text text-anchor="middle" x="95.5" y="-45.5" font-family="Helvetica,sans-Serif" font-size="10.00">buffer[1] (processes token at line 1)</text>
<polyline points="0,-38.5 191,-38.5 "/>
<text text-anchor="middle" x="95.5" y="-26.5" font-family="Helvetica,sans-Serif" font-size="10.00">buffer[2] (processes token at line 2)</text>
<polyline points="0,-19.5 191,-19.5 "/>
<text text-anchor="middle" x="95.5" y="-7.5" font-family="Helvetica,sans-Serif" font-size="10.00">buffer[3] (processes token at line 3)</text>
</g>
</g>
</svg>
</div><aside class="m-note m-info"><h4>Note</h4><p>In practice, you may need to add padding to the data type of the buffer or align it with the cacheline size to avoid false sharing. If the data type varies at different pipes, you can use <a href="https://en.cppreference.com/w/cpp/utility/variant">std::<wbr />variant</a> to store the data types in a uniform storage.</p></aside><p>For each scheduling token, you can use <a href="classtf_1_1Pipeflow.html#afee054e6a99965d4b3e36ff903227e6c" class="m-doc">tf::<wbr />Pipeflow::<wbr />line()</a> to get its line identifier and <a href="classtf_1_1Pipeflow.html#a4914c1f381a3016e98285b019cf60d6d" class="m-doc">tf::<wbr />Pipeflow::<wbr />pipe()</a> to get its pipe identifier. For example, if a scheduling token is at the third pipe of the forth line, <a href="classtf_1_1Pipeflow.html#afee054e6a99965d4b3e36ff903227e6c" class="m-doc">tf::<wbr />Pipeflow::<wbr />line()</a> will return <code>3</code> and <a href="classtf_1_1Pipeflow.html#a4914c1f381a3016e98285b019cf60d6d" class="m-doc">tf::<wbr />Pipeflow::<wbr />pipe()</a> will return <code>2</code> (index starts from 0). To stop the execution of the pipeline, you need to call <a href="classtf_1_1Pipeflow.html#a830b7f204cb87fff17e8d424918d9453" class="m-doc">tf::<wbr />Pipeflow::<wbr />stop()</a> at the first pipe. Once the stop signal has been triggered, the pipeline will stop scheduling any new tokens after the callable. As we can see from this example, <a href="classtf_1_1Pipeline.html" class="m-doc">tf::<wbr />Pipeline</a> gives you the full control to customize your application data on top of a pipeline scheduling framework.</p><aside class="m-note m-info"><h4>Note</h4><ol><li>Calling <a href="classtf_1_1Pipeflow.html#a830b7f204cb87fff17e8d424918d9453" class="m-doc">tf::<wbr />Pipeflow::<wbr />stop()</a> not at the first pipe has no effect on the pipeline scheduling.</li><li>In most cases, <a href="http://en.cppreference.com/w/cpp/thread/thread/hardware_concurrency.html" class="m-doc-external">std::<wbr />thread::<wbr />hardware_concurrency</a> is a good number for line count.</li></ol></aside><p>Our pipeline algorithm schedules tokens in a <em>circular</em> manner, with a factor of <code>num_lines</code>. That is, token <code>t</code> will be processed at line <code>t % num_lines</code>. The following snippet shows one of the possible outputs of this pipeline program:</p><pre class="m-code">pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span></pre><p>There are a total of five tokens running through three pipes. Each pipes prints its input data value, except the first pipe that prints its token identifier. Since the second pipe is a parallel pipe, the output can interleave.</p></section><section id="ConnectWithTasks"><h2><a href="#ConnectWithTasks">Connect Pipeline with Other Tasks</a></h2><p>You can connect the pipeline module task with other tasks to create a taskflow application that embeds one or multiple pipeline algorithms. We describe three common examples below:</p><ul><li><a href="#IterateAPipeline" class="m-doc">Example 1: Iterate a Pipeline</a></li><li><a href="#ConcatenateTwoPipelines" class="m-doc">Example 2: Concatenate Two Pipelines</a></li><li><a href="#DefineMultipleTaskParallelPipelines" class="m-doc">Example 3: Define Multiple Parallel Pipelines</a></li></ul><section id="IterateAPipeline"><h3><a href="#IterateAPipeline">Example 1: Iterate a Pipeline</a></h3><p>This example emulates a data streaming application that iteratively runs a stream of data through a pipeline using conditional tasking. The taskflow graph consists of one pipeline module task and one condition task. The pipeline module task processes a stream of data. The condition task decides the availability of data and reruns the pipeline when the next stream of data becomes available.<br /></p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_lines</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span><span class="w"> </span><span class="c1">// maximum parallelism of the pipeline</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w"> </span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</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="n">N</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="mi">7</span><span class="o">:</span><span class="w"> </span><span class="c1">// custom data storage</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer</span><span class="p">;</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span>
<span class="mi">10</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline consists of three pipes (serial-parallel-serial)</span>
<span class="mi">11</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">12</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">13</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">14</span><span class="o">:</span><span class="w"> </span><span class="c1">// only 5 scheduling tokens are processed</span>
<span class="mi">15</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">i</span><span class="o">++</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">16</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">17</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">18</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">19</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">20</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;stage 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="mi">21</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">();</span>
<span class="mi">22</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">23</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">24</span><span class="o">:</span>
<span class="mi">25</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">26</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">27</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;stage 1: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="mi">28</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">29</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">30</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">31</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">32</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">33</span><span class="o">:</span>
<span class="mi">34</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">35</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">36</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;stage 2: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="mi">37</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">38</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">39</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">40</span><span class="o">:</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">41</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">42</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">43</span><span class="o">:</span><span class="w"> </span>
<span class="mi">44</span><span class="o">:</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">conditional</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">&amp;</span><span class="n">N</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">i</span><span class="p">](){</span>
<span class="mi">45</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="mi">0</span><span class="p">;</span>
<span class="mi">46</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">++</span><span class="n">N</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<span class="mi">47</span><span class="o">:</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">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Rerun the pipeline</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
<span class="mi">48</span><span class="o">:</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="mi">49</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">50</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">51</span><span class="o">:</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">52</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">53</span><span class="o">:</span><span class="w"> </span><span class="p">}).</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;conditional&quot;</span><span class="p">);</span>
<span class="mi">54</span><span class="o">:</span>
<span class="mi">55</span><span class="o">:</span><span class="w"> </span><span class="c1">// build the pipeline graph using composition</span>
<span class="mi">56</span><span class="o">:</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">pipeline</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">composed_of</span><span class="p">(</span><span class="n">pl</span><span class="p">)</span>
<span class="mi">57</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="mi">58</span><span class="o">:</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">initial</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="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;initial</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">})</span>
<span class="mi">59</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;initial&quot;</span><span class="p">);</span>
<span class="mi">60</span><span class="o">:</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">stop</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="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;stop</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">})</span>
<span class="mi">61</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;stop&quot;</span><span class="p">);</span>
<span class="mi">62</span><span class="o">:</span>
<span class="mi">63</span><span class="o">:</span><span class="w"> </span><span class="c1">// specify the graph dependency</span>
<span class="mi">64</span><span class="o">:</span><span class="w"> </span><span class="n">initial</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline</span><span class="p">);</span>
<span class="mi">65</span><span class="o">:</span><span class="w"> </span><span class="n">pipeline</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">conditional</span><span class="p">);</span>
<span class="mi">66</span><span class="o">:</span><span class="w"> </span><span class="n">conditional</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline</span><span class="p">,</span><span class="w"> </span><span class="n">stop</span><span class="p">);</span>
<span class="mi">67</span><span class="o">:</span>
<span class="mi">68</span><span class="o">:</span><span class="w"> </span><span class="c1">// execute the taskflow</span>
<span class="mi">69</span><span class="o">:</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>Debrief:</p><ul><li>Lines 4-5 define the structure of the pipeline scheduling framework</li><li>Line 8 defines the data storage as an one-dimensional array (<code>num_lines</code> integers)</li><li>Line 12 defines the number of lines in the pipeline</li><li>Lines 13-23 define the first serial pipe, which will stop the pipeline scheduling when <code>i</code> is <code>5</code><br /></li><li>Lines 25-32 define the second parallel pipe</li><li>Lines 34-41 define the third serial pipe</li><li>Lines 44-53 define a condition task which returns 0 when <code>N</code> is less than <code>2</code>, otherwise returns <code>1</code></li><li>Line 45 resets variable <code>i</code></li><li>Lines 56-57 define the pipeline graph using composition</li><li>Lines 58-61 define two static tasks</li><li>Line 64-66 define the task dependency</li><li>Line 69 executes the taskflow</li></ul><p>The taskflow graph of this pipeline example is illustrated as follows:</p><div class="m-graph"><svg style="width: 45.200rem; height: 34.400rem;" viewBox="0.00 0.00 452.00 344.00">
<g transform="scale(1 1) rotate(0) translate(4 340)">
<title>Taskflow</title>
<g class="m-cluster">
<title>cluster_p0x7fff4f1276d8</title>
<polygon points="8,-8 8,-328 142,-328 142,-8 8,-8"/>
<text text-anchor="middle" x="75" y="-316" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7fff4f127590</title>
<polygon points="150,-174 150,-328 436,-328 436,-174 150,-174"/>
<text text-anchor="middle" x="293" y="-316" font-family="Helvetica,sans-Serif" font-size="10.00">m1</text>
</g>
<g class="m-node m-flat">
<title>p0xdf4c58</title>
<ellipse cx="66" cy="-283" rx="27" ry="18"/>
<text text-anchor="middle" x="66" y="-280.5" font-family="Helvetica,sans-Serif" font-size="10.00">initial</text>
</g>
<g class="m-node m-flat">
<title>p0xdf4b70</title>
<polygon points="107,-218 29,-218 25,-214 25,-182 103,-182 107,-186 107,-218"/>
<polyline points="103,-214 25,-214 "/>
<polyline points="103,-214 103,-182 "/>
<polyline points="103,-214 107,-218 "/>
<text text-anchor="middle" x="66" y="-197.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline [m1]</text>
</g>
<g class="m-edge">
<title>p0xdf4c58&#45;&gt;p0xdf4b70</title>
<path d="M66,-264.82C66,-254.19 66,-240.31 66,-228.2"/>
<polygon points="69.5,-228.15 66,-218.15 62.5,-228.15 69.5,-228.15"/>
</g>
<g class="m-node">
<title>p0xdf4a88</title>
<polygon points="75,-135 15.79,-117 75,-99 134.21,-117 75,-135"/>
<text text-anchor="middle" x="75" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">conditional</text>
</g>
<g class="m-edge">
<title>p0xdf4b70&#45;&gt;p0xdf4a88</title>
<path d="M63.02,-181.87C61.98,-173.17 61.42,-162.47 63,-153 63.55,-149.71 64.37,-146.3 65.33,-142.98"/>
<polygon points="68.68,-143.99 68.49,-133.39 62.04,-141.79 68.68,-143.99"/>
</g>
<g class="m-edge">
<title>p0xdf4a88&#45;&gt;p0xdf4b70</title>
<path stroke-dasharray="5,2" d="M73.16,-134.6C71.97,-145.25 70.41,-159.34 69.04,-171.62"/>
<polygon points="65.53,-171.5 67.91,-181.82 72.49,-172.27 65.53,-171.5"/>
<text text-anchor="middle" x="74.5" y="-156" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0xdf4d40</title>
<ellipse cx="75" cy="-34" rx="34.29" ry="18"/>
<text text-anchor="middle" x="75" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">terminal</text>
</g>
<g class="m-edge">
<title>p0xdf4a88&#45;&gt;p0xdf4d40</title>
<path stroke-dasharray="5,2" d="M75,-98.82C75,-88.19 75,-74.31 75,-62.2"/>
<polygon points="78.5,-62.15 75,-52.15 71.5,-62.15 78.5,-62.15"/>
<text text-anchor="middle" x="78.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node">
<title>p0xdf4600</title>
<polygon points="292,-301 258.9,-283 292,-265 325.1,-283 292,-301"/>
<text text-anchor="middle" x="292" y="-280.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0xdf46e8</title>
<polygon points="212,-218 158,-218 158,-214 154,-214 154,-210 158,-210 158,-190 154,-190 154,-186 158,-186 158,-182 212,-182 212,-218"/>
<polyline points="158,-214 162,-214 162,-210 158,-210 "/>
<polyline points="158,-190 162,-190 162,-186 158,-186 "/>
<text text-anchor="middle" x="185" y="-197.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0xdf4600&#45;&gt;p0xdf46e8</title>
<path stroke-dasharray="5,2" d="M278.88,-272.07C263.21,-260.21 236.5,-239.99 215.57,-224.14"/>
<polygon points="217.66,-221.34 207.58,-218.09 213.44,-226.92 217.66,-221.34"/>
<text text-anchor="middle" x="247.5" y="-239" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0xdf47d0</title>
<polygon points="284,-218 230,-218 230,-214 226,-214 226,-210 230,-210 230,-190 226,-190 226,-186 230,-186 230,-182 284,-182 284,-218"/>
<polyline points="230,-214 234,-214 234,-210 230,-210 "/>
<polyline points="230,-190 234,-190 234,-186 230,-186 "/>
<text text-anchor="middle" x="257" y="-197.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0xdf4600&#45;&gt;p0xdf47d0</title>
<path stroke-dasharray="5,2" d="M285.9,-267.89C281.08,-256.73 274.21,-240.83 268.38,-227.34"/>
<polygon points="271.54,-225.83 264.36,-218.04 265.11,-228.6 271.54,-225.83"/>
<text text-anchor="middle" x="279.5" y="-239" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0xdf48b8</title>
<polygon points="356,-218 302,-218 302,-214 298,-214 298,-210 302,-210 302,-190 298,-190 298,-186 302,-186 302,-182 356,-182 356,-218"/>
<polyline points="302,-214 306,-214 306,-210 302,-210 "/>
<polyline points="302,-190 306,-190 306,-186 302,-186 "/>
<text text-anchor="middle" x="329" y="-197.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0xdf4600&#45;&gt;p0xdf48b8</title>
<path stroke-dasharray="5,2" d="M298.28,-268.26C303.35,-257.15 310.65,-241.16 316.86,-227.57"/>
<polygon points="320.17,-228.75 321.15,-218.2 313.81,-225.84 320.17,-228.75"/>
<text text-anchor="middle" x="315.5" y="-239" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0xdf49a0</title>
<polygon points="428,-218 374,-218 374,-214 370,-214 370,-210 374,-210 374,-190 370,-190 370,-186 374,-186 374,-182 428,-182 428,-218"/>
<polyline points="374,-214 378,-214 378,-210 374,-210 "/>
<polyline points="374,-190 378,-190 378,-186 374,-186 "/>
<text text-anchor="middle" x="401" y="-197.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0xdf4600&#45;&gt;p0xdf49a0</title>
<path stroke-dasharray="5,2" d="M305.37,-272.07C321.32,-260.21 348.53,-239.99 369.86,-224.14"/>
<polygon points="372.06,-226.87 378,-218.09 367.89,-221.25 372.06,-226.87"/>
<text text-anchor="middle" x="356.5" y="-239" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
</g>
</svg>
</div><p>The following snippet shows one of the possible outputs:</p><pre class="m-code">initial
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
Rerun the pipeline
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">5</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">6</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">6</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">6</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">7</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">7</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">7</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">8</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">8</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">8</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">9</span>
stage <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">9</span>
stage <span class="m">1</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">9</span>
stage <span class="m">2</span>: input buffer<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">10</span>
stop</pre><p>The pipeline runs twice as controlled by the condition task <code>conditional</code>. The starting token in the second run of the pipeline is <code>5</code> rather than <code>0</code> because the pipeline keeps a stateful number of tokens. The last token is <code>9</code>, which means the pipeline processes in total <code>10</code> scheduling tokens. The first five tokens (token <code>0</code> to <code>4</code>) are processed in the first run, and the remaining five tokens (token <code>5</code> to <code>9</code>) are processed in the second run. In the condition task, we use <code>N</code> as a decision-making counter to process the next stream of data.</p></section><section id="ConcatenateTwoPipelines"><h3><a href="#ConcatenateTwoPipelines">Example 2: Concatenate Two Pipelines</a></h3><p>This example demonstrates two concatenated pipelines where a sequence of data tokens run synchronously from one pipeline to another pipeline. The first pipeline task precedes the second pipeline task.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span><span class="w"> </span><span class="c1">// define the maximum parallelism of the pipeline</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_lines</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w"> </span><span class="c1">// custom data storage</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">;</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">;</span>
<span class="mi">10</span><span class="o">:</span><span class="w"> </span>
<span class="mi">11</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline_1 consists of three pipes (serial-parallel-serial)</span>
<span class="mi">12</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">13</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl_1</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">14</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="p">{</span>
<span class="mi">15</span><span class="o">:</span><span class="w"> </span><span class="c1">// generate only 4 scheduling tokens</span>
<span class="mi">16</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">17</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">18</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">19</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">20</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">21</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipeline 1, pipe 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="mi">22</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">();</span>
<span class="mi">23</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">24</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">25</span><span class="o">:</span>
<span class="mi">26</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">27</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">28</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 1, pipe 1: input buffer_1[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">29</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">30</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">31</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">32</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">33</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">34</span><span class="o">:</span>
<span class="mi">35</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">36</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">37</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 1, pipe 2: input buffer_1[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">38</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">39</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">40</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">41</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">42</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">43</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">44</span><span class="o">:</span><span class="w"> </span>
<span class="mi">45</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline_2 consists of three pipes (serial-parallel-serial)</span>
<span class="mi">46</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">47</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl_2</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">48</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span>
<span class="mi">49</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="p">{</span>
<span class="mi">50</span><span class="o">:</span><span class="w"> </span><span class="c1">// generate only 4 scheduling tokens</span>
<span class="mi">51</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">52</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">53</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">54</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">55</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">56</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipeline 2, pipe 0: input value = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]);</span>
<span class="mi">57</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()];</span>
<span class="mi">58</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">59</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">60</span><span class="o">:</span>
<span class="mi">61</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">62</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">63</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 2, pipe 1: input buffer_2[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">64</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">65</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">66</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding 1</span>
<span class="mi">67</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">68</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">69</span><span class="o">:</span>
<span class="mi">70</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">71</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">72</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 2, pipe 2: input buffer_2[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">73</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">74</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">75</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding 1</span>
<span class="mi">76</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">77</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">78</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">79</span><span class="o">:</span>
<span class="mi">80</span><span class="o">:</span><span class="w"> </span><span class="c1">// build the pipeline graph using composition</span>
<span class="mi">81</span><span class="o">:</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">pipeline_1</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">composed_of</span><span class="p">(</span><span class="n">pl_1</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline_1&quot;</span><span class="p">);</span>
<span class="mi">82</span><span class="o">:</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">pipeline_2</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">composed_of</span><span class="p">(</span><span class="n">pl_2</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline_2&quot;</span><span class="p">);</span>
<span class="mi">83</span><span class="o">:</span>
<span class="mi">84</span><span class="o">:</span><span class="w"> </span><span class="c1">// specify the graph dependency</span>
<span class="mi">85</span><span class="o">:</span><span class="w"> </span><span class="n">pipeline_1</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline_2</span><span class="p">);</span>
<span class="mi">86</span><span class="o">:</span><span class="w"> </span>
<span class="mi">87</span><span class="o">:</span><span class="w"> </span><span class="c1">// execute the taskflow</span>
<span class="mi">88</span><span class="o">:</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>Debrief:</p><ul><li>Line 8 defines the data storage (<code>num_lines</code> integers) for pipeline <code>pl_1</code></li><li>Line 9 defines the data storage (<code>num_lines</code> integers) for pipeline <code>pl_2</code></li><li>Lines 14-24 define the first serial pipe in <code>pl_1</code></li><li>Lines 26-33 define the second parallel pipe in <code>pl_1</code></li><li>Lines 35-42 define the third serial pipe in <code>pl_1</code></li><li>Lines 48-59 define the first serial pipe in <code>pl_2</code> that takes the results of <code>pl_1</code> as inputs</li><li>Lines 61-68 define the second parallel pipe in <code>pl_2</code></li><li>Lines 70-77 define the third serial pipe in <code>pl_2</code></li><li>Lines 81-82 define the pipeline graphs using composition</li><li>Line 85 defines the task dependency</li><li>Line 88 runs the taskflow</li></ul><p>The taskflow graph of this pipeline example is illustrated as follows:</p><div class="m-graph"><svg style="width: 72.000rem; height: 17.800rem;" viewBox="0.00 0.00 720.00 178.00">
<g transform="scale(1 1) rotate(0) translate(4 174)">
<title>Taskflow</title>
<g class="m-cluster">
<title>cluster_p0x7ffeaf4d98d8</title>
<polygon points="8,-8 8,-162 116,-162 116,-8 8,-8"/>
<text text-anchor="middle" x="62" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7ffeaf4d9510</title>
<polygon points="124,-8 124,-162 410,-162 410,-8 124,-8"/>
<text text-anchor="middle" x="267" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">m2</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7ffeaf4d95b0</title>
<polygon points="418,-8 418,-162 704,-162 704,-8 418,-8"/>
<text text-anchor="middle" x="561" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">m1</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4f10</title>
<polygon points="108.5,-135 19.5,-135 15.5,-131 15.5,-99 104.5,-99 108.5,-103 108.5,-135"/>
<polyline points="104.5,-131 15.5,-131 "/>
<polyline points="104.5,-131 104.5,-99 "/>
<polyline points="104.5,-131 108.5,-135 "/>
<text text-anchor="middle" x="62" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline_1 [m1]</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4ff8</title>
<polygon points="108.5,-52 19.5,-52 15.5,-48 15.5,-16 104.5,-16 108.5,-20 108.5,-52"/>
<polyline points="104.5,-48 15.5,-48 "/>
<polyline points="104.5,-48 104.5,-16 "/>
<polyline points="104.5,-48 108.5,-52 "/>
<text text-anchor="middle" x="62" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline_2 [m2]</text>
</g>
<g class="m-edge">
<title>p0x1da4f10&#45;&gt;p0x1da4ff8</title>
<path d="M62,-98.82C62,-88.19 62,-74.31 62,-62.2"/>
<polygon points="65.5,-62.15 62,-52.15 58.5,-62.15 65.5,-62.15"/>
</g>
<g class="m-node">
<title>p0x1da4a88</title>
<polygon points="266,-135 232.9,-117 266,-99 299.1,-117 266,-135"/>
<text text-anchor="middle" x="266" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4b70</title>
<polygon points="186,-52 132,-52 132,-48 128,-48 128,-44 132,-44 132,-24 128,-24 128,-20 132,-20 132,-16 186,-16 186,-52"/>
<polyline points="132,-48 136,-48 136,-44 132,-44 "/>
<polyline points="132,-24 136,-24 136,-20 132,-20 "/>
<text text-anchor="middle" x="159" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0x1da4a88&#45;&gt;p0x1da4b70</title>
<path stroke-dasharray="5,2" d="M252.88,-106.07C237.21,-94.21 210.5,-73.99 189.57,-58.14"/>
<polygon points="191.66,-55.34 181.58,-52.09 187.44,-60.92 191.66,-55.34"/>
<text text-anchor="middle" x="221.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4c58</title>
<polygon points="258,-52 204,-52 204,-48 200,-48 200,-44 204,-44 204,-24 200,-24 200,-20 204,-20 204,-16 258,-16 258,-52"/>
<polyline points="204,-48 208,-48 208,-44 204,-44 "/>
<polyline points="204,-24 208,-24 208,-20 204,-20 "/>
<text text-anchor="middle" x="231" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0x1da4a88&#45;&gt;p0x1da4c58</title>
<path stroke-dasharray="5,2" d="M259.9,-101.89C255.08,-90.73 248.21,-74.83 242.38,-61.34"/>
<polygon points="245.54,-59.83 238.36,-52.04 239.11,-62.6 245.54,-59.83"/>
<text text-anchor="middle" x="253.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4d40</title>
<polygon points="330,-52 276,-52 276,-48 272,-48 272,-44 276,-44 276,-24 272,-24 272,-20 276,-20 276,-16 330,-16 330,-52"/>
<polyline points="276,-48 280,-48 280,-44 276,-44 "/>
<polyline points="276,-24 280,-24 280,-20 276,-20 "/>
<text text-anchor="middle" x="303" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0x1da4a88&#45;&gt;p0x1da4d40</title>
<path stroke-dasharray="5,2" d="M272.28,-102.26C277.35,-91.15 284.65,-75.16 290.86,-61.57"/>
<polygon points="294.17,-62.75 295.15,-52.2 287.81,-59.84 294.17,-62.75"/>
<text text-anchor="middle" x="289.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0x1da4e28</title>
<polygon points="402,-52 348,-52 348,-48 344,-48 344,-44 348,-44 348,-24 344,-24 344,-20 348,-20 348,-16 402,-16 402,-52"/>
<polyline points="348,-48 352,-48 352,-44 348,-44 "/>
<polyline points="348,-24 352,-24 352,-20 348,-20 "/>
<text text-anchor="middle" x="375" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0x1da4a88&#45;&gt;p0x1da4e28</title>
<path stroke-dasharray="5,2" d="M279.37,-106.07C295.32,-94.21 322.53,-73.99 343.86,-58.14"/>
<polygon points="346.06,-60.87 352,-52.09 341.89,-55.25 346.06,-60.87"/>
<text text-anchor="middle" x="330.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
<g class="m-node">
<title>p0x1da4600</title>
<polygon points="560,-135 526.9,-117 560,-99 593.1,-117 560,-135"/>
<text text-anchor="middle" x="560" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0x1da46e8</title>
<polygon points="480,-52 426,-52 426,-48 422,-48 422,-44 426,-44 426,-24 422,-24 422,-20 426,-20 426,-16 480,-16 480,-52"/>
<polyline points="426,-48 430,-48 430,-44 426,-44 "/>
<polyline points="426,-24 430,-24 430,-20 426,-20 "/>
<text text-anchor="middle" x="453" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0x1da4600&#45;&gt;p0x1da46e8</title>
<path stroke-dasharray="5,2" d="M546.88,-106.07C531.21,-94.21 504.5,-73.99 483.57,-58.14"/>
<polygon points="485.66,-55.34 475.58,-52.09 481.44,-60.92 485.66,-55.34"/>
<text text-anchor="middle" x="515.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0x1da47d0</title>
<polygon points="552,-52 498,-52 498,-48 494,-48 494,-44 498,-44 498,-24 494,-24 494,-20 498,-20 498,-16 552,-16 552,-52"/>
<polyline points="498,-48 502,-48 502,-44 498,-44 "/>
<polyline points="498,-24 502,-24 502,-20 498,-20 "/>
<text text-anchor="middle" x="525" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0x1da4600&#45;&gt;p0x1da47d0</title>
<path stroke-dasharray="5,2" d="M553.9,-101.89C549.08,-90.73 542.21,-74.83 536.38,-61.34"/>
<polygon points="539.54,-59.83 532.36,-52.04 533.11,-62.6 539.54,-59.83"/>
<text text-anchor="middle" x="547.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0x1da48b8</title>
<polygon points="624,-52 570,-52 570,-48 566,-48 566,-44 570,-44 570,-24 566,-24 566,-20 570,-20 570,-16 624,-16 624,-52"/>
<polyline points="570,-48 574,-48 574,-44 570,-44 "/>
<polyline points="570,-24 574,-24 574,-20 570,-20 "/>
<text text-anchor="middle" x="597" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0x1da4600&#45;&gt;p0x1da48b8</title>
<path stroke-dasharray="5,2" d="M566.28,-102.26C571.35,-91.15 578.65,-75.16 584.86,-61.57"/>
<polygon points="588.17,-62.75 589.15,-52.2 581.81,-59.84 588.17,-62.75"/>
<text text-anchor="middle" x="583.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0x1da49a0</title>
<polygon points="696,-52 642,-52 642,-48 638,-48 638,-44 642,-44 642,-24 638,-24 638,-20 642,-20 642,-16 696,-16 696,-52"/>
<polyline points="642,-48 646,-48 646,-44 642,-44 "/>
<polyline points="642,-24 646,-24 646,-20 642,-20 "/>
<text text-anchor="middle" x="669" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0x1da4600&#45;&gt;p0x1da49a0</title>
<path stroke-dasharray="5,2" d="M573.37,-106.07C589.32,-94.21 616.53,-73.99 637.86,-58.14"/>
<polygon points="640.06,-60.87 646,-52.09 635.89,-55.25 640.06,-60.87"/>
<text text-anchor="middle" x="624.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
</g>
</svg>
</div><p>The following snippet shows one of the possible outputs:</p><pre class="m-code">pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input <span class="nv">value</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">2</span>, pipe <span class="m">3</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input <span class="nv">value</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">3</span>: input buffer_2<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input <span class="nv">value</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">3</span>: input buffer_2<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input <span class="nv">value</span> <span class="o">=</span> <span class="m">5</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
pipeline <span class="m">2</span>, pipe <span class="m">3</span>: input buffer_2<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">6</span></pre><p>The output of pipelines <code>pl_1</code> and <code>pl_2</code> can be different from run to run because their second pipes are both parallel types. Due to the task dependency between <code>pipeline_1</code> and <code>pipeline_2</code>, the output of <code>pl_1</code> precedes the output of <code>pl_2</code>.</p></section><section id="DefineMultipleTaskParallelPipelines"><h3><a href="#DefineMultipleTaskParallelPipelines">Example 3: Define Multiple Parallel Pipelines</a></h3><p>This example creates two independent pipelines that run in parallel on different data sets.</p><pre class="m-code"><span class="w"> </span><span class="mi">1</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="mi">2</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="w"> </span><span class="mi">3</span><span class="o">:</span>
<span class="w"> </span><span class="mi">4</span><span class="o">:</span><span class="w"> </span><span class="c1">// define the maximum parallelism of the pipeline</span>
<span class="w"> </span><span class="mi">5</span><span class="o">:</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_lines</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span>
<span class="w"> </span><span class="mi">6</span><span class="o">:</span>
<span class="w"> </span><span class="mi">7</span><span class="o">:</span><span class="w"> </span><span class="c1">// custom data storage</span>
<span class="w"> </span><span class="mi">8</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">;</span>
<span class="w"> </span><span class="mi">9</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">;</span>
<span class="mi">10</span><span class="o">:</span><span class="w"> </span>
<span class="mi">11</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline_1 consists of three pipes (serial-parallel-serial)</span>
<span class="mi">12</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">13</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl_1</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">14</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="p">{</span>
<span class="mi">15</span><span class="o">:</span><span class="w"> </span><span class="c1">// generate only 5 scheduling tokens</span>
<span class="mi">16</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">17</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">18</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">19</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">20</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">21</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipeline 1, pipe 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="mi">22</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">();</span>
<span class="mi">23</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">24</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">25</span><span class="o">:</span>
<span class="mi">26</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">27</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">28</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 1, pipe 1: input buffer_1[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">29</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">30</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">31</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">32</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">33</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">34</span><span class="o">:</span>
<span class="mi">35</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_1</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">36</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">37</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 1, pipe 2: input buffer_1[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">38</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">39</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">40</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="mi">41</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_1</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="mi">42</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">43</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">44</span><span class="o">:</span><span class="w"> </span>
<span class="mi">45</span><span class="o">:</span><span class="w"> </span><span class="c1">// the pipeline_2 consists of three pipes (serial-parallel-serial)</span>
<span class="mi">46</span><span class="o">:</span><span class="w"> </span><span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="mi">47</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="n">pl_2</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="mi">48</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="p">{</span>
<span class="mi">49</span><span class="o">:</span><span class="w"> </span><span class="c1">// generate only 2 scheduling tokens</span>
<span class="mi">50</span><span class="o">:</span><span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">51</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="mi">52</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">53</span><span class="o">:</span><span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="mi">54</span><span class="o">:</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="mi">55</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipeline 2, pipe 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="mi">56</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;pipeline&quot;</span><span class="p">;</span>
<span class="mi">57</span><span class="o">:</span><span class="w"> </span><span class="p">}</span>
<span class="mi">58</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">59</span><span class="o">:</span>
<span class="mi">60</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">61</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">62</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 2, pipe 1: input buffer_2[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">63</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">64</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">65</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by concatenating &quot;_&quot;</span>
<span class="mi">66</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()];</span>
<span class="mi">67</span><span class="o">:</span><span class="w"> </span><span class="p">}},</span>
<span class="mi">68</span><span class="o">:</span>
<span class="mi">69</span><span class="o">:</span><span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer_2</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="mi">70</span><span class="o">:</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="mi">71</span><span class="o">:</span><span class="w"> </span><span class="s">&quot;pipeline 2, pipe 2: input buffer_2[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span>
<span class="mi">72</span><span class="o">:</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="mi">73</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">74</span><span class="o">:</span><span class="w"> </span><span class="c1">// propagate the previous result to this pipe by concatenating &quot;2&quot;</span>
<span class="mi">75</span><span class="o">:</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer_2</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()];</span>
<span class="mi">76</span><span class="o">:</span><span class="w"> </span><span class="p">}}</span>
<span class="mi">77</span><span class="o">:</span><span class="w"> </span><span class="p">);</span>
<span class="mi">78</span><span class="o">:</span>
<span class="mi">79</span><span class="o">:</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">pipeline_1</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">composed_of</span><span class="p">(</span><span class="n">pl_1</span><span class="p">)</span>
<span class="mi">80</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline_1&quot;</span><span class="p">);</span>
<span class="mi">81</span><span class="o">:</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">pipeline_2</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">composed_of</span><span class="p">(</span><span class="n">pl_2</span><span class="p">)</span>
<span class="mi">82</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline_2&quot;</span><span class="p">);</span>
<span class="mi">83</span><span class="o">:</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">initial</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="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;initial&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">})</span>
<span class="mi">84</span><span class="o">:</span><span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;initial&quot;</span><span class="p">);</span>
<span class="mi">85</span><span class="o">:</span>
<span class="mi">86</span><span class="o">:</span><span class="w"> </span><span class="n">initial</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline_1</span><span class="p">,</span><span class="w"> </span><span class="n">pipeline_2</span><span class="p">);</span>
<span class="mi">87</span><span class="o">:</span><span class="w"> </span>
<span class="mi">88</span><span class="o">:</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>Debrief:</p><ul><li>Line 8 defines the data storage (<code>num_lines</code> integers) for pipeline <code>pl_1</code></li><li>Line 9 defines the data storage (<code>num_lines</code> integers) for pipeline <code>pl_2</code></li><li>Lines 14-24 define the first serial pipe in <code>pl_1</code></li><li>Lines 26-33 define the second parallel pipe in <code>pl_1</code></li><li>Lines 35-42 define the third serial pipe in <code>pl_1</code></li><li>Lines 48-58 define the first serial pipe in <code>pl_2</code></li><li>Lines 60-67 define the second parallel pipe in <code>pl_2</code></li><li>Lines 69-76 define the third serial pipe in <code>pl_2</code></li><li>Lines 79-82 define the pipeline graphs using composition</li><li>Lines 83-84 define a static task.</li><li>Line 86 defines the task dependency</li><li>Line 88 runs the taskflow</li></ul><p>The taskflow graph of this pipeline example is illustrated as follows:</p><div class="m-graph"><svg style="width: 83.100rem; height: 17.800rem;" viewBox="0.00 0.00 831.00 178.00">
<g transform="scale(1 1) rotate(0) translate(4 174)">
<title>Taskflow</title>
<g class="m-cluster">
<title>cluster_p0x7ffe35bde158</title>
<polygon points="8,-8 8,-162 227,-162 227,-8 8,-8"/>
<text text-anchor="middle" x="117.5" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7ffe35bddd80</title>
<polygon points="235,-8 235,-162 521,-162 521,-8 235,-8"/>
<text text-anchor="middle" x="378" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">m2</text>
</g>
<g class="m-cluster">
<title>cluster_p0x7ffe35bdde20</title>
<polygon points="529,-8 529,-162 815,-162 815,-8 529,-8"/>
<text text-anchor="middle" x="672" y="-150" font-family="Helvetica,sans-Serif" font-size="10.00">m1</text>
</g>
<g class="m-node m-flat">
<title>p0x131af10</title>
<polygon points="108.5,-52 19.5,-52 15.5,-48 15.5,-16 104.5,-16 108.5,-20 108.5,-52"/>
<polyline points="104.5,-48 15.5,-48 "/>
<polyline points="104.5,-48 104.5,-16 "/>
<polyline points="104.5,-48 108.5,-52 "/>
<text text-anchor="middle" x="62" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline_1 [m1]</text>
</g>
<g class="m-node m-flat">
<title>p0x131aff8</title>
<polygon points="219.5,-52 130.5,-52 126.5,-48 126.5,-16 215.5,-16 219.5,-20 219.5,-52"/>
<polyline points="215.5,-48 126.5,-48 "/>
<polyline points="215.5,-48 215.5,-16 "/>
<polyline points="215.5,-48 219.5,-52 "/>
<text text-anchor="middle" x="173" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">pipeline_2 [m2]</text>
</g>
<g class="m-node m-flat">
<title>p0x131b0e0</title>
<ellipse cx="118" cy="-117" rx="27" ry="18"/>
<text text-anchor="middle" x="118" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">initial</text>
</g>
<g class="m-edge">
<title>p0x131b0e0&#45;&gt;p0x131af10</title>
<path d="M107.2,-100.38C99.46,-89.18 88.84,-73.82 79.84,-60.81"/>
<polygon points="82.49,-58.49 73.93,-52.25 76.74,-62.47 82.49,-58.49"/>
</g>
<g class="m-edge">
<title>p0x131b0e0&#45;&gt;p0x131aff8</title>
<path d="M128.6,-100.38C136.21,-89.18 146.64,-73.82 155.48,-60.81"/>
<polygon points="158.56,-62.49 161.29,-52.25 152.77,-58.56 158.56,-62.49"/>
</g>
<g class="m-node">
<title>p0x131aa88</title>
<polygon points="377,-135 343.9,-117 377,-99 410.1,-117 377,-135"/>
<text text-anchor="middle" x="377" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0x131ab70</title>
<polygon points="297,-52 243,-52 243,-48 239,-48 239,-44 243,-44 243,-24 239,-24 239,-20 243,-20 243,-16 297,-16 297,-52"/>
<polyline points="243,-48 247,-48 247,-44 243,-44 "/>
<polyline points="243,-24 247,-24 247,-20 243,-20 "/>
<text text-anchor="middle" x="270" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0x131aa88&#45;&gt;p0x131ab70</title>
<path stroke-dasharray="5,2" d="M363.88,-106.07C348.21,-94.21 321.5,-73.99 300.57,-58.14"/>
<polygon points="302.66,-55.34 292.58,-52.09 298.44,-60.92 302.66,-55.34"/>
<text text-anchor="middle" x="332.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0x131ac58</title>
<polygon points="369,-52 315,-52 315,-48 311,-48 311,-44 315,-44 315,-24 311,-24 311,-20 315,-20 315,-16 369,-16 369,-52"/>
<polyline points="315,-48 319,-48 319,-44 315,-44 "/>
<polyline points="315,-24 319,-24 319,-20 315,-20 "/>
<text text-anchor="middle" x="342" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0x131aa88&#45;&gt;p0x131ac58</title>
<path stroke-dasharray="5,2" d="M370.9,-101.89C366.08,-90.73 359.21,-74.83 353.38,-61.34"/>
<polygon points="356.54,-59.83 349.36,-52.04 350.11,-62.6 356.54,-59.83"/>
<text text-anchor="middle" x="364.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0x131ad40</title>
<polygon points="441,-52 387,-52 387,-48 383,-48 383,-44 387,-44 387,-24 383,-24 383,-20 387,-20 387,-16 441,-16 441,-52"/>
<polyline points="387,-48 391,-48 391,-44 387,-44 "/>
<polyline points="387,-24 391,-24 391,-20 387,-20 "/>
<text text-anchor="middle" x="414" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0x131aa88&#45;&gt;p0x131ad40</title>
<path stroke-dasharray="5,2" d="M383.28,-102.26C388.35,-91.15 395.65,-75.16 401.86,-61.57"/>
<polygon points="405.17,-62.75 406.15,-52.2 398.81,-59.84 405.17,-62.75"/>
<text text-anchor="middle" x="400.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0x131ae28</title>
<polygon points="513,-52 459,-52 459,-48 455,-48 455,-44 459,-44 459,-24 455,-24 455,-20 459,-20 459,-16 513,-16 513,-52"/>
<polyline points="459,-48 463,-48 463,-44 459,-44 "/>
<polyline points="459,-24 463,-24 463,-20 459,-20 "/>
<text text-anchor="middle" x="486" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0x131aa88&#45;&gt;p0x131ae28</title>
<path stroke-dasharray="5,2" d="M390.37,-106.07C406.32,-94.21 433.53,-73.99 454.86,-58.14"/>
<polygon points="457.06,-60.87 463,-52.09 452.89,-55.25 457.06,-60.87"/>
<text text-anchor="middle" x="441.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
<g class="m-node">
<title>p0x131a600</title>
<polygon points="671,-135 637.9,-117 671,-99 704.1,-117 671,-135"/>
<text text-anchor="middle" x="671" y="-114.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
</g>
<g class="m-node m-flat">
<title>p0x131a6e8</title>
<polygon points="591,-52 537,-52 537,-48 533,-48 533,-44 537,-44 537,-24 533,-24 533,-20 537,-20 537,-16 591,-16 591,-52"/>
<polyline points="537,-48 541,-48 541,-44 537,-44 "/>
<polyline points="537,-24 541,-24 541,-20 537,-20 "/>
<text text-anchor="middle" x="564" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;0</text>
</g>
<g class="m-edge">
<title>p0x131a600&#45;&gt;p0x131a6e8</title>
<path stroke-dasharray="5,2" d="M657.88,-106.07C642.21,-94.21 615.5,-73.99 594.57,-58.14"/>
<polygon points="596.66,-55.34 586.58,-52.09 592.44,-60.92 596.66,-55.34"/>
<text text-anchor="middle" x="626.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
</g>
<g class="m-node m-flat">
<title>p0x131a7d0</title>
<polygon points="663,-52 609,-52 609,-48 605,-48 605,-44 609,-44 609,-24 605,-24 605,-20 609,-20 609,-16 663,-16 663,-52"/>
<polyline points="609,-48 613,-48 613,-44 609,-44 "/>
<polyline points="609,-24 613,-24 613,-20 609,-20 "/>
<text text-anchor="middle" x="636" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;1</text>
</g>
<g class="m-edge">
<title>p0x131a600&#45;&gt;p0x131a7d0</title>
<path stroke-dasharray="5,2" d="M664.9,-101.89C660.08,-90.73 653.21,-74.83 647.38,-61.34"/>
<polygon points="650.54,-59.83 643.36,-52.04 644.11,-62.6 650.54,-59.83"/>
<text text-anchor="middle" x="658.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
</g>
<g class="m-node m-flat">
<title>p0x131a8b8</title>
<polygon points="735,-52 681,-52 681,-48 677,-48 677,-44 681,-44 681,-24 677,-24 677,-20 681,-20 681,-16 735,-16 735,-52"/>
<polyline points="681,-48 685,-48 685,-44 681,-44 "/>
<polyline points="681,-24 685,-24 685,-20 681,-20 "/>
<text text-anchor="middle" x="708" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;2</text>
</g>
<g class="m-edge">
<title>p0x131a600&#45;&gt;p0x131a8b8</title>
<path stroke-dasharray="5,2" d="M677.28,-102.26C682.35,-91.15 689.65,-75.16 695.86,-61.57"/>
<polygon points="699.17,-62.75 700.15,-52.2 692.81,-59.84 699.17,-62.75"/>
<text text-anchor="middle" x="694.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">2</text>
</g>
<g class="m-node m-flat">
<title>p0x131a9a0</title>
<polygon points="807,-52 753,-52 753,-48 749,-48 749,-44 753,-44 753,-24 749,-24 749,-20 753,-20 753,-16 807,-16 807,-52"/>
<polyline points="753,-48 757,-48 757,-44 753,-44 "/>
<polyline points="753,-24 757,-24 757,-20 753,-20 "/>
<text text-anchor="middle" x="780" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">rt&#45;3</text>
</g>
<g class="m-edge">
<title>p0x131a600&#45;&gt;p0x131a9a0</title>
<path stroke-dasharray="5,2" d="M684.37,-106.07C700.32,-94.21 727.53,-73.99 748.86,-58.14"/>
<polygon points="751.06,-60.87 757,-52.09 746.89,-55.25 751.06,-60.87"/>
<text text-anchor="middle" x="735.5" y="-73" font-family="Helvetica,sans-Serif" font-size="10.00">3</text>
</g>
</g>
</svg>
</div><p>The following snippet shows one of the possible outputs:</p><pre class="m-code">initial
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">1</span>, pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input buffer_2<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input buffer_2<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input buffer_2<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input buffer_2<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">1</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">2</span>, pipe <span class="m">2</span>: input buffer_2<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipeline <span class="m">1</span>, pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span></pre><p>Because pipeline <code>pl_1</code> and pipeline <code>pl_2</code> are running in parallel, their outputs may interleave.</p></section></section><section id="ResetPipeline"><h2><a href="#ResetPipeline">Reset a Pipeline</a></h2><p>Our pipeline scheduling framework keeps a <em>stateful</em> number of scheduled tokens at each submitted run. You can reset the pipeline to the initial state using <a href="classtf_1_1Pipeline.html#a311d874b98de6f0def8a7d869e8d15bd" class="m-doc">tf::<wbr />Pipeline::<wbr />reset()</a>, where the number of scheduled tokens will start from zero in the next run. Borrowed from <a href="#IterateAPipeline" class="m-doc">Example 1: Iterate a Pipeline</a>, the program below resets the pipeline at the second iteration (inside the condition task) so the scheduling token will start from zero in the next run.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="nf">taskflow</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="n">executor</span><span class="p">;</span>
<span class="c1">// define the maximum parallelism of the pipeline</span>
<span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_lines</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">;</span>
<span class="c1">// custom data storage</span>
<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="n">num_lines</span><span class="o">&gt;</span><span class="w"> </span><span class="n">buffer</span><span class="p">;</span>
<span class="c1">// the pipeline consists of three pipes (serial-parallel-serial)</span>
<span class="c1">// and up to four concurrent scheduling tokens</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Pipeline</span><span class="w"> </span><span class="nf">pl</span><span class="p">(</span><span class="n">num_lines</span><span class="p">,</span>
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="k">mutable</span><span class="p">{</span>
<span class="w"> </span><span class="c1">// generate only 5 scheduling tokens</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">stop</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="c1">// save the result of this pipe into the buffer</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;pipe 0: input token = %zu</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</span><span class="p">());</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">token</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="n">tf</span><span class="o">::</span><span class="n">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">PARALLEL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="w"> </span><span class="s">&quot;pipe 1: input buffer_1[%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</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">Pipe</span><span class="p">{</span><span class="n">tf</span><span class="o">::</span><span class="n">PipeType</span><span class="o">::</span><span class="n">SERIAL</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&amp;</span><span class="w"> </span><span class="n">pf</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span>
<span class="w"> </span><span class="s">&quot;pipe 2: input buffer[%zu][%zu] = %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="c1">// propagate the previous result to this pipe by adding one</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="n">pf</span><span class="p">.</span><span class="n">line</span><span class="p">()]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}}</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">conditional</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">&amp;</span><span class="p">](){</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">++</span><span class="n">N</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pl</span><span class="p">.</span><span class="n">reset</span><span class="p">();</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">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;Rerun the pipeline</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}).</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;conditional&quot;</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">pipeline</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">composed_of</span><span class="p">(</span><span class="n">pl</span><span class="p">)</span>
<span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;pipeline&quot;</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">initial</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="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;initial&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">})</span>
<span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;initial&quot;</span><span class="p">);</span>
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">stop</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="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;stop&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">})</span>
<span class="w"> </span><span class="p">.</span><span class="n">name</span><span class="p">(</span><span class="s">&quot;stop&quot;</span><span class="p">);</span>
<span class="n">initial</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline</span><span class="p">);</span>
<span class="n">pipeline</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">conditional</span><span class="p">);</span>
<span class="n">conditional</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">pipeline</span><span class="p">,</span><span class="w"> </span><span class="n">stop</span><span class="p">);</span>
<span class="w"> </span>
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span></pre><p>The following snippet shows one of the possible outputs:</p><pre class="m-code">initial
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
Rerun the pipeline
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">0</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">1</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">1</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">2</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">2</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">3</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">3</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">0</span>: input <span class="nv">token</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">1</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">4</span>
pipe <span class="m">2</span>: input buffer_1<span class="o">[</span><span class="m">0</span><span class="o">]</span> <span class="o">=</span> <span class="m">5</span>
stop</pre><p>The output can be different from run to run, since the second pipe is a parallel type. At the second iteration from the condition task, we reset the pipeline so the token identifier starts from <code>0</code> rather than <code>5</code>.</p></section><section id="TaskParallelPipelineLearnMore"><h2><a href="#TaskParallelPipelineLearnMore">Learn More about Taskflow Pipeline</a></h2><p>Visit the following pages to learn more about pipeline:</p><ul><li><a href="TaskParallelScalablePipeline.html" class="m-doc">Task-parallel Scalable Pipeline</a></li><li><a href="DataParallelPipeline.html" class="m-doc">Data-parallel Pipeline</a></li><li><a href="TextProcessingPipeline.html" class="m-doc">Text Processing Pipeline</a></li><li><a href="GraphProcessingPipeline.html" class="m-doc">Graph Processing Pipeline</a></li><li><a href="TaskflowProcessingPipeline.html" class="m-doc">Taskflow Processing Pipeline</a></li></ul></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">&hellip;</div>
</div>
<div class="m-doc-search-content">
<form>
<input type="search" name="q" id="search-input" placeholder="Loading &hellip;" 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">&darr;</span>
/ <span class="m-label m-dim">&uarr;</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&ndash;2024.<br />Generated by <a href="https://doxygen.org/">Doxygen</a> 1.9.1 and <a href="https://mcss.mosra.cz/">m.css</a>.</p>
</div>
</div>
</div>
</nav></footer>
</body>
</html>