CUDA 代码在 Linux 上编译但不在 Windows 上编译(Visual Studio 2012)

CUDA code compile on Linux but not in Windows ( Visual Studio 2012)

我正在开发一个使用 CUDA 开发工具包版本 10.1 的程序,我使用的是 visual studio 2012。 我正在研究 windows,但我与 linux 用户共享代码。所有代码在这两种情况下都可以正常工作,除了某些代码行在 linux 上有效但在 windows 上无效。所以每次我都必须更改这些行。我会避免这样做,事实上 linux 上的代码编译得很好,我认为 windows 上的代码无法编译是有一些原因的,但这些原因肯定与代码但关于一些 visual studio 设置或类似的。你能帮助我吗? 特别是代码行是:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp props[n_devices];

在最后一行我有错误:

error: expression must have a constant value

我可以修复这个定义 const int n_devices = 1; 和注释函数 cudaGetDeviceCount(&n_devices); 的错误。它之所以有效,是因为我已经知道正确数量的设备,但可以肯定的是,解决方案不如前一个正确。

另一个问题是我有一个 utils.cuh 文件,其中定义了两个常量值

const float PI = 3.141592654f;
const float EPS = 1e-3f;

我在 utils.cu 文件中调用这两个值,但在编译时出现错误:

error: "PI" is undefined in device code

error: "EPS" is undefined in device code

我可以用这种方式声明这两个变量来解决这个问题:

#define PI 3.141592654f
#define EPS 1e-3f

所以即使我可以解决所有这两个问题,我真的想将代码保留在第一个配置中(因为它适用于 linux)。可能是与编译器版本有关的问题?真不知道是什么原因。

您无法仅通过更改编译器版本或类似的方式解决这些问题。

描述了第一个问题 here and ,它与 CUDA 无关,除非 CUDA 使用主机编译器。您显示的代码使用了 VLA(可变长度数组),它是 C99 标准的一部分,但不是任何 C++ 标准的一部分。 CUDA主要是基于C++实现的,利用C++主机编译器来编译主机代码,这就是你所展示的。在 windows 上,它为此使用 Microsoft 编译器。所以 Microsoft 编译器禁止 VLA 是正确的,并且没有办法避免这个 AFAIK。您的代码适用于 linux,因为 linux nvcc 使用 g++ 主机编译器,并且它允许(以 non-standard-compliant 方式)使用 VLA在 C++ 主机代码中。

为了 cross-platform 兼容性,我不知道有什么方法可以在不对您的代码进行一些更改的情况下解决这个问题。但是少量的(C 或)C++ 编程技能可以为您提供一个解决方案,该解决方案应该适用于 linux 或 windows:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp *props = new cudaDeviceProp[n_devices];

(如果你想使用 C 兼容的方法,你可以以类似的方式使用 malloc

第二个问题是 CUDA 的限制,已记录 here

据我所知,也没有解决此问题的方法 cross-platform,无需更改您的代码。

您已经确定了一种可以在 linux 和 windows 上以 cross-platform 方式工作的可能解决方法:

#define PI 3.141592654f
#define EPS 1e-3f