例如,我分配這些以下指導:在CUDA中,如何將設備指針數組複製到設備內存?
float *data_1, *data_2, *data_3, *data_4;
//Use malloc to allocate memory and fill out some data to these pointers
......
//Filling complete
float *data_d1,*data_d2,*data_d3,*data_d4;
cudaMalloc((void **)&data_d1,size1);
cudaMalloc((void **)&data_d2,size2);
cudaMalloc((void **)&data_d3,size3);
cudaMalloc((void **)&data_d4,size4);
cudaMemcpy(data_d1,data_1,size1,cudaMemcpyHostToDevice);
cudaMemcpy(data_d2,data_2,size2,cudaMemcpyHostToDevice);
cudaMemcpy(data_d3,data_3,size3,cudaMemcpyHostToDevice);
cudaMemcpy(data_d4,data_4,size4,cudaMemcpyHostToDevice);
在此之後,我應該已經得到包含確切的數據4個設備指針作爲主機指針做。現在,我想這些指針存儲到指針的一個陣列,如下圖所示
float *ptrs[4];
ptrs[0] = data_d1;
ptrs[1] = data_d2;
ptrs[2] = data_d3;
ptrs[3] = data_d4;
現在我想把這個數組指針轉移到CUDA內核。但是,我知道由於ptrs [4]實際上是在主機內存上,所以我需要在設備上分配一個新的指針。調試時
if (threadIdx.x < length_of_data_1d)
{
float element0 = (ptrs[0])[threadIdx.x];
}
編譯是好的,但是:所以我這樣做,
float **ptrs_d;
size_t size = 4 * sizeof(float*);
cudaMalloc((void ***)&ptrs_d,size);
cudaMemcpy(ptrs_d,ptrs,size,cudaMemcpyHostToDevice);
,然後調用內核:
kernel_test<<<dimGrid,dimBlock>>>(ptrs_d, ...);
//Declaration should be
//__global__ void kernel_test(float **ptrs_d, ...);
在kernel_test,在下面的語法加載數據它會給出訪問衝突的錯誤。
也許我的代碼中有很多錯誤。但我只想弄清楚爲什麼我不能以這種方式傳遞設備指針,以及如果CUDA允許將設備指針數組傳遞給內核函數,那麼訪問它的正確方法是什麼。
那麼我該如何解決這個問題呢?任何建議表示讚賞。提前致謝。
我沒有看到任何明顯的問題與您的方法。我圍繞你所展示的內容構建了一個簡單的代碼,它似乎對我來說是正確的,它是[這裏](http://pastebin.com/n1S63xLb)。根據數據的長度,您的訪問衝突可能僅僅是一個數組超出範圍,以及您在此未顯示的一些代碼。它可能沒有任何關於複製設備指針數組的基本方法。我建議你提供一個完整的代碼來重現問題,而不是一連串的片段。問題在於你沒有在這裏顯示的東西。 –
非常感謝您的建議。我嘗試了幾次調試,最後得知這種方法實際上是適用的。真正的問題似乎最有可能是你提出的現在我想弄明白的越界問題。再次感謝您的響應式幫助。 –
當然,使用調試器運行應該可以讓您瞭解發生了什麼問題。用'cuda-memcheck'運行你的代碼也可以解決這個問題。 –