使用CUDA Thrust实现多GPU使用

dgr*_*rat 3 cuda gpu gpgpu thrust

我想用CUDA Thrust使用我的两张显卡进行计算.

我有两张图形卡.即使我在std :: vector中存储两个device_vectors,在单张卡上运行也能很好地适用于这两种卡.

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

我不确定究竟是什么问题,或者如何使用两张卡进行计算.

最小代码示例:

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;
}
Run Code Online (Sandbox Code Playgroud)

执行时出错:

terminate called after throwing an instance of 'thrust::system::system_error'
what():  invalid argument
Run Code Online (Sandbox Code Playgroud)

tal*_*ies 6

这里的问题是你试图在一对device_vector驻留在不同GPU上下文中的设备之间执行复制数据的设备(因为cudaSetDevice调用).您可能忽略的是这一系列操作:

thrust::host_vector<float> hvConscience(1024);
vRes.push_back(hvConscience);
Run Code Online (Sandbox Code Playgroud)

正在执行一个拷贝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);
}
Run Code Online (Sandbox Code Playgroud)

[免责声明:用浏览器编写的代码,既不编译也不测试,我们自担风险]

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