为什么不能使CUDA C++类的主机/设备成员函数超载

nur*_*bha 3 c++ cuda overloading device member-functions

我有一个3d矢量类,其成员函数标记为主机和设备函数.下面是其中一个成员函数的片段:

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

我想要实现的是对主机和设备功能进行单独定义,以便在设备上执行时使用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;
}
Run Code Online (Sandbox Code Playgroud)

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

函数"Vector :: GetMagReciprocal"已经定义

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

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

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

也许有另一种更简单的方法来实现这一目标.如果有人有任何建议,那就太好了.

REEDITED:我没有提到使用CUDA ARCH标志生成单独的主机和设备的条件编译的可能性.这实际上是我在修改成员函数时所做的第一件事.但有些事情在我脑海中浮现,说这不起作用.也许我对我对这个编译标志的使用的理解是错误的.因此,sgarizvi提出的答案是正确的答案

sga*_*zvi 8

您可以使用条件编译标志__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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是正确的答案,任何断言这不起作用是完全错误的. (4认同)