【问题标题】:"warning: __host__ annotation on a defaulted function is ignored" <- why?“警告:默认函数上的 __host__ 注释被忽略” <- 为什么?
【发布时间】:2018-03-10 04:37:04
【问题描述】:

从 CUDA 8.0 切换到 CUDA 9.0 RC,我收到以下警告:

__host__ __device__ ~Foo() = default;

警告是:

path/to/Foo.cuh(69): warning: __host__ annotation on a defaulted function("~Foo") is ignored

我以前没用过。我真的应该收到这个警告吗?指示您在设备端和主机端都需要默认析构函数有什么问题?

【问题讨论】:

  • 我认为您可能应该收到警告。默认构造函数或析构函数是告诉编译器自动生成自己的微不足道的默认实现。在这种情况下,添加注释是无关紧要的。两个编译器都会生成一个默认值,指定主机或设备编译器的默认值应该存在于主机和设备上,在这种情况下是错误的。
  • @talonmies:所以,你的意思是,即使没有这一行,在主机端和设备端都没有生成默认析构函数,我仍然应该在没有任何注释的情况下拥有它?
  • NVIDIA 声称设备工具链支持 N2346 。如果你想要这种行为(并且真正理解它的含义),那么一定要使用默认的构造函数或析构函数。但在那种情况下,为默认函数指定 __host__ __device__ 对我来说没有意义,我认为警告是有效的。但我知道什么......
  • @talonmies:我想要的是使用默认生成的 dtor,尽管它不是隐式生成的。我认为这就是 N2346 的意义所在,尽管我并不完全确定。我可以用一个空的析构函数来避免它,但是还有其他代码有同样的问题,比如相等运算符等。
  • @Matthias:很晚才跟进,但请记住 nvcc 不是编译器。它通过两个并行编译器通道(主机和设备)运行所有代码,每个编译器都会发出自己的默认实现。警告正是出于这个原因——设备代码编译器看到 __host__ 装饰器应用于设备默认值,并警告它在在编译轨迹中的那个点是无关紧要的。

标签: cuda destructor compiler-warnings nvcc


【解决方案1】:

指示您在设备端和主机端都需要默认析构函数有什么问题?

但这不是代码所说的。它说您希望主机和设备中都有 same 平凡的默认析构函数,这就是为什么会出现警告,因为编译器(主机和设备)都不会发出相同的默认析构函数(并且因为编译轨迹的工作方式是不可能发生的)。

NVIDIA 声称最近的设备工​​具链支持N2346。如果你想要这种行为(并且真正理解它的含义),那么正确的代码应该是:

~Foo() = default;

两个编译器都会在两个代码中自动发出自己的默认析构函数,一切都会正常工作。

如果您想要现有代码库的 hacky 解决方法,添加

-Xcudafe="--diag_suppress=2886" 

你的 nvcc 构建命令应该消除警告,尽管我建议不要抑制警告。

[答案作为 cmets 讨论的摘要添加,以从 CUDA 标签的未回答列表中删除问题。 ]

【讨论】:

  • nvcc 和原生 clang++ 中“主机设备”显式默认功能的可移植解决方案是什么?警告 2886 仅与此问题有关还是实际上与更多事情有关?作为记录,在 CUDA 10(或 10.1)中,警告编号似乎已更改为 2929...
  • 您是否声称~Foo() = default 暗示析构函数是空操作?这在 C++ 中不是这种情况:默认析构函数调用成员的析构函数。好的,我已经阅读了您关于任务的 cmets,并且您似乎知道这一点。不过,答案有点误导
  • “两个编译器都会在两个代码中自动发出它们自己的默认析构函数,一切都会正常工作。”
  • 我指的是编写此答案时最新的 CUDA 9
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 2020-01-16
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
相关资源
最近更新 更多