我可以使用仅主机功能覆盖CUDA主机和设备功能吗?

时间:2019-12-16 21:04:18

标签: compiler-errors cuda overriding virtual-functions nvcc

考虑以下程序:

class A {
    __host__  __device__ void foo();
};

class B : A {
    __host__ void foo();
};

int main()
{
    A a; (void) a; 
    B b; (void) b;
}

此nvcc 10为compiles(GodBolt)。

但是,在更复杂的程序中,有时会出现以下错误(换行以提高可读性):

whatever.hpp(88): error: execution space mismatch: overridden entity (function
"C::foo") is a __host__ __device__ function, but overriding entity (function "D::foo")
is a __host__ function

因此,nvcc告诉我应该在覆盖方法时删除执行空间。我不是在问自己的代码(在这里没有引用),而是在问原理:

  • 如果只用__host__ __device__个函数覆盖__host__个函数(我认为是合理的)是可以接受的-那么nvcc怎么会出现这样的错误?
  • 或者,如果不允许的话-为什么上面的小程序正在编译?

1 个答案:

答案 0 :(得分:1)

覆盖(虚拟)方法必须尊重覆盖方法的执行空间选择。

“覆盖”仅与虚拟方法相关-因此必须在您的C::foo()被标记为virtual 的情况下。实际上,如果我们在示例程序中将foo()标记为虚拟:

class A {
    virtual __host__  __device__ void foo();
};

class B : A {
    __host__ void foo(); // can say "override" here; but it doesn't matter
};

int main()
{
    A a; (void) a; 
    B b; (void) b;
}

这将fail to compile

<source>(6): error: member function declared with "override" does not override
a base class member

此限制有意义吗?可以想象一种解释,其中基类方法将应用于__device__端调用,而子类方法将应用于__host__端调用。但这也有点尴尬-当通过基类ptr对对象进行操作时,我们需要调用 something