我想用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
答案 0 :(得分:5)
这里的问题是您尝试在驻留在不同GPU上下文中的一对device_vector
之间执行设备到设备的复制数据(因为cudaSetDevice
调用)。您可能忽略的是这一系列操作:
thrust::host_vector<float> hvConscience(1024);
vRes.push_back(hvConscience);
在每次循环迭代时从hvConscience
执行 copy 。推力后端期望源和目标内存位于相同的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上下文中创建一次每个向量,然后复制分配主机指针,该指针不会在内存空间中触发任何设备端副本。