Runtime Tasking
Taskflow allows you to interact with the scheduling runtime from the execution context of a runtime task. Runtime tasking is mostly used for designing specialized parallel algorithms that go beyond the default scheduling rules of taskflows.
Create a Runtime Task
A runtime task is a callable that takes a reference to a tf::
tf::Task A, B, C, D; std::tie(A, B, C, D) = taskflow.emplace( [] () { return 0; }, [&C] (tf::Runtime& rt) { // C must be captured by reference std::cout << "B\n"; rt.schedule(C); }, [] () { std::cout << "C\n"; }, [] () { std::cout << "D\n"; } ); A.precede(B, C, D); executor.run(taskflow).wait();
When the condition task A
completes and returns 0
, the scheduler moves on to the runtime task B
. Under the normal circumstance, tasks C
and D
will not run because their conditional dependencies never happen. This can be broken by forcefully scheduling C
or/and D
via a runtime task that resides in the same graph. Here, the runtime task B
call tf::C
even though the weak dependency between A
and C
will never happen based on the graph structure itself. As a result, we will see both B
and C
in the output:
B # B is a runtime task to schedule C out of its dependency constraint C
Acquire the Running Executor
You can acquire the reference to the running executor using tf::
tf::Executor executor; tf::Taskflow taskflow; taskflow.emplace([&](tf::Runtime& rt){ assert(&(rt.executor()) == &executor); }); executor.run(taskflow).wait();