Search code examples
c++cudathrust

Is it possible to create a thrust's function predicate for structs using a given parameter?


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);
    }
};

Solution

  • 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
    $