# Learning from Examples » 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.

    #include <taskflow/taskflow.hpp>

    int main() {
      tf::Executor executor;
      tf::Taskflow taskflow;
      int num_blocks = 3;
      std::vector<std::vector<tf::Task>> node(num_blocks);

      // 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);
    }

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

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.

Tab / T to search, Esc to close
…

Search for symbols, directories, files, pages or modules. You can omit any prefix from the symbol or file path; adding a `:` or `/` suffix lists all members of given symbol or directory.

Use ↓ / ↑ to navigate through the list, Enter to go. Tab autocompletes common prefix, you can copy a link to the result using ⌘ L while ⌘ M produces a Markdown link.

Sorry, nothing was found.