4

我想用我的两张显卡和 CUDA Thrust 进行计算。

我有两张显卡。即使我将两个 device_vector 存储在 std::vector 中,在单卡上运行也适用于两张卡。

如果我同时使用两张卡,则循环中的第一个循环有效并且不会导致错误。第一次运行后它会导致错误,可能是因为设备指针无效。

我不确定确切的问题是什么,或者如何使用两张卡进行计算。

最小代码示例:

std::vector<thrust::device_vector<float> > TEST() {
    std::vector<thrust::device_vector<float> > vRes;

    unsigned int iDeviceCount   = GetCudaDeviceCount();
    for(unsigned int i = 0; i < iDeviceCount; i++) {
        checkCudaErrors(cudaSetDevice(i) ); 
        thrust::host_vector<float> hvConscience(1024);

                // first run works, runs afterwards cause errors ..
        vRes.push_back(hvConscience); // this push_back causes the error on exec

    }
    return vRes;
}

执行时的错误信息:

terminate called after throwing an instance of 'thrust::system::system_error'
what():  invalid argument
4

1 回答 1

6

这里的问题是您正在尝试在一对device_vector位于不同 GPU 上下文中的设备之间复制数据(因为cudaSetDevice调用)。您可能忽略了以下操作序列:

thrust::host_vector<float> hvConscience(1024);
vRes.push_back(hvConscience);

在每次循环迭代中执行复制hvConscience推力后端期望源内存和目标内存位于相同的 GPU 上下文中。在这种情况下,他们没有,因此错误。

您可能想要做的是使用指针向量来device_vector代替,例如:

typedef thrust::device_vector< float > vec;
typedef vec *p_vec;
std::vector< p_vec > vRes;

unsigned int iDeviceCount   = GetCudaDeviceCount();
for(unsigned int i = 0; i < iDeviceCount; i++) {
    cudaSetDevice(i); 
    p_vec hvConscience = new vec(1024);
    vRes.push_back(hvConscience);
}

[免责声明:在浏览器中编写的代码,未经编译或测试,我们自担风险]

这样,您只需在正确的 GPU 上下文中创建每个向量一次,然后复制分配一个主机指针,这不会触发跨内存空间的任何设备端复制。

于 2013-06-03T11:49:12.670 回答