【问题标题】:Can't get simple CUDA program to work无法让简单的 CUDA 程序工作
【发布时间】:2012-11-11 08:10:51
【问题描述】:

我正在尝试 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 日下载)。该卡是具有 96 个内核和 1GB 内存的 EVGA GeForce GT 430。

我应该怎么做才能弄清楚发生了什么?

【问题讨论】:

  • 您是否从here 安装了cuda sdk? (不是工具包)
  • 我的猜测是 CUDA 无法初始化。我建议为每个 CUDA API 调用添加错误检查。
  • @gokcehan 我从那个网站下载了驱动程序、工具包和 SDK。不过,我不确定如何处理 SDK。它似乎主要包含文档和示例代码。
  • 我记得工具包包含编译器 (nvcc) 而 SDK 包含库。我记得有一个类似的问题,因为我没有安装其中之一。奇怪的是,在不安装 SDK 的情况下尝试运行它并没有报错。
  • 编译和运行CUDA代码不需要SDK。如果您使用 SDK 中的某些内容,例如某些 SDK 中的 cutil,那么您当然需要它。但是您的代码似乎对 SDK 没有任何依赖关系。您的工具包安装可能没问题,因为您可以使用 nvcc 进行编译。这留下了 GPU 和驱动程序。 @njuffa 的评论绝对值得推荐,并且始终是一种很好的做法。您还可以从 linux 命令行运行 nvidia-smi -a 以查看 GPU 是否正常可用。

标签: cuda


【解决方案1】:

您的驱动程序似乎未初始化,但不检查 cuda 返回代码始终是一种不好的做法,您应该避免这种做法。这是可用于 cuda 调用的简单函数 + 宏(引自 Cuda by Example):

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(...));

【讨论】:

    【解决方案2】:

    最可能的原因:未加载 NVIDIA 驱动程序。在无头 Linux 系统上,X Windows 没有运行,因此在启动时不会加载驱动程序。

    以 root 身份运行 nvidia-smi -a 以加载它们并以报告的形式获得确认。

    虽然驱动程序现在已加载,但每次运行 CUDA 程序时仍需要对其进行初始化。使用nvidia-smi -pm 1 将驱动程序置于持久模式,以便它们始终保持初始化状态。将此添加到启动脚本(例如 rc.local)中,以便在每次启动时发生。

    【讨论】:

    • 值得指出的是,Linux 发行说明和/或 Linux 入门 PDF 中已经明确涵盖了该问题的解决方案。
    • 很高兴知道这一点。如果只有 NVIDIA 驱动程序的安装程序将我指向那里。相反,它说“请参阅您的供应商发行版的文档”,并且 Ubuntu 的文档假设每个人都在运行 GUI。
    猜你喜欢
    • 2017-08-09
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 2015-07-09
    相关资源
    最近更新 更多