606 lines
71 KiB
HTML
606 lines
71 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Modern C++ Parallel Task Programming | 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>
|
|
Modern C++ Parallel Task Programming
|
|
</h1>
|
|
<nav class="m-block m-default">
|
|
<h3>Contents</h3>
|
|
<ul>
|
|
<li><a href="#ASimpleFirstProgram">Start Your First Taskflow Program</a></li>
|
|
<li><a href="#QuickStartCreateASubflowGraph">Create a Subflow Graph</a></li>
|
|
<li><a href="#QuickStartIntegrateControlFlowIntoATaskGraph">Integrate Control Flow into a Task Graph</a></li>
|
|
<li><a href="#QuickStartOffloadTasksToGPU">Offload Tasks to a GPU</a></li>
|
|
<li><a href="#QuickStartComposeTaskGraphs">Compose Task Graphs</a></li>
|
|
<li><a href="#QuickStartLaunchAsyncTasks">Launch Asynchronous Tasks</a></li>
|
|
<li><a href="#QuickStartRunATaskflowThroughAnExecution">Run a Taskflow through an Executor</a></li>
|
|
<li><a href="#QuickStartLeverageStandardParallelAlgorithms">Leverage Standard Parallel Algorithms</a></li>
|
|
<li><a href="#QuickStartVisualizeATaskflow">Visualize Taskflow Graphs</a></li>
|
|
<li><a href="#SupportedCompilers">Supported Compilers</a></li>
|
|
<li><a href="#QuickStartGetInvolved">Get Involved</a></li>
|
|
<li><a href="#License">License</a></li>
|
|
</ul>
|
|
</nav>
|
|
<p>Taskflow helps you quickly write parallel and heterogeneous task programs with <em>high performance</em> and simultaneous <em>high productivity</em>. It is faster, more expressive, fewer lines of code, and easier for drop-in integration than many of existing task programming libraries. The source code is available in our <a href="https://github.com/taskflow/">Project GitHub</a>.</p><section id="ASimpleFirstProgram"><h2><a href="#ASimpleFirstProgram">Start Your First Taskflow Program</a></h2><p>The following program (<code>simple.cpp</code>) creates four tasks <code>A</code>, <code>B</code>, <code>C</code>, and <code>D</code>, where <code>A</code> runs before <code>B</code> and <code>C</code>, and <code>D</code> runs after <code>B</code> and <code>C</code>. When <code>A</code> finishes, <code>B</code> and <code>C</code> can run in parallel.</p><div class="m-graph"><svg style="width: 24.200rem; height: 9.800rem;" viewBox="0.00 0.00 242.00 98.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 94)">
|
|
<title>G</title>
|
|
<g class="m-node m-flat">
|
|
<title>A</title>
|
|
<ellipse cx="27" cy="-45" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="27" y="-42.5" font-family="Helvetica,sans-Serif" font-size="10.00">A</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>B</title>
|
|
<ellipse cx="117" cy="-72" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="117" y="-69.5" font-family="Helvetica,sans-Serif" font-size="10.00">B</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>A->B</title>
|
|
<path d="M52.05,-52.38C61.44,-55.26 72.36,-58.61 82.5,-61.72"/>
|
|
<polygon points="81.7,-65.14 92.29,-64.72 83.75,-58.45 81.7,-65.14"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>C</title>
|
|
<ellipse cx="117" cy="-18" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="117" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">C</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>A->C</title>
|
|
<path d="M52.05,-37.62C61.44,-34.74 72.36,-31.39 82.5,-28.28"/>
|
|
<polygon points="83.75,-31.55 92.29,-25.28 81.7,-24.86 83.75,-31.55"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>D</title>
|
|
<ellipse cx="207" cy="-45" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="207" y="-42.5" font-family="Helvetica,sans-Serif" font-size="10.00">D</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>B->D</title>
|
|
<path d="M142.05,-64.62C151.44,-61.74 162.36,-58.39 172.5,-55.28"/>
|
|
<polygon points="173.75,-58.55 182.29,-52.28 171.7,-51.86 173.75,-58.55"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>C->D</title>
|
|
<path d="M142.05,-25.38C151.44,-28.26 162.36,-31.61 172.5,-34.72"/>
|
|
<polygon points="171.7,-38.14 182.29,-37.72 173.75,-31.45 171.7,-38.14"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div><pre class="m-code"><span class="cp">#include</span><span class="w"> </span><span class="cpf"><taskflow/taskflow.hpp></span><span class="c1"> // Taskflow is header-only</span>
|
|
|
|
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(){</span>
|
|
<span class="w"> </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="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="k">auto</span><span class="w"> </span><span class="p">[</span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">D</span><span class="p">]</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="c1">// create four tasks</span>
|
|
<span class="w"> </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">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"TaskA</span><span class="se">\n</span><span class="s">"</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="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"TaskB</span><span class="se">\n</span><span class="s">"</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="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"TaskC</span><span class="se">\n</span><span class="s">"</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="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"TaskD</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="p">);</span><span class="w"> </span>
|
|
<span class="w"> </span>
|
|
<span class="w"> </span><span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">);</span><span class="w"> </span><span class="c1">// A runs before B and C</span>
|
|
<span class="w"> </span><span class="n">D</span><span class="p">.</span><span class="n">succeed</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">);</span><span class="w"> </span><span class="c1">// D runs after B and C</span>
|
|
<span class="w"> </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><span class="w"> </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="p">}</span></pre><p>Taskflow is <em>header-only</em> and there is no wrangle with installation. To compile the program, clone the Taskflow project and tell the compiler to include the headers under <code>taskflow/</code>.</p><pre class="m-console"><span class="go">~$ git clone https://github.com/taskflow/taskflow.git # clone it only once</span>
|
|
<span class="go">~$ g++ -std=c++20 simple.cpp -I taskflow/ -O2 -pthread -o simple</span>
|
|
<span class="go">~$ ./simple</span>
|
|
<span class="go">TaskA</span>
|
|
<span class="go">TaskC </span>
|
|
<span class="go">TaskB </span>
|
|
<span class="go">TaskD</span></pre><p>Taskflow comes with a built-in profiler, <a href="https://taskflow.github.io/tfprof/">Taskflow Profiler</a>, for you to profile and visualize taskflow programs in an easy-to-use web-based interface.</p><img class="m-image" src="tfprof.png" alt="Image" /><pre class="m-console"><span class="gp"># </span>run the program with the environment variable TF_ENABLE_PROFILER enabled
|
|
<span class="go">~$ TF_ENABLE_PROFILER=simple.json ./simple</span>
|
|
<span class="go">~$ cat simple.json</span>
|
|
<span class="go">[</span>
|
|
<span class="go">{"executor":"0","data":[{"worker":0,"level":0,"data":[{"span":[172,186],"name":"0_0","type":"static"},{"span":[187,189],"name":"0_1","type":"static"}]},{"worker":2,"level":0,"data":[{"span":[93,164],"name":"2_0","type":"static"},{"span":[170,179],"name":"2_1","type":"static"}]}]}</span>
|
|
<span class="go">]</span>
|
|
<span class="gp"># </span>paste the profiling json data to https://taskflow.github.io/tfprof/</pre></section><section id="QuickStartCreateASubflowGraph"><h2><a href="#QuickStartCreateASubflowGraph">Create a Subflow Graph</a></h2><p>Taskflow supports <em>recursive tasking</em> for you to create a subflow graph from the execution of a task to perform recursive parallelism. The following program spawns a task dependency graph parented at task <code>B</code>.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">A</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="n">name</span><span class="p">(</span><span class="s">"A"</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">C</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="n">name</span><span class="p">(</span><span class="s">"C"</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">D</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="n">name</span><span class="p">(</span><span class="s">"D"</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">B</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="p">(</span><span class="n">tf</span><span class="o">::</span><span class="n">Subflow</span><span class="o">&</span><span class="w"> </span><span class="n">subflow</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// subflow task B</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">B1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">subflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){}).</span><span class="n">name</span><span class="p">(</span><span class="s">"B1"</span><span class="p">);</span><span class="w"> </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">B2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">subflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){}).</span><span class="n">name</span><span class="p">(</span><span class="s">"B2"</span><span class="p">);</span><span class="w"> </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">B3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">subflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){}).</span><span class="n">name</span><span class="p">(</span><span class="s">"B3"</span><span class="p">);</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="n">B3</span><span class="p">.</span><span class="n">succeed</span><span class="p">(</span><span class="n">B1</span><span class="p">,</span><span class="w"> </span><span class="n">B2</span><span class="p">);</span><span class="w"> </span><span class="c1">// B3 runs after B1 and B2</span>
|
|
<span class="p">}).</span><span class="n">name</span><span class="p">(</span><span class="s">"B"</span><span class="p">);</span>
|
|
|
|
<span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">);</span><span class="w"> </span><span class="c1">// A runs before B and C</span>
|
|
<span class="n">D</span><span class="p">.</span><span class="n">succeed</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">);</span><span class="w"> </span><span class="c1">// D runs after B and C</span></pre><div class="m-graph"><svg style="width: 37.200rem; height: 22.800rem;" viewBox="0.00 0.00 372.00 228.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 224)">
|
|
<title>Taskflow</title>
|
|
<g class="m-cluster">
|
|
<title>cluster_p0x7ffee9781810</title>
|
|
<polygon points="8,-8 8,-212 356,-212 356,-8 8,-8"/>
|
|
<text text-anchor="middle" x="182" y="-200" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow</text>
|
|
</g>
|
|
<g class="m-cluster">
|
|
<title>cluster_p0x7f9866c01b70</title>
|
|
<polygon points="16,-60 16,-185 266,-185 266,-60 16,-60"/>
|
|
<text text-anchor="middle" x="141" y="-173" font-family="Helvetica,sans-Serif" font-size="10.00">Subflow: B</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866c01820</title>
|
|
<ellipse cx="141" cy="-34" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="141" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">A</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866c01b70</title>
|
|
<ellipse cx="231" cy="-88" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="231" y="-85.5" font-family="Helvetica,sans-Serif" font-size="10.00">B</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866c01820->p0x7f9866c01b70</title>
|
|
<path d="M161.53,-45.98C173.38,-53.26 188.7,-62.66 201.84,-70.72"/>
|
|
<polygon points="200.17,-73.8 210.52,-76.05 203.83,-67.84 200.17,-73.8"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866c01930</title>
|
|
<ellipse cx="231" cy="-34" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="231" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">C</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866c01820->p0x7f9866c01930</title>
|
|
<path d="M168.4,-34C176.39,-34 185.31,-34 193.82,-34"/>
|
|
<polygon points="193.92,-37.5 203.92,-34 193.92,-30.5 193.92,-37.5"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866c01a40</title>
|
|
<ellipse cx="321" cy="-61" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="321" y="-58.5" font-family="Helvetica,sans-Serif" font-size="10.00">D</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866c01b70->p0x7f9866c01a40</title>
|
|
<path d="M256.05,-80.62C265.44,-77.74 276.36,-74.39 286.5,-71.28"/>
|
|
<polygon points="287.75,-74.55 296.29,-68.28 285.7,-67.86 287.75,-74.55"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866c01930->p0x7f9866c01a40</title>
|
|
<path d="M256.05,-41.38C265.44,-44.26 276.36,-47.61 286.5,-50.72"/>
|
|
<polygon points="285.7,-54.14 296.29,-53.72 287.75,-47.45 285.7,-54.14"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866d01880</title>
|
|
<ellipse cx="51" cy="-140" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="51" y="-137.5" font-family="Helvetica,sans-Serif" font-size="10.00">B1</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866d01ac0</title>
|
|
<ellipse cx="141" cy="-88" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="141" y="-85.5" font-family="Helvetica,sans-Serif" font-size="10.00">B3</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866d01880->p0x7f9866d01ac0</title>
|
|
<path d="M71.97,-128.2C83.56,-121.35 98.35,-112.61 111.19,-105.03"/>
|
|
<polygon points="113.28,-107.85 120.11,-99.75 109.72,-101.83 113.28,-107.85"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866d01ac0->p0x7f9866c01b70</title>
|
|
<path d="M168.4,-88C176.39,-88 185.31,-88 193.82,-88"/>
|
|
<polygon points="193.92,-91.5 203.92,-88 193.92,-84.5 193.92,-91.5"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f9866d019a0</title>
|
|
<ellipse cx="51" cy="-86" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="51" y="-83.5" font-family="Helvetica,sans-Serif" font-size="10.00">B2</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f9866d019a0->p0x7f9866d01ac0</title>
|
|
<path d="M78.4,-86.6C86.39,-86.78 95.31,-86.98 103.82,-87.18"/>
|
|
<polygon points="103.84,-90.68 113.92,-87.41 104,-83.68 103.84,-90.68"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div></section><section id="QuickStartIntegrateControlFlowIntoATaskGraph"><h2><a href="#QuickStartIntegrateControlFlowIntoATaskGraph">Integrate Control Flow into a Task Graph</a></h2><p>Taskflow supports <em>conditional tasking</em> for you to make rapid control-flow decisions across dependent tasks to implement cycles and conditions in an <em>end-to-end</em> task graph.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">init</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([](){}).</span><span class="n">name</span><span class="p">(</span><span class="s">"init"</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="n">name</span><span class="p">(</span><span class="s">"stop"</span><span class="p">);</span>
|
|
|
|
<span class="c1">// creates a condition task that returns a random binary</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">cond</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="k">return</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">rand</span><span class="p">()</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mi">2</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">"cond"</span><span class="p">);</span>
|
|
|
|
<span class="c1">// creates a feedback loop {0: cond, 1: stop}</span>
|
|
<span class="n">init</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">cond</span><span class="p">);</span>
|
|
<span class="n">cond</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">cond</span><span class="p">,</span><span class="w"> </span><span class="n">stop</span><span class="p">);</span><span class="w"> </span><span class="c1">// moves on to 'cond' on returning 0, or 'stop' on 1</span></pre><div class="m-graph"><svg style="width: 26.300rem; height: 7.300rem;" viewBox="0.00 0.00 262.60 73.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 69)">
|
|
<title>Taskflow</title>
|
|
<g class="m-node">
|
|
<title>cond</title>
|
|
<polygon points="124.3,-36 91.2,-18 124.3,0 157.4,-18 124.3,-36"/>
|
|
<text text-anchor="middle" x="124.3" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">cond</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>cond->cond</title>
|
|
<path stroke-dasharray="5,2" d="M116.24,-31.67C113.02,-42.66 115.71,-54 124.3,-54 130.21,-54 133.32,-48.64 133.65,-41.72"/>
|
|
<polygon points="137.1,-41.14 132.36,-31.67 130.16,-42.03 137.1,-41.14"/>
|
|
<text text-anchor="middle" x="124.3" y="-57" font-family="Helvetica,sans-Serif" font-size="10.00">0</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>stop</title>
|
|
<ellipse cx="227.6" cy="-18" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="227.6" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">stop</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>cond->stop</title>
|
|
<path stroke-dasharray="5,2" d="M157.63,-18C167.97,-18 179.48,-18 190.09,-18"/>
|
|
<polygon points="190.32,-21.5 200.32,-18 190.32,-14.5 190.32,-21.5"/>
|
|
<text text-anchor="middle" x="179.1" y="-21" font-family="Helvetica,sans-Serif" font-size="10.00">1</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>init</title>
|
|
<ellipse cx="27" cy="-18" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="27" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">init</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>init->cond</title>
|
|
<path d="M54.04,-18C62.37,-18 71.82,-18 80.99,-18"/>
|
|
<polygon points="81.17,-21.5 91.17,-18 81.17,-14.5 81.17,-21.5"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div></section><section id="QuickStartOffloadTasksToGPU"><h2><a href="#QuickStartOffloadTasksToGPU">Offload Tasks to a GPU</a></h2><p>Taskflow supports GPU tasking for you to accelerate a wide range of scientific computing applications by harnessing the power of CPU-GPU collaborative computing using CUDA.</p><pre class="m-code"><span class="n">__global__</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">saxpy</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">float</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="kt">float</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="kt">float</span><span class="w"> </span><span class="o">*</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</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="n">blockIdx</span><span class="p">.</span><span class="n">x</span><span class="o">*</span><span class="n">blockDim</span><span class="p">.</span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">threadIdx</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
|
|
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="o">*</span><span class="n">x</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
|
|
<span class="w"> </span><span class="p">}</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">cudaflow</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">emplace</span><span class="p">([</span><span class="o">&</span><span class="p">](</span><span class="n">tf</span><span class="o">::</span><span class="n">cudaFlow</span><span class="o">&</span><span class="w"> </span><span class="n">cf</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">cudaTask</span><span class="w"> </span><span class="n">h2d_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cf</span><span class="p">.</span><span class="n">copy</span><span class="p">(</span><span class="n">dx</span><span class="p">,</span><span class="w"> </span><span class="n">hx</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span><span class="w"> </span><span class="n">N</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">"h2d_x"</span><span class="p">);</span>
|
|
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">cudaTask</span><span class="w"> </span><span class="n">h2d_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cf</span><span class="p">.</span><span class="n">copy</span><span class="p">(</span><span class="n">dy</span><span class="p">,</span><span class="w"> </span><span class="n">hy</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span><span class="w"> </span><span class="n">N</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">"h2d_y"</span><span class="p">);</span>
|
|
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">cudaTask</span><span class="w"> </span><span class="n">d2h_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cf</span><span class="p">.</span><span class="n">copy</span><span class="p">(</span><span class="n">hx</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span><span class="w"> </span><span class="n">dx</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">"d2h_x"</span><span class="p">);</span>
|
|
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">cudaTask</span><span class="w"> </span><span class="n">d2h_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cf</span><span class="p">.</span><span class="n">copy</span><span class="p">(</span><span class="n">hy</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span><span class="w"> </span><span class="n">dy</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">"d2h_y"</span><span class="p">);</span>
|
|
<span class="w"> </span><span class="n">tf</span><span class="o">::</span><span class="n">cudaTask</span><span class="w"> </span><span class="n">saxpy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cf</span><span class="p">.</span><span class="n">kernel</span><span class="p">((</span><span class="n">N</span><span class="o">+</span><span class="mi">255</span><span class="p">)</span><span class="o">/</span><span class="mi">256</span><span class="p">,</span><span class="w"> </span><span class="mi">256</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">saxpy</span><span class="p">,</span><span class="w"> </span><span class="n">N</span><span class="p">,</span><span class="w"> </span><span class="mf">2.0f</span><span class="p">,</span><span class="w"> </span><span class="n">dx</span><span class="p">,</span><span class="w"> </span><span class="n">dy</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">"saxpy"</span><span class="p">);</span><span class="w"> </span><span class="c1">// parameters to the saxpy kernel</span>
|
|
<span class="w"> </span><span class="n">saxpy</span><span class="p">.</span><span class="n">succeed</span><span class="p">(</span><span class="n">h2d_x</span><span class="p">,</span><span class="w"> </span><span class="n">h2d_y</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">d2h_x</span><span class="p">,</span><span class="w"> </span><span class="n">d2h_y</span><span class="p">);</span>
|
|
<span class="p">}).</span><span class="n">name</span><span class="p">(</span><span class="s">"cudaFlow"</span><span class="p">);</span></pre><div class="m-graph"><svg style="width: 24.200rem; height: 9.800rem;" viewBox="0.00 0.00 242.31 98.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 94)">
|
|
<title>Taskflow</title>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f2870401a50</title>
|
|
<ellipse cx="27.08" cy="-72" rx="27.16" ry="18"/>
|
|
<text text-anchor="middle" x="27.08" y="-69.5" font-family="Helvetica,sans-Serif" font-size="10.00">h2d_x</text>
|
|
</g>
|
|
<g class="m-node">
|
|
<title>p0x7f2870402bc0</title>
|
|
<polygon points="144.16,-63 94.16,-63 90.16,-59 90.16,-27 140.16,-27 144.16,-31 144.16,-63"/>
|
|
<polyline points="140.16,-59 90.16,-59 "/>
|
|
<polyline points="140.16,-59 140.16,-27 "/>
|
|
<polyline points="140.16,-59 144.16,-63 "/>
|
|
<text text-anchor="middle" x="117.16" y="-42.5" font-family="Helvetica,sans-Serif" font-size="10.00" fill="white">saxpy</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f2870401a50->p0x7f2870402bc0</title>
|
|
<path d="M52.15,-64.62C60.84,-61.96 70.85,-58.89 80.34,-55.98"/>
|
|
<polygon points="81.42,-59.31 89.95,-53.03 79.37,-52.62 81.42,-59.31"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f2870402310</title>
|
|
<ellipse cx="207.24" cy="-72" rx="27.16" ry="18"/>
|
|
<text text-anchor="middle" x="207.24" y="-69.5" font-family="Helvetica,sans-Serif" font-size="10.00">d2h_x</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f2870402bc0->p0x7f2870402310</title>
|
|
<path d="M144.58,-53.1C153.37,-55.79 163.27,-58.83 172.52,-61.67"/>
|
|
<polygon points="171.64,-65.06 182.23,-64.64 173.69,-58.36 171.64,-65.06"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f2870402780</title>
|
|
<ellipse cx="207.24" cy="-18" rx="27.16" ry="18"/>
|
|
<text text-anchor="middle" x="207.24" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">d2h_y</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f2870402bc0->p0x7f2870402780</title>
|
|
<path d="M144.58,-36.9C153.37,-34.21 163.27,-31.17 172.52,-28.33"/>
|
|
<polygon points="173.69,-31.64 182.23,-25.36 171.64,-24.94 173.69,-31.64"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7f2870401eb0</title>
|
|
<ellipse cx="27.08" cy="-18" rx="27.16" ry="18"/>
|
|
<text text-anchor="middle" x="27.08" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">h2d_y</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7f2870401eb0->p0x7f2870402bc0</title>
|
|
<path d="M52.15,-25.38C60.84,-28.04 70.85,-31.11 80.34,-34.02"/>
|
|
<polygon points="79.37,-37.38 89.95,-36.97 81.42,-30.69 79.37,-37.38"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div></section><section id="QuickStartComposeTaskGraphs"><h2><a href="#QuickStartComposeTaskGraphs">Compose Task Graphs</a></h2><p>Taskflow is composable. You can create large parallel graphs through composition of modular and reusable blocks that are easier to optimize at an individual scope.</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="n">f1</span><span class="p">,</span><span class="w"> </span><span class="n">f2</span><span class="p">;</span>
|
|
|
|
<span class="c1">// create taskflow f1 of two tasks</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">f1A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f1</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Task f1A</span><span class="se">\n</span><span class="s">"</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">"f1A"</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">f1B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f1</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Task f1B</span><span class="se">\n</span><span class="s">"</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">"f1B"</span><span class="p">);</span>
|
|
|
|
<span class="c1">// create taskflow f2 with one module task composed of f1</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">f2A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f2</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Task f2A</span><span class="se">\n</span><span class="s">"</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">"f2A"</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">f2B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f2</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Task f2B</span><span class="se">\n</span><span class="s">"</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">"f2B"</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">f2C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f2</span><span class="p">.</span><span class="n">emplace</span><span class="p">([]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Task f2C</span><span class="se">\n</span><span class="s">"</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">"f2C"</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">f1_module_task</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f2</span><span class="p">.</span><span class="n">composed_of</span><span class="p">(</span><span class="n">f1</span><span class="p">).</span><span class="n">name</span><span class="p">(</span><span class="s">"module"</span><span class="p">);</span>
|
|
|
|
<span class="n">f1_module_task</span><span class="p">.</span><span class="n">succeed</span><span class="p">(</span><span class="n">f2A</span><span class="p">,</span><span class="w"> </span><span class="n">f2B</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">f2C</span><span class="p">);</span></pre><div class="m-graph"><svg style="width: 31.600rem; height: 23.900rem;" viewBox="0.00 0.00 316.00 239.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 235)">
|
|
<title>Taskflow</title>
|
|
<g class="m-cluster">
|
|
<title>cluster_p0x7ffeeb8ff970</title>
|
|
<polygon points="8,-8 8,-223 150,-223 150,-8 8,-8"/>
|
|
<text text-anchor="middle" x="79" y="-211" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow: f2</text>
|
|
</g>
|
|
<g class="m-cluster">
|
|
<title>cluster_p0x7ffeeb8ff8d0</title>
|
|
<polygon points="158,-152 158,-223 300,-223 300,-152 158,-152"/>
|
|
<text text-anchor="middle" x="229" y="-211" font-family="Helvetica,sans-Serif" font-size="10.00">Taskflow: f1</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813838</title>
|
|
<ellipse cx="79" cy="-34" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="79" y="-31.5" font-family="Helvetica,sans-Serif" font-size="10.00">f2C</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813938</title>
|
|
<ellipse cx="115" cy="-178" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="115" y="-175.5" font-family="Helvetica,sans-Serif" font-size="10.00">f2B</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813b38</title>
|
|
<polygon points="139.5,-124 22.5,-124 18.5,-120 18.5,-88 135.5,-88 139.5,-92 139.5,-124"/>
|
|
<polyline points="135.5,-120 18.5,-120 "/>
|
|
<polyline points="135.5,-120 135.5,-88 "/>
|
|
<polyline points="135.5,-120 139.5,-124 "/>
|
|
<text text-anchor="middle" x="79" y="-103.5" font-family="Helvetica,sans-Serif" font-size="10.00">module [Taskflow: f1]</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7ffb03813938->p0x7ffb03813b38</title>
|
|
<path d="M106.65,-160.76C102.46,-152.61 97.27,-142.53 92.53,-133.31"/>
|
|
<polygon points="95.49,-131.42 87.81,-124.12 89.27,-134.62 95.49,-131.42"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7ffb03813b38->p0x7ffb03813838</title>
|
|
<path d="M79,-87.7C79,-79.98 79,-70.71 79,-62.11"/>
|
|
<polygon points="82.5,-62.1 79,-52.1 75.5,-62.1 82.5,-62.1"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813a38</title>
|
|
<ellipse cx="43" cy="-178" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="43" y="-175.5" font-family="Helvetica,sans-Serif" font-size="10.00">f2A</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>p0x7ffb03813a38->p0x7ffb03813b38</title>
|
|
<path d="M51.35,-160.76C55.54,-152.61 60.73,-142.53 65.47,-133.31"/>
|
|
<polygon points="68.73,-134.62 70.19,-124.12 62.51,-131.42 68.73,-134.62"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813638</title>
|
|
<ellipse cx="265" cy="-178" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="265" y="-175.5" font-family="Helvetica,sans-Serif" font-size="10.00">f1B</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>p0x7ffb03813738</title>
|
|
<ellipse cx="193" cy="-178" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="193" y="-175.5" font-family="Helvetica,sans-Serif" font-size="10.00">f1A</text>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div></section><section id="QuickStartLaunchAsyncTasks"><h2><a href="#QuickStartLaunchAsyncTasks">Launch Asynchronous Tasks</a></h2><p>Taskflow supports <em>asynchronous</em> tasking. You can launch tasks asynchronously to dynamically explore task graph parallelism.</p><pre class="m-code"><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">// create asynchronous tasks directly from an executor</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">future</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">future</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">async</span><span class="p">([](){</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"async task returns 1</span><span class="se">\n</span><span class="s">"</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="p">});</span><span class="w"> </span>
|
|
<span class="n">executor</span><span class="p">.</span><span class="n">silent_async</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"><<</span><span class="w"> </span><span class="s">"async task does not return</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span><span class="w"> </span><span class="p">});</span>
|
|
|
|
<span class="c1">// create asynchronous tasks with dynamic dependencies</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">AsyncTask</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">silent_dependent_async</span><span class="p">([](){</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"A</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="p">});</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">AsyncTask</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">silent_dependent_async</span><span class="p">([](){</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"B</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="n">A</span><span class="p">);</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">AsyncTask</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">silent_dependent_async</span><span class="p">([](){</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"C</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="n">A</span><span class="p">);</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">AsyncTask</span><span class="w"> </span><span class="n">D</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">executor</span><span class="p">.</span><span class="n">silent_dependent_async</span><span class="p">([](){</span><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"D</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">);</span>
|
|
|
|
<span class="n">executor</span><span class="p">.</span><span class="n">wait_for_all</span><span class="p">();</span></pre></section><section id="QuickStartRunATaskflowThroughAnExecution"><h2><a href="#QuickStartRunATaskflowThroughAnExecution">Run a Taskflow through an Executor</a></h2><p>The executor provides several <em>thread-safe</em> methods to run a taskflow. You can run a taskflow once, multiple times, or until a stopping criteria is met. These methods are non-blocking with a <code>tf::Future<void></code> return to let you query the execution status.</p><pre class="m-code"><span class="c1">// runs the taskflow once</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">Future</span><span class="o"><</span><span class="kt">void</span><span class="o">></span><span class="w"> </span><span class="n">run_once</span><span class="w"> </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="w"> </span>
|
|
|
|
<span class="c1">// wait on this run to finish</span>
|
|
<span class="n">run_once</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
|
|
|
|
<span class="c1">// run the taskflow four times</span>
|
|
<span class="n">executor</span><span class="p">.</span><span class="n">run_n</span><span class="p">(</span><span class="n">taskflow</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">);</span>
|
|
|
|
<span class="c1">// runs the taskflow five times</span>
|
|
<span class="n">executor</span><span class="p">.</span><span class="n">run_until</span><span class="p">(</span><span class="n">taskflow</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="n">counter</span><span class="o">=</span><span class="mi">5</span><span class="p">](){</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">--</span><span class="n">counter</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="p">});</span>
|
|
|
|
<span class="c1">// blocks the executor until all submitted taskflows complete</span>
|
|
<span class="n">executor</span><span class="p">.</span><span class="n">wait_for_all</span><span class="p">();</span></pre></section><section id="QuickStartLeverageStandardParallelAlgorithms"><h2><a href="#QuickStartLeverageStandardParallelAlgorithms">Leverage Standard Parallel Algorithms</a></h2><p>Taskflow defines algorithms for you to quickly express common parallel patterns using standard C++ syntaxes, such as parallel iterations, parallel reductions, and parallel sort.</p><pre class="m-code"><span class="c1">// standard parallel CPU algorithms</span>
|
|
<span class="n">tf</span><span class="o">::</span><span class="n">Task</span><span class="w"> </span><span class="n">task1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">taskflow</span><span class="p">.</span><span class="n">for_each</span><span class="p">(</span><span class="w"> </span><span class="c1">// assign each element to 100 in parallel</span>
|
|
<span class="w"> </span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">,</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="k">auto</span><span class="o">&</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"> </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">task2</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">reduce</span><span class="p">(</span><span class="w"> </span><span class="c1">// reduce a range of items in parallel</span>
|
|
<span class="w"> </span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">,</span><span class="w"> </span><span class="n">init</span><span class="p">,</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="p">;</span><span class="w"> </span><span class="p">}</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">task3</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">sort</span><span class="p">(</span><span class="w"> </span><span class="c1">// sort a range of items in parallel</span>
|
|
<span class="w"> </span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="n">last</span><span class="p">,</span><span class="w"> </span><span class="p">[]</span><span class="w"> </span><span class="p">(</span><span class="k">auto</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">b</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>
|
|
<span class="p">);</span></pre><p>Additionally, Taskflow provides composable graph building blocks for you to efficiently implement common parallel algorithms, such as parallel pipeline.</p><pre class="m-code"><span class="c1">// create a pipeline to propagate five tokens through three serial stages</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="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&</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="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="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="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&</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="s">"stage 2: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">"</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="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="n">tf</span><span class="o">::</span><span class="n">Pipeflow</span><span class="o">&</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="s">"stage 3: input buffer[%zu] = %d</span><span class="se">\n</span><span class="s">"</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="p">);</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">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></section><section id="QuickStartVisualizeATaskflow"><h2><a href="#QuickStartVisualizeATaskflow">Visualize Taskflow Graphs</a></h2><p>You can dump a taskflow graph to a DOT format and visualize it using a number of free GraphViz tools such as <a href="https://dreampuf.github.io/GraphvizOnline/">GraphViz Online</a>.</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="n">taskflow</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">A</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="p">()</span><span class="w"> </span><span class="p">{}).</span><span class="n">name</span><span class="p">(</span><span class="s">"A"</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">B</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="p">()</span><span class="w"> </span><span class="p">{}).</span><span class="n">name</span><span class="p">(</span><span class="s">"B"</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">C</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="p">()</span><span class="w"> </span><span class="p">{}).</span><span class="n">name</span><span class="p">(</span><span class="s">"C"</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">D</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="p">()</span><span class="w"> </span><span class="p">{}).</span><span class="n">name</span><span class="p">(</span><span class="s">"D"</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">E</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="p">()</span><span class="w"> </span><span class="p">{}).</span><span class="n">name</span><span class="p">(</span><span class="s">"E"</span><span class="p">);</span>
|
|
<span class="n">A</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="p">);</span>
|
|
<span class="n">C</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">D</span><span class="p">);</span>
|
|
<span class="n">B</span><span class="p">.</span><span class="n">precede</span><span class="p">(</span><span class="n">D</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="p">);</span>
|
|
|
|
<span class="c1">// dump the graph to a DOT file through std::cout</span>
|
|
<span class="n">taskflow</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">);</span><span class="w"> </span></pre><div class="m-graph"><svg style="width: 17.500rem; height: 18.800rem;" viewBox="0.00 0.00 175.00 188.00">
|
|
<g transform="scale(1 1) rotate(0) translate(4 184)">
|
|
<title>G</title>
|
|
<g class="m-node m-flat">
|
|
<title>A</title>
|
|
<ellipse cx="68" cy="-162" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="68" y="-159.5" font-family="Helvetica,sans-Serif" font-size="10.00">A</text>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>B</title>
|
|
<ellipse cx="68" cy="-90" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="68" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00">B</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>A->B</title>
|
|
<path d="M68,-143.7C68,-135.98 68,-126.71 68,-118.11"/>
|
|
<polygon points="71.5,-118.1 68,-108.1 64.5,-118.1 71.5,-118.1"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>C</title>
|
|
<ellipse cx="140" cy="-90" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="140" y="-87.5" font-family="Helvetica,sans-Serif" font-size="10.00">C</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>A->C</title>
|
|
<path d="M82.57,-146.83C92.75,-136.94 106.52,-123.55 118.03,-112.36"/>
|
|
<polygon points="120.47,-114.87 125.2,-105.38 115.59,-109.85 120.47,-114.87"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>E</title>
|
|
<ellipse cx="27" cy="-18" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="27" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">E</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>A->E</title>
|
|
<path d="M54.52,-145.98C46.42,-135.98 36.78,-122.12 32,-108 25.27,-88.12 24.27,-64.32 24.81,-46.34"/>
|
|
<polygon points="28.31,-46.4 25.3,-36.24 21.32,-46.06 28.31,-46.4"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>B->E</title>
|
|
<path d="M58.49,-72.76C53.47,-64.19 47.2,-53.49 41.58,-43.9"/>
|
|
<polygon points="44.53,-42.01 36.46,-35.15 38.49,-45.55 44.53,-42.01"/>
|
|
</g>
|
|
<g class="m-node m-flat">
|
|
<title>D</title>
|
|
<ellipse cx="126" cy="-18" rx="27" ry="18"/>
|
|
<text text-anchor="middle" x="126" y="-15.5" font-family="Helvetica,sans-Serif" font-size="10.00">D</text>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>B->D</title>
|
|
<path d="M80.59,-73.81C88.26,-64.55 98.23,-52.52 106.86,-42.09"/>
|
|
<polygon points="109.75,-44.09 113.44,-34.16 104.36,-39.63 109.75,-44.09"/>
|
|
</g>
|
|
<g class="m-edge">
|
|
<title>C->D</title>
|
|
<path d="M136.61,-72.05C135.07,-64.35 133.21,-55.03 131.47,-46.36"/>
|
|
<polygon points="134.85,-45.39 129.46,-36.28 127.98,-46.77 134.85,-45.39"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div></section><section id="SupportedCompilers"><h2><a href="#SupportedCompilers">Supported Compilers</a></h2><p>To use Taskflow, you only need a compiler that supports C++17:</p><ul><li>GNU C++ Compiler at least v8.4 with -std=c++17</li><li>Clang C++ Compiler at least v6.0 with -std=c++17</li><li>Microsoft Visual Studio at least v19.27 with /std:c++17</li><li>AppleClang Xcode Version at least v12.0 with -std=c++17</li><li>Nvidia CUDA Toolkit and Compiler (nvcc) at least v11.1 with -std=c++17</li><li>Intel C++ Compiler at least v19.0.1 with -std=c++17</li><li>Intel DPC++ Clang Compiler at least v13.0.0 with -std=c++17 and SYCL20</li></ul><p>Taskflow works on Linux, Windows, and Mac OS X.</p><aside class="m-note m-info"><h4>Note</h4><p>Although Taskflow supports primarily C++17, you can enable C++20 compilation through <code>-std=c++20</code> to achieve better performance due to new C++20 features.</p></aside></section><section id="QuickStartGetInvolved"><h2><a href="#QuickStartGetInvolved">Get Involved</a></h2><p>Visit our <a href="https://taskflow.github.io/">Project Website</a> and <a href="https://taskflow.github.io/showcase/index.html">showcase presentation</a> to learn more about Taskflow. To get involved:</p><ul><li>See release notes at <a href="Releases.html" class="m-doc">Release Notes</a></li><li>Read the step-by-step tutorial at <a href="Cookbook.html" class="m-doc">Cookbook</a></li><li>Submit an issue at <a href="https://github.com/taskflow/taskflow/issues">issue tracker</a></li><li>Learn more about our technical details at <a href="References.html" class="m-doc">References</a></li><li>Watch our <a href="https://www.youtube.com/watch?v=MX15huP5DsM">2020 CppCon Taskflow Talk</a> and <a href="https://www.youtube.com/watch?v=u8Mc_WgGwVY">2020 MUC++ Taskflow Talk</a></li></ul><p>We are committed to support trustworthy developments for both academic and industrial research projects in parallel and heterogeneous computing. If you are using Taskflow, please cite the following paper we published at 2022 IEEE TPDS:</p><ul><li>Tsung-Wei Huang, Dian-Lun Lin, Chun-Xun Lin, and Yibo Lin, "<a href="https://tsung-wei-huang.github.io/papers/tpds21-taskflow.pdf">Taskflow: A Lightweight Parallel and Heterogeneous Task Graph Computing System</a>," <em>IEEE Transactions on Parallel and Distributed Systems (TPDS)</em>, vol. 33, no. 6, pp. 1303-1320, June 2022</li></ul><p>More importantly, we appreciate all Taskflow <a href="contributors.html" class="m-doc">Contributors</a> and the following organizations for sponsoring the Taskflow project!</p><table class="m-table"><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td><img class="m-image" src="utah-ece-logo.png" alt="Image" /></td><td><img class="m-image" src="nsf.png" alt="Image" /></td><td><img class="m-image" src="darpa.png" alt="Image" /></td><td><img class="m-image" src="NumFocus.png" alt="Image" /></td></tr><tr><td><img class="m-image" src="nvidia-logo.png" alt="Image" /></td><td></td><td></td><td></td></tr></tbody></table></section><section id="License"><h2><a href="#License">License</a></h2><p>Taskflow is open-source under permissive MIT license. You are completely free to use, modify, and redistribute any work on top of Taskflow. The source code is available in <a href="https://github.com/taskflow/">Project GitHub</a> and is actively maintained by <a href="https://tsung-wei-huang.github.io/">Dr. Tsung-Wei Huang</a> and his research group at the University of Wisconsin at Madison.</p></section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article></main>
|
|
<div class="m-doc-search" id="search">
|
|
<a href="#!" onclick="return hideSearch()"></a>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-m-8 m-push-m-2">
|
|
<div class="m-doc-search-header m-text m-small">
|
|
<div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
|
|
<div id="search-symbolcount">…</div>
|
|
</div>
|
|
<div class="m-doc-search-content">
|
|
<form>
|
|
<input type="search" name="q" id="search-input" placeholder="Loading …" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
|
|
</form>
|
|
<noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
|
|
<div id="search-help" class="m-text m-dim m-text-center">
|
|
<p class="m-noindent">Search for symbols, directories, files, pages or
|
|
modules. You can omit any prefix from the symbol or file path; adding a
|
|
<code>:</code> or <code>/</code> suffix lists all members of given symbol or
|
|
directory.</p>
|
|
<p class="m-noindent">Use <span class="m-label m-dim">↓</span>
|
|
/ <span class="m-label m-dim">↑</span> to navigate through the list,
|
|
<span class="m-label m-dim">Enter</span> to go.
|
|
<span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
|
|
copy a link to the result using <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">L</span> while <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">M</span> produces a Markdown link.</p>
|
|
</div>
|
|
<div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
|
|
<ul id="search-results"></ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script src="search-v2.js"></script>
|
|
<script src="searchdata-v2.js" async="async"></script>
|
|
<footer><nav>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-l-10 m-push-l-1">
|
|
<p>Taskflow handbook is part of the <a href="https://taskflow.github.io">Taskflow project</a>, copyright © <a href="https://tsung-wei-huang.github.io/">Dr. Tsung-Wei Huang</a>, 2018–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>
|