我想使用我的两个图形卡与 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;
}
执行时的错误信息:
terminate called after throwing an instance of 'thrust::system::system_error'
what(): invalid argument
最佳答案
这里的问题是您正试图在一对 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 上下文中创建每个向量一次,然后复制分配一个主机指针,这不会触发任何跨内存空间的设备端复制。
关于cuda - 多 GPU 与 CUDA Thrust 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16885971/