CUDA:为什么不能定义静态全局成员函数?

时间:2013-08-31 19:13:12

标签: c++ static cuda global member

使用nvcc(CUDA 5.0)编译下面的代码时,会出现错误“内存限定符的非法组合”,因为显然不可能在类中使用全局内核。

class A
{
public:
    __global__ static void kernel();
};

__global__ void A::kernel()
{}

我在处理非静态成员时可以理解这个限制,但是为什么在内核声明为static时仍然会出现错误?调用此类成员与在函数名称中声明函数时的调用没有什么不同(在本例中为A)。

A::kernel <<< 1, 1 >>> ();

有没有理由我错过了为什么还没有实现呢?

编辑:根据答案和评论中的回答,我对我的问题不够清楚。我的问题不是出现错误的原因。显然,这是因为它尚未实施。我的问题是为什么尚未实施。到目前为止,我还没有想到让这个功能得以实现的原因。我意识到我可能已经忘记了一个会使问题复杂化的特殊情况,因此就是问题。

我认为这是一个合理的功能的原因是:

  • 静态函数没有this指针所以即使在主机上的对象上调用内核,访问其数据也没有冲突,因为这些数据在第一次访问时是不可访问的放置(来自哪个对象的数据?)。
  • 您可能会争辩说,如果类具有与之关联的静态数据,并且生活在主机上,那么原则上应该可以从静态内核访问它。但是,也不支持静态数据,因此不会发生冲突。
  • 在主机上的对象上调用静态内核(A a; a.staticKernel<<<...,...>>>();)完全等同于在没有对象的情况下调用它(A::staticKernel<<<...,...>>>();),正如我们在常规C ++中习惯的那样。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

幸运的是,在提出这个问题后约4年clang 4.0 can compile the CUDA language。考虑这个例子:

class A
{
public:
    __global__ static void kernel();
};

__device__ void A::kernel()
{}

int main()
{
    A::kernel <<< 1, 1 >>> ();
};

当我尝试使用clang 4.0编译它时,我收到以下错误:

test.cu:7:1: error: kernel function 'kernel' must be a free function or static member function
__global__ void A::kernel()
^
/usr/local/cuda/include/host_defines.h:191:9: note: expanded from macro '__global__'
        __location__(global)
        ^
/usr/local/cuda/include/host_defines.h:88:9: note: expanded from macro '__location__'
        __annotate__(a)
        ^
/usr/local/cuda/include/host_defines.h:86:9: note: expanded from macro '__annotate__'
        __attribute__((a))
        ^
test.cu:7:20: error: __host__ function 'kernel' cannot overload __global__ function 'kernel'
__global__ void A::kernel()
                   ^
test.cu:4:28: note: previous declaration is here
    __global__ static void kernel();
                           ^
2 errors generated.

为了满足这些错误,我已将内核定义内联到类声明中:

class A
{
public:
    __global__ static void kernel()
    {
        // implementation would go here
    }
};

然后clang 4.0成功编译它并且可以毫无错误地执行它。所以这显然不是CUDA 语言的限制,而是它事实上的标准编译器。顺便说一句,nvcc有许多类似的不合理的限制,而clang没有。