我正在尝试CUDA编程的“hello world”程序:将两个向量相加。这是我尝试的程序:
#include <cuda.h>
#include <stdio.h>
#define SIZE 10
__global__ void vecAdd(float* A, float* B, float* C)
{
int i = threadIdx.x;
C[i] = A[i] + B[i];
}
int main()
{
float A[SIZE], B[SIZE], C[SIZE];
float *devPtrA, *devPtrB, *devPtrC;
size_t memsize= SIZE * sizeof(float);
for (int i=0; i< SIZE; i++) {
A[i] = i;
B[i] = i;
}
cudaMalloc(&devPtrA, memsize);
cudaMalloc(&devPtrB, memsize);
cudaMalloc(&devPtrC, memsize);
cudaMemcpy(devPtrA, A, memsize, cudaMemcpyHostToDevice);
cudaMemcpy(devPtrB, B, memsize, cudaMemcpyHostToDevice);
vecAdd<<<1, SIZE>>>(devPtrA, devPtrB, devPtrC);
cudaMemcpy(C, devPtrC, memsize, cudaMemcpyDeviceToHost);
for (int i=0; i<SIZE; i++)
printf("C[%d]: %f + %f => %f\n",i,A[i],B[i],C[i]);
cudaFree(devPtrA);
cudaFree(devPtrB);
cudaFree(devPtrC);
}
编译:
nvcc cuda.cu
输出是这样的:
C[0]: 0.000000 + 0.000000 => 0.000000
C[1]: 1.000000 + 1.000000 => 0.000000
C[2]: 2.000000 + 2.000000 => 0.000000
C[3]: 3.000000 + 3.000000 => 0.000000
C[4]: 4.000000 + 4.000000 => 0.000000
C[5]: 5.000000 + 5.000000 => 0.000000
C[6]: 6.000000 + 6.000000 => 0.000000
C[7]: 7.000000 + 7.000000 => 0.000000
C[8]: 8.000000 + 8.000000 => 366987238703104.000000
C[9]: 9.000000 + 9.000000 => 0.000000
每次我运行它时,我得到一个不同的答案C [8],但所有其他元素的结果总是0.000000。
Ubuntu 11.04系统是一个64位Xeon服务器,带有4个内核,运行最新的NVIDIA驱动程序(2012年10月4日下载)。该卡是EVGA GeForce GT 430,具有96核和1GB RAM。
我该怎么做才能弄明白发生了什么?
答案 0 :(得分:5)
似乎您的驱动程序未初始化,但是不检查cuda返回代码始终是一种不好的做法,您应该避免这种情况。这是一个简单的函数+宏,你可以用于cuda调用(引自Cuda的例子):
static void HandleError( cudaError_t err,
const char *file,
int line ) {
if (err != cudaSuccess) {
printf( "%s in %s at line %d\n", cudaGetErrorString( err ),
file, line );
exit( EXIT_FAILURE );
}
}
#define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ ))
现在开始调用你的函数:
HANDLE_ERROR(cudaMemcpy(...));
答案 1 :(得分:1)
最有可能原因:未加载NVIDIA驱动程序。在无头的Linux系统上,X Windows没有运行,因此在启动时不会加载驱动程序。
以root身份运行nvidia-smi -a
以加载它们并以报告的形式获得确认。
虽然现在加载了驱动程序,但每次运行CUDA程序时仍需要初始化它们。使用nvidia-smi -pm 1
将驱动程序置于持久模式,以便它们始终保持初始化状态。将其添加到启动脚本(例如rc.local)中,以便在每次启动时都会发生。