同步操作将从 Gitee 极速下载/cpp-taskflow 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<?xml version='1.0' encoding='UTF-8' standalone='no'?><doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.12.0" xml:lang="en-US"><compounddef id="ModuleAlgorithm" kind="page"><compoundname>ModuleAlgorithm</compoundname><title>Module Algorithm</title><tableofcontents><tocsect><name>Include the Header</name><reference>ModuleAlgorithm_1ModuleAlgorithmInclude</reference></tocsect><tocsect><name>What is a Module Task</name><reference>ModuleAlgorithm_1WhatIsAModuleTask</reference></tocsect><tocsect><name>Create a Module Task over a Custom Graph</name><reference>ModuleAlgorithm_1CreateAModuleTaskOverACustomGraph</reference></tocsect></tableofcontents><briefdescription></briefdescription><detaileddescription><para>Taskflow provides template methods that let users create reusable building blocks called <emphasis>modules</emphasis>. Users can connect modules together to build more complex parallel algorithms.</para><sect1 id="ModuleAlgorithm_1ModuleAlgorithmInclude"><title>Include the Header</title><para>You need to include the header file, <computeroutput><ref refid="module_8hpp_source" kindref="compound">taskflow/algorithm/module.hpp</ref></computeroutput>, for creating a module task over a schedulable graph target.</para><para><programlisting filename=".cpp"><codeline><highlight class="preprocessor">#include<sp/><taskflow/algorithm/module.hpp></highlight></codeline></programlisting></para></sect1><sect1 id="ModuleAlgorithm_1WhatIsAModuleTask"><title>What is a Module Task</title><para>Similar to <ref refid="ComposableTasking" kindref="compound">Composable Tasking</ref>, but in a more general setting, the template function <ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref> allows you to create a task over a <ref refid="classtf_1_1Taskflow" kindref="compound">Taskflow</ref> graph that can be executed by an executor. This provides a flexible mechanism to encapsulate and reuse complex task logic within your Taskflow applications. The following example demonstrates how to create and launch multiple <ref refid="classtf_1_1Taskflow" kindref="compound">Taskflow</ref> graphs in parallel using asynchronous tasking:</para><para><programlisting filename=".cpp"><codeline><highlight class="preprocessor">#include<sp/><<ref refid="taskflow_8hpp" kindref="compound">taskflow/taskflow.hpp</ref>></highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="preprocessor">#include<sp/><taskflow/algorithm/module.hpp></highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main()<sp/>{</highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Executor" kindref="compound">tf::Executor</ref><sp/>executor;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>A;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>B;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>C;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>D;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>A.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/>printf(</highlight><highlight class="stringliteral">"Taskflow<sp/>A\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>B.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/>printf(</highlight><highlight class="stringliteral">"Taskflow<sp/>B\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>C.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/><ref refid="cpp/io/c/fprintf" kindref="compound" external="/Users/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">printf</ref>(</highlight><highlight class="stringliteral">"Taskflow<sp/>C\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>D.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/><ref refid="cpp/io/c/fprintf" kindref="compound" external="/Users/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">printf</ref>(</highlight><highlight class="stringliteral">"Taskflow<sp/>D\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="comment">//<sp/>launch<sp/>the<sp/>four<sp/>taskflows<sp/>using<sp/>asynchronous<sp/>tasking</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1af960048056f7c6b5bc71f4f526f05df7" kindref="member">async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(A));</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1af960048056f7c6b5bc71f4f526f05df7" kindref="member">async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(B));</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1af960048056f7c6b5bc71f4f526f05df7" kindref="member">async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(C));</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1af960048056f7c6b5bc71f4f526f05df7" kindref="member">async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(D));</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1ab9aa252f70e9a40020a1e5a89d485b85" kindref="member">wait_for_all</ref>();<sp/><sp/></highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>0;</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline></programlisting></para><para><dotfile name="module_task_1.dot"></dotfile></para><para>Since the four taskflows are launched asynchronously without any dependencies between them, we can observe any order of the output message:</para><para><programlisting filename=".bash"><codeline><highlight class="normal">#<sp/>one<sp/>possible<sp/>output</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>B</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>C</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>A</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>D</highlight></codeline><codeline></codeline><codeline><highlight class="normal">#<sp/>another<sp/>possible<sp/>output</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>D</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>A</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>B</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>C</highlight></codeline></programlisting></para><para>If you need to enforce dependencies among these four taskflows, you can use dependent-async tasks. The example below launches the four taskflows one by one in sequential:</para><para><programlisting filename=".cpp"><codeline><highlight class="normal"><ref refid="classtf_1_1Executor" kindref="compound">tf::Executor</ref><sp/>executor;</highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>A;</highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>B;</highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>C;</highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>D;</highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal">A.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/>printf(</highlight><highlight class="stringliteral">"Taskflow<sp/>A\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal">B.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/>printf(</highlight><highlight class="stringliteral">"Taskflow<sp/>B\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal">C.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/><ref refid="cpp/io/c/fprintf" kindref="compound" external="/Users/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">printf</ref>(</highlight><highlight class="stringliteral">"Taskflow<sp/>C\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal">D.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([](){<sp/><ref refid="cpp/io/c/fprintf" kindref="compound" external="/Users/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">printf</ref>(</highlight><highlight class="stringliteral">"Taskflow<sp/>D\n"</highlight><highlight class="normal">);<sp/>});<sp/></highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="keyword">auto</highlight><highlight class="normal"><sp/>TA<sp/>=<sp/>executor.<ref refid="classtf_1_1Executor_1a0e2d792f28136b8227b413d0c27d5c7f" kindref="member">silent_dependent_async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(A));</highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="keyword">auto</highlight><highlight class="normal"><sp/>TB<sp/>=<sp/>executor.<ref refid="classtf_1_1Executor_1a0e2d792f28136b8227b413d0c27d5c7f" kindref="member">silent_dependent_async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(B),<sp/>TA);</highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="keyword">auto</highlight><highlight class="normal"><sp/>TC<sp/>=<sp/>executor.<ref refid="classtf_1_1Executor_1a0e2d792f28136b8227b413d0c27d5c7f" kindref="member">silent_dependent_async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(C),<sp/>TB);</highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="keyword">auto</highlight><highlight class="normal"><sp/>[TD,<sp/>FD]<sp/>=<sp/>executor.<ref refid="classtf_1_1Executor_1aee02b63d3a91ad5ca5a1c0e71f3e128f" kindref="member">dependent_async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(D),<sp/>TC);</highlight></codeline><codeline><highlight class="normal">FD.get();</highlight></codeline></programlisting></para><para><dotfile name="module_task_2.dot"></dotfile></para><para><programlisting filename=".bash"><codeline><highlight class="normal">#<sp/>dependent-async<sp/>tasks<sp/>enforce<sp/>a<sp/>sequential<sp/>execution<sp/>of<sp/>the<sp/>four<sp/>taskflows</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>A</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>B</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>C</highlight></codeline><codeline><highlight class="normal">Taskflow<sp/>D</highlight></codeline></programlisting></para><para>The module task maker, <ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>, operates similarly to <ref refid="classtf_1_1FlowBuilder_1ac6f22228d4c2ea2e643c4b0d42c0e92a" kindref="member">tf::Taskflow::composed_of</ref>, but provides a more general interface that can be used beyond Taskflow. Specifically, the following two approaches achieve equivalent functionality:</para><para><programlisting filename=".cpp"><codeline><highlight class="comment">//<sp/>approach<sp/>1:<sp/>composition<sp/>using<sp/>composed_of</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Task" kindref="compound">tf::Task</ref><sp/>m1<sp/>=<sp/>taskflow1.<ref refid="classtf_1_1Task_1ab38be520fe700cb4ca1f312308a95585" kindref="member">composed_of</ref>(taskflow2);</highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"></highlight><highlight class="comment">//<sp/>approach<sp/>2:<sp/>composition<sp/>using<sp/>make_module_task</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><ref refid="classtf_1_1Task" kindref="compound">tf::Task</ref><sp/>m1<sp/>=<sp/>taskflow1.emplace(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(taskflow2));</highlight></codeline></programlisting></para><para><simplesect kind="attention"><para>Similar to <ref refid="classtf_1_1FlowBuilder_1ac6f22228d4c2ea2e643c4b0d42c0e92a" kindref="member">tf::Taskflow::composed_of</ref>, <ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref> does not assume ownership of the provided taskflow but a soft reference. You are responsible for ensuring that the encapsulated taskflow remains valid throughout its execution.</para></simplesect></para></sect1><sect1 id="ModuleAlgorithm_1CreateAModuleTaskOverACustomGraph"><title>Create a Module Task over a Custom Graph</title><para>In addition to encapsulate taskflow graphs, you can create a module task to schedule a custom graph target. A schedulable target (of type <computeroutput>T</computeroutput>) must define the method <computeroutput>T::graph()</computeroutput> that returns a reference to the <ref refid="classtf_1_1Graph" kindref="compound">tf::Graph</ref> object managed by <computeroutput>T</computeroutput>. The following example defines a custom graph that can be scheduled through making module tasks:</para><para><programlisting filename=".cpp"><codeline><highlight class="keyword">struct<sp/></highlight><highlight class="normal">CustomGraph<sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Graph" kindref="compound">tf::Graph</ref><sp/>graph;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>CustomGraph()<sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="comment">//<sp/>use<sp/>flow<sp/>builder<sp/>to<sp/>inherit<sp/>all<sp/>task<sp/>creation<sp/>methods<sp/>in<sp/>tf::Taskflow</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><ref refid="classtf_1_1FlowBuilder" kindref="compound">tf::FlowBuilder</ref><sp/>builder(graph);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><ref refid="classtf_1_1Task" kindref="compound">tf::Task</ref><sp/>task<sp/>=<sp/>builder.emplace([](){</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><ref refid="cpp/io/basic_ostream" kindref="compound" external="/Users/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">std::cout</ref><sp/><<<sp/></highlight><highlight class="stringliteral">"a<sp/>task\n"</highlight><highlight class="normal">;<sp/><sp/></highlight><highlight class="comment">//<sp/>static<sp/>task</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>});</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="comment">//<sp/>returns<sp/>a<sp/>reference<sp/>to<sp/>the<sp/>graph<sp/>for<sp/>taskflow<sp/>composition</highlight><highlight class="normal"></highlight></codeline><codeline><highlight class="normal"><sp/><sp/>Graph&<sp/>graph()<sp/>{<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>graph;<sp/>}</highlight></codeline><codeline><highlight class="normal">};</highlight></codeline><codeline><highlight class="normal"></highlight></codeline><codeline><highlight class="normal">CustomGraph<sp/>target;</highlight></codeline><codeline><highlight class="normal">executor.<ref refid="classtf_1_1Executor_1af960048056f7c6b5bc71f4f526f05df7" kindref="member">async</ref>(<ref refid="namespacetf_1ad13f8d0b6628d895792570515497139c" kindref="member">tf::make_module_task</ref>(target));</highlight></codeline></programlisting></para><para><simplesect kind="attention"><para>Users are responsible for ensuring the given custom graph remains valid throughout its execution. The executor does not assume ownership of the custom graph. </para></simplesect></para></sect1></detaileddescription><location file="doxygen/algorithms/module.dox"/></compounddef></doxygen>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。