I want to use copy_if from CUDA's Thrust to compact a array of structs. My struct has a id and a score. I want to copy only the structs that satisfy a minimum score. The threshold is set by the user.
struct is_bigger_than_threshold
{
__host__ __device__
bool operator()(const register x)
{
return (x.score > threshold);
}
};
Yes, it's possible. The functor needs to accept the struct as its operator parameter, and it needs to include storage for the desired threshold. This threshold can be passed as a parameter when the functor is used. Here is a fully worked example:
$ cat t688.cu
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/copy.h>
#include <iostream>
struct my_score {
int id;
int score;
};
const int dsize = 10;
struct copy_func {
int threshold;
copy_func(int thr) : threshold(thr) {};
__host__ __device__
bool operator()(const my_score &x){
return (x.score > threshold);
}
};
int main(){
thrust::host_vector<my_score> h_data(dsize);
thrust::device_vector<my_score> d_result(dsize);
int my_threshold = 50;
for (int i = 0; i < dsize; i++){
h_data[i].id = i;
h_data[i].score = i * 10;}
thrust::device_vector<my_score> d_data = h_data;
int rsize = thrust::copy_if(d_data.begin(), d_data.end(), d_result.begin(), copy_func(my_threshold)) - d_result.begin();
std::cout << "There were " << rsize << " entries with a score greater than " << my_threshold << std::endl;
return 0;
}
$ nvcc -o t688 t688.cu
$ ./t688
There were 4 entries with a score greater than 50
$