Taskflow  3.2.0-Master-Branch
Loading...
Searching...
No Matches
Wavefront Parallelism

We study the wavefront parallelism, which is a common pattern in dynamic programming to sweep elements in a diagonal direction.

Problem Formulation

The computation starts at a singular point at a corner of a data plan (e.g., grid) and propagates its effect diagonally to other elements. This sweep of computation is known as wavefront. Each point in the wavefront can be computed in parallel. The following example shows a wavefront parallelism in a 2D matrix.

We partition the 9x9 grid into a 3x3 block and assign a task to one block. The wavefront propagates task dependencies from the top-left block all the way to the bottom-right block. Each task precedes two tasks, one to the right and another below.

Wavefront Task Graph

We can describe the wavefront parallelism in a simple two-level loop. Since we need to address the two tasks upper and left to a task when creating its dependencies, we use a 2D vector to pre-allocate all tasks via tf::Taskflow::placeholder.

int main() {
tf::Executor executor;
tf::Taskflow taskflow;
// create num_blocks*num_blocks placeholder tasks
for(auto &n : node){
for(int i=0; i<num_blocks; i++){
n.emplace_back(taskflow.placeholder());
}
}
// scan each block and create dependencies
for( int i=num_blocks; --i>=0; ) {
for( int j=num_blocks; --j>=0; ) {
// deferred task assignment
node[i][j].work([=]() { printf("compute block (%d, %d)", i, j); });
// wavefront dependency
if(j+1 < num_blocks) node[i][j].precede(node[i][j+1]);
if(i+1 < num_blocks) node[i][j].precede(node[i+1][j]);
}
}
executor.run(taskflow).wait();
// dump the taskflow
taskflow.dump(std::cout);
}
class to create an executor for running a taskflow graph
Definition executor.hpp:50
tf::Future< void > run(Taskflow &taskflow)
runs a taskflow once
Definition executor.hpp:1573
Task placeholder()
creates a placeholder task
Definition flow_builder.hpp:820
class to create a taskflow object
Definition core/taskflow.hpp:73
void dump(std::ostream &ostream) const
dumps the taskflow to a DOT format through a std::ostream target
Definition core/taskflow.hpp:363
main taskflow include file

The figure below shows the wavefront parallelism in a 3x3 grid:

dot_wavefront_2.png

Wavefront parallelism has many variations in different applications, for instance, Smith-Waterman sequencing, video encoding algorithms, image analysis, and pipeline parallelism. The parallel pattern exhibits in a diagonal direction.