【发布时间】:2017-07-12 23:44:41
【问题描述】:
第一篇文章在这里。我目前正在做一个项目,该项目需要将一个大型二维数组(大约 1,000,000x7)写入我的 GPU,进行一些计算,然后将其返回给主机。由于我想用如此大的数组快速完成,我尝试将数组展平以帮助将其相当直接地传递到 GPU。数组成功写入(或者当我写入设备时,至少 cudaMalloc 和 cudaMemcpy 都返回 cudaSuccess),但是当我尝试读取它时,cudaMemcpy 返回一个无效参数错误。
我无法弄清楚为什么会这样,因为我认为我应该在设备上写入一个有效的一维数组(展平)并将其读回,并且我认为我提供了正确的论点这个。我在网上找到的这个错误的唯一结果涉及将 dst 和 src 参数交换为 cudaMemcpy,但我想我已经找到了。
这是重现问题的我的代码的简化版本:
#include <iostream>
using namespace std;
void alloc2dArray(float ** &arr, unsigned long int rows, unsigned long int cols){
arr = new float*[rows];
arr[0] = new float[rows * cols];
for(unsigned long int i = 1; i < rows; i++) arr[i] = arr[i - 1] + cols;
}
void write2dArrayToGPU(float ** arr, float * devPtr, unsigned long int rows, unsigned long int cols){
if(cudaSuccess != cudaMalloc((void**)&devPtr, sizeof(float) * rows * cols)) cerr << "cudaMalloc Failed";
if(cudaSuccess != cudaMemcpy(devPtr, arr[0], sizeof(float) * rows * cols, cudaMemcpyHostToDevice)) cerr << "cudaMemcpy Write Failed";
}
void read2dArrayFromGPU(float ** arr, float * devPtr, unsigned long int rows, unsigned long int cols){
if(cudaSuccess != cudaMemcpy(arr[0], devPtr, sizeof(float) * rows * cols, cudaMemcpyDeviceToHost)) cerr << "cudaMemcpy Read Failed" << endl;
}
int main(){
int R = 100;
int C = 7;
cout << "Allocating an " << R << "x" << C << " array ...";
float ** arrA;
alloc2dArray(arrA, R, C);
cout << "Assigning some values ...";
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
arrA[i][j] = i*C + j;
}
}
cout << "Done!" << endl;
cout << "Writing to the GPU ...";
float * Darr = 0;
write2dArrayToGPU(arrA, Darr, R, C);
cout << " Done!" << endl;
cout << "Allocating second " << R << "x" << C << " array ...";
float ** arrB;
alloc2dArray(arrB, R, C);
cout << "Done!" << endl;
cout << "Reading from the GPU into the new array ...";
read2dArrayFromGPU(arrB, Darr, R, C);
}
我用
在我的笔记本电脑上编译并运行它 $nvcc -arch=sm_30 test.cu -o test
$optirun cuda-memcheck ./test
并得到结果:
========= CUDA-MEMCHECK
Allocating an 100x7 array ...Assigning some values ...Done!
Writing to the GPU ... Done!
Allocating second 100x7 array ...Done!
========= Program hit cudaErrorInvalidValue (error 11) due to "invalid argument" on CUDA API call to cudaMemcpy.
========= Saved host backtrace up to driver entry point at error
Reading from the GPU into the new array ...========= Host Frame:/usr/lib64/nvidia-bumblebee/libcuda.so.1 [0x2ef343]
cudaMemcpy Read Failed========= Host Frame:./test [0x38c6f]
========= Host Frame:./test [0x2f08]
========= Host Frame:./test [0x3135]
========= Host Frame:/usr/lib64/libc.so.6 (__libc_start_main + 0xf1) [0x20401]
========= Host Frame:./test [0x2c6a]
=========
========= ERROR SUMMARY: 1 error
我对 CUDA 比较陌生,还在学习中,因此我们将不胜感激,谢谢!
【问题讨论】:
-
CUDA 与 C 无关。
-
您不能将
devPtr作为单个指针参数传递给函数,在该指针上执行cudaMalloc,然后期望分配的指针值显示在调用环境。这是传递值的常见错误,当然还有其他类似的问题。如this one。您可能想在那里研究答案,您的问题可以说是那个问题的重复。