FreddyKay
FreddyKay

Reputation: 285

How can I use a thrust::transform with independent iterators?

What I mean in the title is, if I want to generate a vector which depends on two different values in vectors, how can I do this in thrust?

Imagine this function:

void foo(int rows, int columns)
{
    std::vector<int> blubb;
    for (int x = 0; x < rows; x++)
    {
        for (int y = 0; y < columns; y++)
        {
            blubb.push_back(x * y);
        }
    }
}

I cannot seem to figure out how to easily transform this to thrust.

If I use thrust::transform with thrust::counting_iterator, both iterators would be incremented in each step, but I actually want the permutations that are possible:

void fooGPU(int rows, int columns)
{
    thrust::device_vector<int> blubb(rows * columns);

    thrust::transform(thrust::make_counting_iterator<int>(0),
                      thrust::make_counting_iterator<int>(rows), 
                      thrust::make_counting_iterator<int>(0), 
                      blubb.begin(), 
                      thrust::multiplies<int>());
}

I have the feeling that there is a very simple solution to that problem, but I fail to see it.

Upvotes: 2

Views: 292

Answers (1)

kangshiyin
kangshiyin

Reputation: 9781

You could transform linear index first to row and column indices and then multiply them.

thrust::transform(
  thrust::make_transform_iterator(thrust::make_counting_iterator(0),
                                  _1 % columns),
  thrust::make_transform_iterator(thrust::make_counting_iterator(0),
                                  _1 % columns) + rows * columns,
  thrust::make_transform_iterator(thrust::make_counting_iterator(0),
                                  _1 / columns),
  blubb.begin(), 
  _1 * _2);

You could find a simple example about placeholders here.

https://thrust.github.io/doc/namespaceplaceholders.html

Upvotes: 3

Related Questions