Search code examples
c++11thrust

"Warning : Non-POD class type passed through ellipsis" for simple thrust program


In spite of reading many answers on the same kind of questions on SO I am not able to figure out solution in my case. I have written the following code to implement a thrust program. Program performs simple copy and display operation.

#include <stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>


int main(void)
{
// H has storage for 4 integers
  thrust::host_vector<int> H(4);
  H[0] = 14;
  H[1] = 20;
  H[2] = 38;
  H[3] = 46;

  // H.size() returns the size of vector H
  printf("\nSize of vector : %d",H.size());
  printf("\nVector Contents : ");
  for (int i = 0; i < H.size(); ++i) {
      printf("\t%d",H[i]);
  }

  thrust::device_vector<int> D = H;
  printf("\nDevice Vector Contents : ");
  for (int i = 0; i < D.size(); i++) {
      printf("%d",D[i]);         //This is where I get the warning.
  }

  return 0;
}

Solution

  • Thrust implements certain operations to facilitate using elements of a device_vector in host code, but this apparently isn't one of them.

    There are many approaches to addressing this issue. The following code demonstrates 3 possible approaches:

    1. explicitly copy D[i] to a host variable, and thrust has an appropriate method defined for that.
    2. copy the thrust device_vector back to a host_vector before print-out.
    3. use thrust::copy to directly copy the elements of the device_vector to a stream.

    Code:

    #include <stdio.h>
    #include <iostream>
    #include <thrust/host_vector.h>
    #include <thrust/device_vector.h>
    #include <thrust/copy.h>
    
    
    int main(void)
    {
    // H has storage for 4 integers
      thrust::host_vector<int> H(4);
      H[0] = 14;
      H[1] = 20;
      H[2] = 38;
      H[3] = 46;
    
      // H.size() returns the size of vector H
      printf("\nSize of vector : %d",H.size());
      printf("\nVector Contents : ");
      for (int i = 0; i < H.size(); ++i) {
          printf("\t%d",H[i]);
      }
    
      thrust::device_vector<int> D = H;
      printf("\nDevice Vector Contents : ");
    //method 1
      for (int i = 0; i < D.size(); i++) {
          int q = D[i];
          printf("\t%d",q);
      }
      printf("\n");
    //method 2
      thrust::host_vector<int> Hnew = D;
      for (int i = 0; i < Hnew.size(); i++) {
          printf("\t%d",Hnew[i]);
      }
      printf("\n");
    //method 3
      thrust::copy(D.begin(), D.end(), std::ostream_iterator<int>(std::cout, ","));
      std::cout << std::endl;
    
      return 0;
    }
    

    Note that for methods like these, thrust is generating various kinds of device-> host copy operations to facilitate the use of device_vector in host code. This has performance implications, so you might want to use the defined copy operations for large vectors.