我可以在CUDA内核中使用实现纯虚函数的类吗?

时间:2015-10-18 12:04:37

标签: c++ inheritance cuda pure-virtual

我正在努力解决一个看似有点模糊不清的问题。

我正在开发一个框架,用户可以在其中提供抽象基类的实现,在完成魔法和代码生成的几个步骤之后,它将在CUDA内核中使用。

我知道

  

“不允许将全局函数作为参数传递给具有虚函数的类的对象。”

因为vtable在主机上创建时会被垃圾,然后被复制到GPU。但是我没有将对象传递给内核,我在内核中构造了对象,这不应该导致vtable问题。

class VirtualBase {
public:
    __device__ virtual int getResult() const = 0;
    __device__ virtual ~VirtualBase();
};

class Implementation : public VirtualBase {
public:
    __device__ Implementation(){};
    __device__ int getResult() const { return 42; };
    __device__ ~Implementation() {};
};

__global__ void kernel() {
    Implementation impl;
    int res = impl.getResult();
}

int main(void) {
    kernel<<<1, 1>>>();
    return 0;
}

使用Nsights自动生成的makefile编译代码

/Developer/NVIDIA/CUDA-7.5/bin/nvcc -G -g -O0 -std=c++11 -gencode arch=compute_30,code=sm_30  -odir "src" -M -o "src/main.d" "../src/main.cu"
/Developer/NVIDIA/CUDA-7.5/bin/nvcc -G -g -O0 -std=c++11 --compile --relocatable-device-code=false -gencode arch=compute_30,code=compute_30 -gencode arch=compute_30,code=sm_30  -x cu -o  "src/main.o" "../src/main.cu"

导致错误

ptxas fatal   : Unresolved extern function '_ZN11VirtualBaseD2Ev'
make: *** [src/main.o] Error 255

我在安装了CUDA 7.5的Mac上,但我在使用Ubuntu 14.10和CUDA 7.0的机器上尝试了相同的操作,产生了相同的结果。

1 个答案:

答案 0 :(得分:0)

经过多个小时的调试,编写这个问题并盯着ptxas错误,我有一种奇怪的感觉,这是未找到的基类的析构函数,因为D接近结束时_ZN11VirtualBaseD2Ev

I looked for ways to demangle the identifier实际上,D代表析构函数(标准构造函数在同一位置有C)。

稍后的几个调试语句,我意识到,当Implementation impl;超出范围时,两个析构函数都被称为,它首先是自己的,然后是基类。由于基类的析构函数没有实现,因此无法调用它,并抛出错误。

编辑:这个析构函数调用当然不是CUDA问题,而是标准C ++例程。此外,正如Robert Crovella在评论中指出的那样,如果在设备上实例化,CUDA确实支持实现虚函数的类。

相关问题