CUDA does not support using vector directly inside kernel functions, so the vector data normally has to be copied into a dynamic array before computing.
Here we show how to convert vector data into a dynamic array and pass it to a kernel for computation.
- 1D
vector<int> b;
int* a;
cudaMalloc((void**)& a, sizeof(int) * b.size());
cudaMemcpy(a, &b[0],sizeof(int) * b.size(), cudaMemcpyHostToDevice);
- 2D is more cumbersome, because each inner vector (each row) has to be handled in a loop; an intermediate 2D array is used to hold the pointers
vector<vector<int>> d;
int ** a_2d = new int* [d.size()];
int * a_2d_cu;
for (int i = 0; i < d.size(); i++){
int* devPtr;
int length = d[i].size();
cudaMalloc((void**)& devPtr, sizeof(int)*length);
cudaMemcpy(devPtr, &d[i], sizeof(int)*length, cudaMemcpyHostToDevice);
a_2d[i] = devPtr; //first store the pointers to CUDA memory in an array in host memory
}
cudaMalloc((void**)& a_2d_cu, sizeof(int*)*d.size());
cudaMemcpy(a_2d_cu, a_2d, sizeof(int*)*d.size(), cudaMemcpyHostToDevice);
The cudaMalloc here can be further replaced with cudaMallocPitch and cudaMemcpy2D
//this aligns memory; for 2D arrays whose size is not a multiple of 32, this works better
size_t pitch;
cudaMallocPitch(& a_2d_cu, &pitch, d[0].size()*sizeof(int), d.size()));
cudaMemcpy2D(a_2d_cu, pitch, a_2d, d[0].size()*sizeof(int), d[0].size()*sizeof(int), d.size(), cudaMemcpyHostToDevice);