thrust::transform_iterator

Defined in thrust/iterator/transform_iterator.h

template<class AdaptableUnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
class transform_iterator : public detail::make_transform_iterator_base::type<AdaptableUnaryFunction, Iterator, use_default, use_default>

transform_iterator is an iterator which represents a pointer into a range of values after transformation by a function. This iterator is useful for creating a range filled with the result of applying an operation to another range without either explicitly storing it in memory, or explicitly executing the transformation. Using transform_iterator facilitates kernel fusion by deferring the execution of a transformation until the value is needed while saving both memory capacity and bandwidth.

The following code snippet demonstrates how to create a transform_iterator which represents the result of sqrtf applied to the contents of a device_vector.

#include <thrust/iterator/transform_iterator.h>
#include <thrust/device_vector.h>

struct square_root
{
  __host__ __device__
  float operator()(float x) const
  {
    return sqrtf(x);
  }
};

int main()
{
  thrust::device_vector<float> v(4);
  v[0] = 1.0f;
  v[1] = 4.0f;
  v[2] = 9.0f;
  v[3] = 16.0f;

  using FloatIterator = thrust::device_vector<float>::iterator;

  thrust::transform_iterator<square_root, FloatIterator> iter(v.begin(), square_root());

  *iter;   // returns 1.0f
  iter[0]; // returns 1.0f;
  iter[1]; // returns 2.0f;
  iter[2]; // returns 3.0f;
  iter[3]; // returns 4.0f;

  // iter[4] is an out-of-bounds error
}

This next example demonstrates how to use a transform_iterator with the thrust::reduce function to compute the sum of squares of a sequence. We will create temporary transform_iterators with the make_transform_iterator function in order to avoid explicitly specifying their type:

#include <thrust/iterator/transform_iterator.h>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <iostream>

struct square
{
  __host__ __device__
  float operator()(float x) const
  {
    return x * x;
  }
};

int main()
{
  // initialize a device array
  thrust::device_vector<float> v(4);
  v[0] = 1.0f;
  v[1] = 2.0f;
  v[2] = 3.0f;
  v[3] = 4.0f;

  float sum_of_squares =
   thrust::reduce(thrust::make_transform_iterator(v.begin(), square()),
                  thrust::make_transform_iterator(v.end(),   square()));

  std::cout << "sum of squares: " << sum_of_squares << std::endl;
  return 0;
}

The following example illustrates how to use the third template argument to explicitly specify the return type of the function.

#include <thrust/iterator/transform_iterator.h>
#include <thrust/device_vector.h>

struct square_root
{
  __host__ __device__
  float operator()(float x) const
  {
    return sqrtf(x);
  }
};

int main()
{
  thrust::device_vector<float> v(4);
  v[0] = 1.0f;
  v[1] = 4.0f;
  v[2] = 9.0f;
  v[3] = 16.0f;

  using FloatIterator = thrust::device_vector<float>::iterator;

  // note: float result_type is specified explicitly
  thrust::transform_iterator<square_root, FloatIterator, float> iter(v.begin(), square_root());

  *iter;   // returns 1.0f
  iter[0]; // returns 1.0f;
  iter[1]; // returns 2.0f;
  iter[2]; // returns 3.0f;
  iter[3]; // returns 4.0f;

  // iter[4] is an out-of-bounds error
}

See also

make_transform_iterator