(Thrust) Defining functor inside a function thrust, transform, functor

Hi.

Is it not possible to define a functor inside a function?

I’m trying to invoke Thrust::transform with a functor defined inside the same function.

But the compiler complains as below.

#include <stdlib.h>

#include <stdio.h>

#include <thrust/device_vector.h>

#include <thrust/transform.h>

#include <thrust/sequence.h>

#include <thrust/copy.h>

#include <thrust/fill.h>

#include <thrust/replace.h>

#include <thrust/functional.h>

int main(void) {

struct saxpy_functor : thrust::binary_function<float,float,float> {

    const float a;

    saxpy_functor ( float _a ) : a ( _a ) {}

    __host__ __device__ float operator () ( const float & x , const float & y) const {

      return a * x + y ;

    }

  };

thrust::device_vector <float> X(10) ;

  thrust::device_vector <float> Y(10) ;

thrust::transform(X.begin(),X.end(),Y.begin(),Y.begin(), saxpy_functor(2.0f));

return 0;

}

If the functor definition is taken out of the main function, it compiles fine.

Is there a way to define the functor inside the main function?

Thanks.

Without doing any work, I wonder if maybe you should use device_ptr instead of device_vector. See if that works.

Also, this seems like a lot of code to write for such a simple operation. Perhaps ArrayFire would make life easier (it’s free for most users):

#include <arrayfire.h>

int main(void) {

float a = 2.0;

array x = randu(10,1);  array y = randu(10,1);

y += a*x;

return 0;

}

I believe that c++03 requires template parameters to have “linkage” [1], which function-scope types like your saxpy_functor lacks. So the short answer to your question is no. You can read more about it here [2].

For short arithmetic expressions like saxpy, you can use a placeholder expression [3] (warning, untested code):

#include <thrust/device_vector.h>

#include <thrust/transform.h>

#include <thrust/functional.h>

int main(void)

{

  thrust::device_vector <float> X(10) ;

  thrust::device_vector <float> Y(10) ;

using thrust::placeholders;

thrust::transform(X.begin(),X.end(),Y.begin(),Y.begin(), 2.0f * _1 + _2);

return 0;

}

[1] http://en.wikipedia.org/wiki/Linkage_(software)

[2] http://stackoverflow.com/questions/3470189/why-cant-templates-take-function-local-types

[3] http://code.google.com/p/thrust/source/browse/examples/lambda.cu

Thanks!