How to: Use transformer in a Data Pipeline

This topic contains a basic example that shows how to use the concurrency::transformer class in a data pipeline. For a more complete example that uses a data pipeline to perform image processing, see Walkthrough: Creating an Image-Processing Network.

Data pipelining is a common pattern in concurrent programming. A data pipeline consists of a series of stages, where each stage performs work and then passes the result of that work to the next stage. The transformer class a key component in data pipelines because it receives an input value, performs work on that value, and then produces a result for another component to use.

Example

This example uses the following data pipeline to perform a series of transformations given an initial input value:

  1. The first stage calculates the absolute value of its input.

  2. The second stage calculates the square root of its input.

  3. The third stage computes the square of its input.

  4. The forth stage negates its input.

  5. The fifth stage writes the final result to a message buffer.

Finally, the example prints the result of the pipeline to the console.

// data-pipeline.cpp
// compile with: /EHsc
#include <agents.h>
#include <math.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Computes the absolute value of its input.
   transformer<int, int> t0([](int n) {
      return abs(n);
   });

   // Computes the square root of its input.
   transformer<int, double> t1([](int n) {
      return sqrt(static_cast<double>(n));
   });

   // Computes the square its input.
   transformer<double, int> t2([](double n) {
      return static_cast<int>(n * n);
   });

   // Negates its input.
   transformer<int, int> t3([](int n) {
      return -n;
   });

   // Holds the result of the pipeline computation.
   single_assignment<int> result;

   // Link together each stage of the pipeline.
   // t0 -> t1 -> t2 -> t3 -> result
   t0.link_target(&t1);
   t1.link_target(&t2);
   t2.link_target(&t3);
   t3.link_target(&result);

   // Propagate a message through the pipeline.
   send(t0, -42);

   // Print the result to the console.
   wcout << L"The result is " << receive(result) << L'.' << endl;
}

This example produces the following output:

The result is -42.

It is common for a stage in a data pipeline to output a value whose type differs from its input value. In this example, the second stage takes a value of type int as its input and produces the square root of that value (a double) as its output.

Note

The data pipeline in this example is for illustration. Because each transformation operation performs little work, the overhead that is required to perform message-passing can outweigh the benefits of using a data pipeline.

Compiling the Code

Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named data-pipeline.cpp and then run the following command in a Visual Studio Command Prompt window.

cl.exe /EHsc data-pipeline.cpp

See also

Asynchronous Agents Library
Asynchronous Message Blocks
Walkthrough: Creating an Image-Processing Network