Back to Taskflow

Include the Header

docs/ModuleAlgorithm.html

4.1.09.3 KB
Original Source

| | Taskflow: A General-purpose Task-parallel Programming System |

Loading...

Searching...

No Matches

Module Algorithm

Taskflow provides template methods that let users create reusable building blocks called modules. Users can connect modules together to build more complex parallel algorithms.

Include the Header

You need to include the header file, taskflow/algorithm/module.hpp, for creating a module task over a schedulable graph target.

#include <taskflow/algorithm/module.hpp>

What is a Module Task

Similar to Composable Tasking, but in a more general setting, the template function tf::make_module_task allows you to create a task over a Taskflow 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 Taskflow graphs in parallel using asynchronous tasking:

#include <taskflow/taskflow.hpp>

#include <taskflow/algorithm/module.hpp>

int main() {

tf::Executor executor;

tf::Taskflow A;

tf::Taskflow B;

tf::Taskflow C;

tf::Taskflow D;

A.emplace({ printf("Taskflow A\n"); });

B.emplace({ printf("Taskflow B\n"); });

C.emplace({ printf("Taskflow C\n"); });

D.emplace({ printf("Taskflow D\n"); });

// launch the four taskflows using asynchronous tasking

executor.async(tf::make_module_task(A));

executor.async(tf::make_module_task(B));

executor.async(tf::make_module_task(C));

executor.async(tf::make_module_task(D));

executor.wait_for_all();

return 0;

}

tf::Executor

class to create an executor

Definition executor.hpp:62

tf::Executor::wait_for_all

void wait_for_all()

waits for all tasks to complete

tf::Executor::async

auto async(P &&params, F &&func)

creates a parameterized asynchronous task to run the given function

tf::FlowBuilder::emplace

Task emplace(C &&callable)

creates a static task

Definition flow_builder.hpp:1571

tf::Taskflow

class to create a taskflow object

Definition taskflow.hpp:64

tf::make_module_task

auto make_module_task(T &target)

creates a module task using the given graph

Definition module.hpp:74

Embedded content

Since the four taskflows are launched asynchronously without any dependencies between them, we can observe any order of the output message:

one possible output

Taskflow B

Taskflow C

Taskflow A

Taskflow D

another possible output

Taskflow D

Taskflow A

Taskflow B

Taskflow C

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:

tf::Executor executor;

tf::Taskflow A;

tf::Taskflow B;

tf::Taskflow C;

tf::Taskflow D;

A.emplace({ printf("Taskflow A\n"); });

B.emplace({ printf("Taskflow B\n"); });

C.emplace({ printf("Taskflow C\n"); });

D.emplace({ printf("Taskflow D\n"); });

auto TA = executor.silent_dependent_async(tf::make_module_task(A));

auto TB = executor.silent_dependent_async(tf::make_module_task(B), TA);

auto TC = executor.silent_dependent_async(tf::make_module_task(C), TB);

auto [TD, FD] = executor.dependent_async(tf::make_module_task(D), TC);

FD.get();

tf::Executor::silent_dependent_async

tf::AsyncTask silent_dependent_async(F &&func, Tasks &&... tasks)

runs the given function asynchronously when the given predecessors finish

tf::Executor::dependent_async

auto dependent_async(F &&func, Tasks &&... tasks)

runs the given function asynchronously when the given predecessors finish

Embedded content

dependent-async tasks enforce a sequential execution of the four taskflows

Taskflow A

Taskflow B

Taskflow C

Taskflow D

The module task maker, tf::make_module_task, operates similarly to tf::Taskflow::composed_of, but provides a more general interface that can be used beyond Taskflow. Specifically, the following two approaches achieve equivalent functionality:

// approach 1: composition using composed_of

tf::Task m1 = taskflow1.composed_of(taskflow2);

// approach 2: composition using make_module_task

tf::Task m1 = taskflow1.emplace(tf::make_module_task(taskflow2));

tf::Task

class to create a task handle over a taskflow node

Definition task.hpp:569

tf::Task::composed_of

Task & composed_of(T &object)

creates a module task from a taskflow

Definition task.hpp:1290

NoteSimilar to tf::Taskflow::composed_of, tf::make_module_task 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.

Create a Module Task over a Custom Graph

In addition to encapsulate taskflow graphs, you can create a module task to schedule a custom graph target. A schedulable target (of type T) must define the method T::graph() that returns a reference to the tf::Graph object managed by T. The following example defines a custom graph that can be scheduled through making module tasks:

struct CustomGraph {

tf::Graph graph;

CustomGraph() {

// use flow builder to inherit all task creation methods in tf::Taskflow

tf::FlowBuilder builder(graph);

tf::Task task = builder.emplace({

std::cout << "a task\n"; // static task

});

}

// returns a reference to the graph for taskflow composition

Graph& graph() { return graph; }

};

CustomGraph target;

executor.async(tf::make_module_task(target));

tf::FlowBuilder

class to build a task dependency graph

Definition flow_builder.hpp:22

tf::Graph

class to create a graph object

Definition graph.hpp:47

NoteUsers are responsible for ensuring the given custom graph remains valid throughout its execution. The executor does not assume ownership of the custom graph.