cuda 11 内核无法运行

gov*_*sky 2 printf cuda nvidia

这是demo.cu从 GPU 设备打印的目标:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

__global__ void hello_cuda() {
        printf("hello from GPU\n");
}

int main() {
        printf("hello from CPU\n");
        hello_cuda <<<1, 1>>> ();
        cudaDeviceSynchronize();

        cudaDeviceReset();
        printf("bye bye from CPU\n");
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

它编译并运行:

$ nvcc demo.cu
$ ./a.out
Run Code Online (Sandbox Code Playgroud)

这就是我得到的输出:

hello from CPU
bye bye from CPU
Run Code Online (Sandbox Code Playgroud)

问:为什么GPU没有打印结果?

看起来我确实错误配置了 cuda 工具包或其他东西,但是我可以从 cuda-samples 编译并运行各种程序。例如,matrixMuldeviceQuery

Rob*_*lla 9

如果您的设备的计算能力为 3.0 或更低,则 CUDA 11 会放弃对这些 GPU 的支持。您需要使用先前的 CUDA 版本

CUDA 编译器必须针对 GPU 目标(即设备架构)进行编译。如果你没有在编译命令行上指定目标架构,历史上,CUDA选择了一个非常灵活的默认架构规范,可以在CUDA版本支持的所有GPU上运行。

然而,情况并非总是如此,CUDA 11 也并非如此。CUDA 11(和 CUDA 12)针对默认架构sm_52(计算能力 5.2,即就像您-arch=sm_52在命令行上指定的那样)进行编译。但 CUDA 11 支持低至sm_35(计算能力 3.5)的架构。(CUDA 12 已放弃对 sm_3x GPU 的支持。)

因此,如果您没有在 CUDA 11 的编译命令行上指定目标架构,并尝试在具有早于 CUDA 11 之前的架构的 GPU 上运行sm_52,则您编写的任何 CUDA 代码(内核)肯定无法工作。

每当您在使用 CUDA 代码时遇到问题时,使用适当的 CUDA 错误检查都是一个很好的做法,如果您在这里这样做,您将得到一个运行时错误指示,该指示将立即识别问题(至少对于那些熟悉 CUDA 错误)。

这些情况下的解决方案是指定一个编译命令,其中包括您打算运行的 GPU(无论如何,这通常是一个很好的做法)。如果您这样做,并且您指定的架构已“弃用”,那么nvcc编译器将发出警告,让您知道未来的 CUDA 版本可能不支持您尝试运行的 GPU。该警告并不意味着您所做的任何事情是错误的或非法的或需要更改,而是意味着将来的 CUDA 版本可能不支持该 GPU。

如果您想抑制该警告,可以-Wno-deprecated-gpu-targets在编译命令行上传递开关。

当然,同样的问题也可能发生在 Windows 上。在这种情况下,您需要修改以下 VS 项目设置以匹配您的设备的体系结构:

在此输入图像描述