【问题标题】:Why it is not possible to overload host/device member function of a CUDA C++ class [duplicate]为什么不可能重载 CUDA C++ 类的主机/设备成员函数 [重复]
【发布时间】:2015-06-22 12:21:56
【问题描述】:

我有一个 3d 矢量类,其成员函数标记为主机和设备函数。下面是成员函数之一的sn-p:

__host__ __device__
double Vector::GetMagReciprocal()
{
    double result = 1/sqrt(x*x + y*y + z*z);
    return result;
}

我想要实现的是对主机和设备函数进行单独定义,以便在设备上执行时通过使用 CUDA 数学内在函数 rqsrt 获得更好的性能。我这样做的方法是为主机和设备重载这个成员函数:

__host__
double Vector::GetMagReciprocal()
{
    double result = 1/sqrt(x*x + y*y + z*z);
    return result;
}

__device__
double Vector::GetMagReciprocal()
{
    double result = rsqrt(x*x + y*y + z*z);
    return result;
}

现在当我使用 nvcc(-x cu flag) 编译 Vector.cpp 文件时,我得到以下错误

函数“Vector::GetMagReciprocal”已经定义

现在我想知道为什么 NVIDIA 不支持这种重载。

我可以想到实现分离的替代方法,但它们都有自己的问题:

  • 在矢量类中为主机和设备创建单独的成员函数,例如 GetMagReciprocalHostGetMagReciprocalDevice,并在主机/设备代码中调用相应的函数
  • 只有一个成员函数GetMagReciprocal,但将标志传递给成员函数以在主机代码和设备代码之间进行选择

也许还有另一种更简单的方法来实现这一点。如果有人有什么建议,那就太好了。

重新编辑:我没有提到使用 CUDA ARCH 标志进行条件编译以生成单独的主机和设备的可能性。这实际上是我在修改成员函数时所做的第一件事。但是我想到了一些事情,说这行不通。也许我对这个编译标志的理解是错误的。所以 sgarizvi 提出的答案是正确的答案

【问题讨论】:

  • CUDA_ARCH 确实解决了这个问题。您使用__host____device__ 装饰一个函数,然后使用带有CUDA_ARCH 宏的条件编译来更改设备代码的代码生成。
  • 这是我做的第一件事。但在我看来它不起作用。我必须测试一下,看看是不是这样。
  • 如果你提供一个简短、完整的代码,其他人可以复制、粘贴、编译和运行,看看问题是什么,我相信它可以解释。但是小代码 sn-ps 以及“这不起作用”的断言无法为您解决。在我看来,如果这个问题没有作为重复问题关闭,它也可能因为缺少MCVE 而被关闭。以后请务必提供 MCVE。

标签: c++ cuda overloading device member-functions


【解决方案1】:

您可以使用条件编译标志__CUDA_ARCH____host__ __device__ 函数中为主机和设备生成不同的代码。

__CUDA_ARCH__ 仅为设备代码定义,因此要为主机和设备创建不同的实现,您可以执行以下操作:

__host__ __device__
double Vector::GetMagReciprocal()
{
    double result;
    #ifdef __CUDA_ARCH__
    result = rsqrt(x*x + y*y + z*z);
    #else
    result = 1/sqrt(x*x + y*y + z*z);
    #endif
    return result;
}

【讨论】:

  • 我总是用 nvcc 编译,所以它为主机和设备功能生成相同的代码。不工作
  • 这绝对是正确的答案,任何认为这不起作用的断言都是完全错误的。
  • @nurabha 不,它不会为主机和设备生成相同的代码。 nvcc 不是编译器。它是一个编译器驱动程序,将代码传递给后端的实际主机和设备编译器。将生成两个版本的代码。一个由主机编译器,一个由设备编译器。
  • @sgarizvi:我知道 nvcc 是一个编译器驱动程序。
  • @nurabha... 好吧,您能否解释一下您所寻求的预期目的是什么?我的意思是为什么你需要两个独立的功能?如果您可以添加更多详细信息,也许我们可以提供替代解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-08-20
  • 2012-04-06
  • 1970-01-01
  • 2016-03-07
  • 2011-06-11
  • 1970-01-01
  • 2012-12-25
  • 2013-09-04
相关资源
最近更新 更多