I am somewhat new to CUDA and thrust and I am currently struggeling with the following problem:
I have 2 structs carrying data.
struct S1 {
unsigned long A, B, C;
}
struct S2 {
double A, B, C;
}
At the start of the program I have a vector of the first struct and I want to use the GPU as well as a special functor to transform the vector of S1
to a vector of S2
. The result will have the same size as the input only with elements of a different type.
I am currently using this setup:
struct Functor {
Functor() {}
__host__ __ device__ S2 operator() (const S1& s1) {
// perform some operation on S1 to convert it so S2
// here I just copy the values
return S2{s1.A, s1.B, s1.C};
}
}
void main() {
std::vector<S1> input;
// fill the 'input' vector
// move the input to a device vector
thrust::device_vector<S1> input_d(input);
// empty vector for struct S2
thrust::device_vector<S2> output_d(input.size());
thrust::transform(input_d.begin(), input_d.end(), output_d.begin(), output_d.end(), Functor());
return 0;
}
The functor Functor
is responsible for converting S1
to S2
(simplified in this case).
This code results in a compiler error since the operator()
needs 2 arguments while I only want to have one input. Looking around the web I did not find a solution that applies to my problem.
As already pointed out in the comments I misread the documentation (see here). The solution is to use a unary functor and another way of calling the thrust::transform
.
// this functor converts values of S1 to S1 by multiplying them with .5
// in the actual scenario this method does perform much more useful operations
struct Functor : public thrust::unary_function<S1, S2> {
Functor() {}
__host__ __device__ S2 operator() (const S1& s1) const {
// very basic operations on the values of s1
double a = s1.A * .5;
double b = s1.B * .5;
double c = s1.C * .5;
return S2{a, b, c};
}
}
The transform is then called as:
thrust::host_vector<S1> tmp;
// fill the tmp vector with S1 instances...
// move the host vector to the device
thrust::device_vector<S1> input_d;
input_d = tmp;
// initializing the output with the same size as the input
thrust::device_vector<S2> output_d(tmp.size());
// calling the functor on all elements of the input and store them in the output
thrust::transform(input_d.begin(), input_d.end(), output_d.begin(), Functor());
Edit: Added some more code parts so it is actually working code.