【问题标题】:CUDA code compile on Linux but not in Windows ( Visual Studio 2012)CUDA 代码可在 Linux 上编译,但不能在 Windows 上编译(Visual Studio 2012)
【发布时间】:2019-07-10 14:24:50
【问题描述】:

我正在开发一个使用 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];

在最后一行我有错误:

错误:表达式必须有一个常量值

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

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

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

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

错误:设备代码中未定义“PI”

错误:设备代码中未定义“EPS”

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

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

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

【问题讨论】:

  • 第一个问题描述为here,与CUDA无关。
  • 第二个问题是与微软主机编译器一起使用时 CUDA 的枚举限制,请参阅here
  • 第一个问题是你的程序不是标准的 C++,它只是 g++。在 Linux 上编译时尝试传递 -pedantic-ansi 选项,以帮助您更早地发现这些问题。

标签: c++ visual-studio-2012 compiler-errors cuda


【解决方案1】:

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

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

我不知道任何不涉及对代码进行一些更改以实现跨平台兼容性的解决方法。但是少量的(C 或)C++ 编程技能可以为您提供一个可以在 linux 或 windows 上工作的解决方案:

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

(如果您想使用符合 C 标准的方法,您可以以类似的方式使用 malloc

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

据我所知,也没有任何方法可以解决这个跨平台问题,这不涉及对您的代码进行任何更改。

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

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

【讨论】:

  • 第一个问题的链接是关于使用 Microsoft 编译器编译 C 程序(允许使用 VLA)。这个问题是关于一个 C++ 程序的,其中根本没有 VLA 这样的东西。
  • @BenVoigt 我不反对,但在 Linux 上,at least with gnu,g++ 编译器似乎允许在 C++ 程序中使用 VLA。我怀疑这部分是 OP 的问题的根源,因为他们目睹了使用 nvcc 编译时在 Linux 上运行的 VLA,它在后台使用 g++ 进行主机代码编译,这就是这里的观点。我将编辑我的答案以对此进行参考,但我认为此答案中的扩展讨论不会增加任何清晰度。
  • 你的新链接更好,因为它反映了这不应该工作,而第一个链接说它是一个缺失的功能。
  • 编辑了我的答案,如果您想更好地解释它,请随时编辑它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多