【问题标题】:CUDA, code works on one GPU machine, doesn't work on anotherCUDA,代码在一台 GPU 机器上工作,在另一台机器上不工作
【发布时间】:2014-06-03 10:14:20
【问题描述】:

我对下面sn-p的行为感到困惑:

 #include <stdio.h>

// kernel
__global__ void CheckAddressing(float * d_Result, int numCols, int numRows)
{
    printf("%d\n", threadIdx.x);
    if(threadIdx.x<16)
    {
        d_Result[threadIdx.x]=float(364.66);

    }
}


////////

int main(int argc, char ** argv)
{
    int TotalSize = 16;
    float * d_Result;

    float * h_Result;

        cudaSetDevice(0);

    h_Result = (float *)malloc(TotalSize*sizeof(float));
    cudaMalloc((void **) &d_Result, TotalSize*sizeof(float));
    CheckAddressing<<<dim3(1),dim3(16)>>>(d_Result, 8,8);


    cudaMemcpy(h_Result, d_Result, TotalSize*sizeof(float), cudaMemcpyDeviceToHost);

    for(int n=0; n<16; n++)
    {
        printf("%f\t", h_Result[n]);
    }
        printf("\n");


// free GPU memory
        cudaFree(d_Result);
        free(h_Result);
    return 0;

}

它可以在一台机器上运行(我使用nvcc -arch=sm_30 编译)并返回 364.66(16 次)。然而,在另一台运行 Cuda 5.5 的机器上,它返回全零。知道会发生什么吗?

更新:

cuda-memcheck ./test
========= CUDA-MEMCHECK
0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    0.000000    
========= ERROR SUMMARY: 0 errors

nvidia-smi
Fri Apr 18 14:45:05 2014       
+------------------------------------------------------+                       
| NVIDIA-SMI 331.44     Driver Version: 331.44         |                       
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K20Xm         Off  | 0000:02:00.0     Off |                    0 |
| N/A   20C    P0    50W / 235W |     11MiB /  5759MiB |     99%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Compute processes:                                               GPU Memory |
|  GPU       PID  Process name                                     Usage      |
|=============================================================================|
|  No running compute processes found                                         |
+-----------------------------------------------------------------------------+

【问题讨论】:

  • 最简单的找出方法是添加一些错误检查。每个 API 调用(和内核启动)都会返回或报告一个状态。检查这些将解释正在发生的事情。
  • 我在运行代码时正在执行cudamemcheck。检查错误是否足够?如果不是,获取错误报告的正确方法是什么?
  • 您在返回全零的机器上运行代码,而cuda-memcheck 报告零错误?你能显示你的实际调用和那台机器的实际输出吗? (将其粘贴到您的问题中)。机器配置和操作系统是什么?
  • 罗伯特,机器是狄拉克@Nersc。我以交互方式登陆其中一个节点 (nersc.gov/users/computational-systems/testbeds/dirac),编译代码,然后以相同的交互模式运行它。我也在联系 nersc 支持,但我认为我的代码可能有错误,看起来不像那样。如果我不在主机阵列上执行malloc 而只是执行float h_Result[16],则相同的代码会给出随机数

标签: c cuda gpu gpgpu


【解决方案1】:

Dirac 在its banner 上提到了 Fermi GPU。如果您在使用 Fermi GPU 的节点上,则您的编译命令不正确:

-arch=sm_30 

用于 Kepler GPU。

试试:

-arch=sm_20

改为。

cuda-memcheck 没有报告错误,但您遇到的错误类型是 cuda-memcheck 不一定会捕获的类型,这让我感到困惑。具体来说,有一类启动失败错误只能被@talonmies 建议的proper cuda error checking 捕获。请特别注意内核启动后立即需要的错误检查代码。

当您为 -arch=sm_30 编译并尝试在 Fermi (sm_20) 机器上运行它时,内核启动将立即失败,但所有其他后续 CUDA API 调用都不会报告失败。

detail page for Dirac 确实提到了几个 Kepler 节点/GPU:

•1 个节点:Tesla K20Xm

•1 个节点:Tesla K40c

我相信您使用-arch=sm_35 编译的代码应该可以在这些节点上正确运行。

我还注意到,甚至还有一些较旧的(“特斯拉”系列)GPU/节点:

•4 个节点:1 个 C1060 NVIDIA Tesla GPU,具有 4GB 内存和 240 个并行 CUDA 处理器内核。

• 1 个节点:4 个 C1060 Nvidia Tesla GPU,每个具有 4GB 内存和 240 个并行 CUDA 处理器内核。

对于这些节点,您需要编译:

-arch=sm_13

但不要忘记使用正确的 cuda 错误检查,任何时候您在使用 CUDA 代码时遇到困难。

或者您可以使用nvcc extended notation 为所有 3 种类型指定编译和二进制/可执行文件。

使用扩展符号,针对该集群上的 3 个不同 GPU 架构(我可以看到):

nvcc -gencode arch=compute_13,code=sm_13 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_35,code=sm_35 ...

【讨论】:

  • 我尝试了-arch=sm_20 并且没有指定arch。仍然得到全零。这很令人困惑
  • 这会令人困惑,因为您在该机器中至少有 3 种不同的节点类型,并且您可能想要在这 3 种类型中的任何一种上运行的代码。为此,我建议使用扩展符号。
  • 对于您所在的开普勒节点(根据您的nvidia-smi 输出),您也可以尝试-arch=sm_35
  • 您在答案(最后一行)中提到的扩展符号终于给了我需要的结果。谢谢你,罗伯特,非常感谢你的帮助!
  • 是的,我确实认为发生了其他事情。添加 cuda 错误检查可能是有益的。交互式作业和非交互式作业之间可能存在机器配置差异(模块等)。 K20 GPU 应该能够运行使用-arch=sm_20-arch=sm_30-arch=sm_35 编译的代码。我刚才自己试了一下,用你的代码确认。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多