为啥定义没有 CUDA __device__ 属性的类头有效? (C++)

Posted

技术标签:

【中文标题】为啥定义没有 CUDA __device__ 属性的类头有效? (C++)【英文标题】:Why defining class headers without CUDA __device__ attribute works? (C++)为什么定义没有 CUDA __device__ 属性的类头有效? (C++) 【发布时间】:2011-11-04 16:10:44 【问题描述】:

我有一个包含以下声明的 .h 文件:

class Foo
public:
    inline int getInt();
;

我的 .cu 文件定义了以下内容:

__device__ int Foo::getInt()
   return 42;

这太棒了,因为虽然我实际上不能从主机调用getInt,但我可以将 .h 文件包含在 .cpp 文件中,这样我就可以看到主机的类型声明。但对我来说它似乎不应该工作,那么为什么我不需要将__device__ 属性放在 .h 文件上?

【问题讨论】:

【参考方案1】:

如果它有效,它不应该。这可能是 CUDA 编译器中的一个错误,将来可能会得到修复 - 所以不要依赖它。

但是,如果您希望该类对主机(和非 cuda 编译器)可见,但您有一些主机上不需要的 __device__ 功能,您始终可以使用#ifdef __CUDACC__——#endif__CUDACC__ 是在使用 nvcc 编译时预定义的,否则不是。所以你可以在你的标题中写下这样的内容:

class Foo
public:
#ifdef __CUDACC__
    inline __device__ int getInt();
#endif
;

如果你怕预处理器 ifdef 太多,你也可以这样做:

#ifdef __CUDACC__
#define HOST __host__
#define DEVICE __device__
#else
#define HOST
#define DEVICE
#endif

...

class Foo
public:
    inline HOST DEVICE int getInt();
;

【讨论】:

非常感谢,这个__CUDACC__ 将非常有用。 是否也可以使用这种技术来定义属性?因为当我尝试在 Foo 中定义 __device__ int test 时遇到 attribute "device" does not apply here 错误 不,你永远不会为字段写__device__。字段仅指定类型,本身不是变量。如果您写__device__ Foo var,那么var 的所有字段都将在设备上。其他内存空间(共享、常量)也是如此。 哦,当然,有道理。如果对象在设备内存上实例化,则字段将在设备内存上,否则不在。【参考方案2】:

将其更改为以下内容:

__device__ int Foo::getInt()
   return 42;

问题在于函数的返回类型。不是void,而是int

【讨论】:

对不起,它是int,我在这里写错了。此代码有效。我已更改问题以明确我想知道的内容。

以上是关于为啥定义没有 CUDA __device__ 属性的类头有效? (C++)的主要内容,如果未能解决你的问题,请参考以下文章

CUDA compiler driver nvcc 散点

CUDA:Nsight VS2010 profile __device__ 函数

将主机内存复制到 cuda __device__ 变量

cuda nvcc 使 __device__ 有条件

在 CUDA 的 __device__ 函数中使用动态分配时出现“未知错误”

不允许从 __device__ 函数调用 __host__ 函数的 cuda::cub 错误