【发布时间】:2012-07-13 06:02:53
【问题描述】:
我是一名 CUDA 初学者,已使用 CUFFT 和 CUBLAS 等 CUDA 库成功编译并运行了多个代码示例。然而,最近,我一直在尝试生成自己的简单内核,并且在调用我的内核后反复收到无意义的值。也就是说——当我将参数传递到内核中,在内核中设置它的值,然后尝试将结果复制回主机并稍后读取这些值时,它们是假的。我尝试了许多不同的简单教程内核,这些内核似乎适用于大多数在线用户,但我总是得到无意义的值。比如……
#define SIZE 10
// Kernel definition, see also section 4.2.3 of Nvidia Cuda Programming Guide
__global__ void vecAdd(float* A, float* B, float* C) {
// threadIdx.x is a built-in variable provided by CUDA at runtime
int i = threadIdx.x;
A[i]=0;
B[i]=i;
C[i] = A[i] + B[i];
}
int main {
int N=SIZE;
float A[SIZE], B[SIZE], C[SIZE];
float *devPtrA;
float *devPtrB;
float *devPtrC;
int memsize= SIZE * sizeof(float);
cudaMalloc((void**)&devPtrA, memsize);
cudaMalloc((void**)&devPtrB, memsize);
cudaMalloc((void**)&devPtrC, memsize);
cudaMemcpy(devPtrA, A, memsize, cudaMemcpyHostToDevice);
cudaMemcpy(devPtrB, B, memsize, cudaMemcpyHostToDevice);
// __global__ functions are called: Func<<< Dg, Db, Ns >>>(parameter);
vecAdd<<<1, N>>>(devPtrA, devPtrB, devPtrC);
cudaMemcpy(C, devPtrC, memsize, cudaMemcpyDeviceToHost);
for (int i=0; i<SIZE; i++)
printf("C[%d]=%f\n",i,C[i]);
cudaFree(devPtrA);
cudaFree(devPtrA);
cudaFree(devPtrA);
}
这是一个相当简单的问题;结果应该是:
C[0]=0.000000
C[1]=1.000000
C[2]=2.000000
C[3]=3.000000
C[4]=4.000000
C[5]=5.000000
C[6]=6.000000
C[7]=7.000000
C[8]=8.000000
C[9]=9.000000
然而,我很棒的结果总是随机的,通常看起来更像:
C[0]=nan
C[1]=-32813464158208.000000
C[2]=nan
C[3]=-27667211200843743232.000000
C[4]=34559834084263395806523272811251761152.000000
C[5]=9214363188332593152.000000
C[6]=nan
C[7]=-10371202300694685655937271382147072.000000
C[8]=121653576586393934243511643668480.000000
C[9]=-30648783863808.000000
所以基本上,当我将参数传递到 CUDA 内核并打算在其中存储结果以复制回主机时,我往往会遇到垃圾。
这个真的把我难住了。任何帮助将不胜感激。
谢谢。
【问题讨论】:
-
您是否先在仿真模式下测试过代码?
-
您可能应该将您对
cudaMalloc和cudaMemcpy的调用与CUDA_SAFE_CALL括起来,因为目前您没有进行任何错误检查。 -
我刚刚将 -deviceemu 参数添加到 NVCC 并收到警告,“选项 'device-emulation' 已被弃用并被忽略”。谷歌搜索表明不再支持仿真,还是我的做法不正确?
-
@nedblorf:真可惜——我已经有一段时间没有做过任何 CUDA 工作了,但仿真模式一直是一种有用的调试技术。我想我听说最新的 CUDA 工具现在包括一个调试器?您可能不得不尝试这样做。
-
顺便说一句,只是出于好奇,你在 A 和 B 中也有垃圾吗?