1

I am trying to perform a thrust::reduce_by_key using zip and permutation iterators. i.e. doing this on a zipped array of several 'virtual' permuted arrays. I am having trouble in writing the syntax for the functor density_update.

But first the setup of the problem.

Here is my function call:

thrust::reduce_by_key(  dflagt,
                        dflagtend,
                        thrust::make_zip_iterator( 
                            thrust::make_tuple(
                                thrust::make_permutation_iterator(dmasst, dmapt), 
                                thrust::make_permutation_iterator(dvelt, dmapt),
                                thrust::make_permutation_iterator(dmasst, dflagt),
                                thrust::make_permutation_iterator(dvelt, dflagt)
                            )
                        ),
                        thrust::make_discard_iterator(),
                        danswert,
                        thrust::equal_to<int>(),
                        density_update()
                  ) 

dmapt, dflagt are of type thrust::device_ptr<int> and dvelt , dmasst and danst are of type thrust::device_ptr<double>.

(They are thrust wrappers to my raw cuda arrays)

The arrays mapt and flagt are both index vectors from which I need to perform a gather operation from the arrays dmasst and dvelt.

After the reduction step I intend to write my data to the danswert array. Since multiple arrays are being used in the reduction, obviously I am using zip iterators.

My problem lies in writing the functor density_update which is binary operation.

struct density_update
{
  typedef thrust::device_ptr<double> ElementIterator;
  typedef thrust::device_ptr<int>   IndexIterator;
  typedef thrust::permutation_iterator<ElementIterator,IndexIterator> PIt;

  typedef thrust::tuple< PIt , PIt , PIt, PIt> Tuple;
  __host__ __device__
  double operator()(const Tuple& x , const Tuple& y)
  {   
      return    thrust::get<0>(*x) * (thrust::get<1>(*x) - thrust::get<3>(*x)) + \
                thrust::get<0>(*y) * (thrust::get<1>(*y) - thrust::get<3>(*y));
  }
};

The value being returned is a double . Why the binary operation looks like the above functor is not important. I just want to know how I would go about correcting the above syntactically. As shown above the code is throwing a number of compilation errors. I am not sure where I have gone wrong.

I am using CUDA 4.0 on GTX 570 on Ubuntu 10.10

talonmies
  • 70,661
  • 34
  • 192
  • 269
smilingbuddha
  • 14,334
  • 33
  • 112
  • 189
  • If you are going to post long, nested, templated expressions, could you please pay a little for attention to code formatting? Your last few questions have been *very* hard to read. The easier you make your code to read, the easier it will be for others to understand it, spot the mistakes and give you useful answer. – talonmies Sep 05 '12 at 07:08
  • I apologize for that. Yes, I'll format my code better in the future. – smilingbuddha Sep 05 '12 at 13:50

1 Answers1

1

density_update should not receive tuples of iterators as parameters -- it needs tuples of the iterators' references.

In principle you could write density_update::operator() in terms of the particular reference type of the various iterators, but it's simpler to have the compiler infer the type of the parameters:

struct density_update
{
  template<typename Tuple>
  __host__ __device__
  double operator()(const Tuple& x, const Tuple& y)
  {   
    return thrust::get<0>(x) * (thrust::get<1>(x) - thrust::get<3>(x)) + \
           thrust::get<0>(y) * (thrust::get<1>(y) - thrust::get<3>(y));
  }
};
Jared Hoberock
  • 11,118
  • 3
  • 40
  • 76
  • Thank you for the reply. When I tried your copy-pasting you suggested solution, it is still not compiling, and I am getting a big list of errors. For `reduce_by_key`, is it true that the output type of `binary_op` should be the same data-type as the input. Here, the output of the functor is a `double` whereas the input is a Tuple – smilingbuddha Sep 05 '12 at 05:52
  • 1
    If you post some complete, self-contained code in the OP so that I can reproduce the errors I'll take a closer look. – Jared Hoberock Sep 05 '12 at 16:49
  • I was struggling to find the correct type to use in defining these functions' parameters, it is really clever to let compiler decide about it using templates! – phoad Jan 10 '14 at 09:06
  • If the functor's output type is different than its input types then this is a transformation. If this is your intent, try using transform_reduce instead of reduce. – All The Rage Nov 26 '18 at 23:55