CUDA 编译器无法检测到(GPU)设备上调用的主机函数

问题描述 投票:0回答:2

请看这段代码:

void bar() {}

__host__ __device__ void foo()
{
  bar();
}

__global__ void kernel()
{
  foo();
}

int main()
{
  kernel<<<1, 1>>>();
  gpuErrchk(cudaPeekAtLastError());

  gpuErrchk(cudaDeviceSynchronize());

  return 0;
}

我花了几个小时试图解决

an illegal memory access was encountered
运行时错误。事实证明,原因是
bar()
函数 - 它没有声明为
__device__
。但!但是代码可以编译!它会产生警告,但可以编译!警告说:

warning: calling a __host__ function("bar") from a __host__ __device__
function("Test::foo") is not allowed

由于我的项目编译产生了大量输出,所以我根本没有看到该警告。但是,如果我从

__device__
函数中删除
foo()
属性,我会得到预期的错误:

error: identifier "foo" is undefined in device code

问题是为什么编译器只打印警告以及如何将其变成错误

cuda
2个回答
4
投票

问题是为什么编译器只打印警告以及如何将其变成错误?

编译器仅打印一条警告,因为它不知道(在编译调用函数时)该函数是否实际上会在运行时以令人反感的配置(即在设备代码上或从设备代码)被调用。

以及如何将其变成错误?

nvcc 手册,您可以添加:

-Werror all-warnings

将所有警告标记为错误

-Werror cross-execution-space-call

仅将此类警告标记为错误。

另请参阅此处。对于那些会问我为什么没有标记为骗子的人来说,其他问题不包含关于编译器为何如此行为的问题(或答案本身)。


-3
投票

我花了几个小时试图解决这个...错误。 ...但是代码可以编译!它会产生警告,但可以编译!

您需要重新审视您的调试方法:-(

任何您尚未向自己“积极证明”的警告都是无关紧要的 - 您需要在其中查找错误。解决警告比证明警告无效要容易得多,也更有价值。 (通过解决,我的意思是解决根本条件,而不是抑制警告或 const_cast'ing 等) 所以,不要用编译器

将警告变成错误

,而是将它们变成你心中的本质错误。干净、无警告的代码=幸福的生活。

© www.soinside.com 2019 - 2024. All rights reserved.