为什么编译器无法检测到在设备上调用了主机函数,如何解决?
Why the compiler can't detect that a host function is called on the device, and how to fix it?
请看这段代码:
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
由于我的项目的编译产生了很多输出,所以我根本没有看到那个警告。但是如果我从 foo()
函数中删除 __device__
属性,我会得到预期的错误:
error: identifier "foo" is undefined in device code
问题是为什么编译器只打印 warning 以及如何将它变成 error?
The question is why the compiler prints only a warning and how to turn it into an error?
编译器只打印一条警告,因为它不知道(在编译调用函数时)该函数是否会在运行时以令人反感的配置(即在设备代码上或从设备代码中)实际调用.
and how to turn it into an error?
从 nvcc manual 您可以添加:
-Werror all-warnings
将所有警告标记为错误
或
-Werror cross-execution-space-call
仅将此类警告标记为错误。
另见 here。对于那些会问为什么我没有标记为受骗者的人,另一个问题不包括关于编译器为何以这种方式运行的问题(或答案本身)。
I spent hours trying to solve the... error. ... But the code compiles! It produces a warning, but compiles!
您需要重新审视您的调试方法:-(
任何您尚未积极证明 给您自己的警告都是无关紧要的 - 是您需要查找错误的地方。解决警告比证明它们无效要容易得多,也更有回报。 (通过解决,我的意思是解决潜在的条件,而不是抑制警告,或者 const_cast'ing 等)
所以,不要用编译器将警告变成错误,而是将它们变成essentially-errors 在你的脑海中。干净,warning-free代码=快乐生活。
请看这段代码:
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
由于我的项目的编译产生了很多输出,所以我根本没有看到那个警告。但是如果我从 foo()
函数中删除 __device__
属性,我会得到预期的错误:
error: identifier "foo" is undefined in device code
问题是为什么编译器只打印 warning 以及如何将它变成 error?
The question is why the compiler prints only a warning and how to turn it into an error?
编译器只打印一条警告,因为它不知道(在编译调用函数时)该函数是否会在运行时以令人反感的配置(即在设备代码上或从设备代码中)实际调用.
and how to turn it into an error?
从 nvcc manual 您可以添加:
-Werror all-warnings
将所有警告标记为错误
或
-Werror cross-execution-space-call
仅将此类警告标记为错误。
另见 here。对于那些会问为什么我没有标记为受骗者的人,另一个问题不包括关于编译器为何以这种方式运行的问题(或答案本身)。
I spent hours trying to solve the... error. ... But the code compiles! It produces a warning, but compiles!
您需要重新审视您的调试方法:-(
任何您尚未积极证明 给您自己的警告都是无关紧要的 - 是您需要查找错误的地方。解决警告比证明它们无效要容易得多,也更有回报。 (通过解决,我的意思是解决潜在的条件,而不是抑制警告,或者 const_cast'ing 等)
所以,不要用编译器将警告变成错误,而是将它们变成essentially-errors 在你的脑海中。干净,warning-free代码=快乐生活。