CUDA多个设备问题,推力:: system_error

时间:2014-09-24 19:49:46

标签: linux cuda thrust

我使用thrust开发了一种算法。我的办公室计算机有一个支持CUDA的卡,具有架构:

  

---有关设备0的一般信息       名称:Quadro 2000       计算能力:2.1       时钟频率:1251000 kHz       设备重叠:           启用       内核执行超时:           禁用

在这台机器上,我的算法运行没有错误。但是,在尝试生成thrust::system::system_error时,实验室计算机上的干净构建会引发令人讨厌的device_vector。这两台机器都运行RedHat 6并且配置相同,但多个图形卡除外。该实验室机器包含三个具有以下体系结构的支持CUDA的卡:

  

---有关设备0的一般信息       名称:特斯拉C2050       计算能力:2.0       时钟频率:1147000 kHz       设备重叠:           启用       内核执行超时:           禁用

     

---有关设备1的一般信息       名称:Quadro 2000       计算能力:2.1       时钟频率:1251000 kHz       设备重叠:           启用       内核执行超时:           禁用

     

---有关设备2的一般信息       名称:Quadro 2000       计算能力:2.1       时钟频率:1251000 kHz       设备重叠:           启用       内核执行超时:           Enabled`

我知道thrust需要针对目标架构进行编译才能工作。因此,我将CUDA设备设置为1。但是,错误仍然存​​在。

作为一项调试措施,我在cudaGetDevice()分配之前立即拨打了device_vector电话。设备已正确声明为1

int device;
CUDA_CHECK_RETURN(cudaGetDevice(&device), __FILE__, __LINE__);
std::cout << "Operating on device " << device << std::endl; // <-- device 1

// copy the turns to the runtime
thrust::device_vector<MalfunctionTurn> d_turns = turns; // <-- error here

我在我的智慧结束时试图调试它。以前有没有人看到这样的错误?更值得注意的是,cudaSetDevice()是否存在我不知道的限制?我很担心,因为不同机器上的两张相同的卡无法运行相同的代码。

提前致谢。


修改

编译命令行:nvcc -rdc=true -arch=sm_21 -O3 file

以下是重现错误的最小示例:

#define DEVICE __device__
#define HOST __host__

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

template <typename T, std::size_t N>
class Container {
public:

    DEVICE HOST
    Container() {

    }

private:
    T data[N];
};

typedef Container<double, 7> double7;

template <std::size_t N = 10 >
class History {
public:

    DEVICE HOST
    History() {

    }

    DEVICE HOST
    virtual ~History() {

    }

private:

    double7 history[N];
};

int main() {

    try {

        thrust::host_vector<History<> > histories(1);
        thrust::device_vector<History<> > d_histories = histories;
    } catch (const thrust::system_error &) {
        std::cerr << "boo boo" << std::endl;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:3)

尽我所知,您的代码(在引擎盖下)违反了对usage of classes with virtual functions的CUDA限制:

  

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

如果我拿走你的代码并删除:

#include <JARSS.h>

并将其替换为:

#define HOST   __host__
#define DEVICE __device__

我可以编译它。然而,在引擎盖下,推力执行这一行:

    thrust::device_vector<History<> > d_histories = histories;

通过启动一个内核,该内核将主机上的对象作为参数复制到设备中。 (例如,您可以使用nvprof验证内核启动。)这是推力的常见行为。问题出现在那些具有虚拟析构函数的对象不能以这种方式复制。

与您的问题所述相反,此代码不应在任何CUDA计算机上正确运行。

您可以通过注释掉虚拟析构函数来“修复”您的代码。如果您需要多态行为,那么对实际代码的修复可能会比这更复杂。仍然可以使用具有推力的多态对象行为,请参阅this answer以获得有用的示例。