Parallel Transforms
Contents
Taskflow provides template functions for constructing tasks to perform parallel transforms over ranges of items.
Include the Header
You need to include the header file, taskflow/algorithm/transform.hpp
, for creating a parallel-transform task.
#include <taskflow/algorithm/transform.hpp>
Create a Unary Parallel-Transform Task
Parallel-transform transforms a range of items, possibly with a different type for the transformed data, and stores the result in another range. The task created by tf::
while (first1 != last1) { *d_first++ = c(*first1++); }
By default, tf::c
to the object obtained by dereferencing every iterator in the range [first1, last1)
and stores the result in another range beginning at d_first
. It is user's responsibility for ensuring the range is valid within the execution of the parallel-transform task. Taskflow's parallel-transform tasks work on all iterable STL containers.
std::vector<int> src = {1, 2, 3, 4, 5}; std::vector<int> tgt(src.size()); taskflow.transform(src.begin(), src.end(), [](int i){ std::cout << "transforming item " << i << " to " << i + 1 << '\n'; return i + 1; });
You can enable stateful iterators by creating a reference wrapper and pass the wrapped iterator to the argument of tf::
std::vector<int> src, tgt; std::vector<int>::iterator first, last, d_first; tf::Task init = taskflow.emplace([&](){ src.resize(1000); tgt.resize(1000); first = src.begin(); last = src.end(); d_first = tgt.begin(); }); tf::Task transform = taskflow.for_each( std::ref(first), std::ref(last), std::ref(d_first), [&](int i) { std::cout << "transforming item " << i << " to " << i + 1 << '\n'; return i+1; } ); init.precede(transform);
When init
finishes, the parallel-transform task transform
will see first
pointing to the beginning of src
and last
pointing to the end of src
. Then, it simultaneously transforms these 1000 items by adding one to each element and stores the result in another range starting at d_first
.
Create a Binary Parallel-Transform Task
You can use the overload, tf::first1
and first2
using the binary operator c
and store the result in another range pointed by d_first
. This method is equivalent to the parallel execution of the following loop:
while (first1 != last1) { *d_first++ = c(*first1++, *first2++); }
The following example creates a parallel-transform task that adds two ranges of elements one by one and stores the result in a target range:
std::vector<int> src1 = {1, 2, 3, 4, 5}; std::vector<int> src2 = {5, 4, 3, 2, 1}; std::vector<int> tgt(src.size()); taskflow.transform( src1.begin(), src1.end(), src2.begin(), tgt.begin(), [](int i, int j){ return i + j; } );