是否可以更改thrust :: device vector的设备ID? 我想像这样编码
cudaSetDevice(0); //set to device:0
thrust::device_vector<int> a(10); //define the device vector
a.clear(); thrust::device_vector<int>().swap(a); //deallocate the vector
cudaSetDevice(1); //set to device:1
a.resize(10);
有可能吗? 谢谢
答案 0 :(得分:1)
我不知道它是否以及如何与推力完全一致,如果您尝试更改设备阵列的设备ID而不是使用推力,并且您知道对等内存访问。
这是一个有趣的问题,但我可以做自己的实验。 但是,根据CUDA编程指南(第3.2.6.4节),如果您使用计算能力2.x 及以上,则可以进行点对点内存访问(即两个设备可以互相寻址内存)使用特斯拉卡。
这是编程指南中的一个例子:
cudaSetDevice(0);
float* p0;
size_t size = 1024 * sizeof(float);
cudaMalloc(&p0, size);
MyKernel<<<1000, 128>>>(p0);
cudaSetDevice(1);
cudaDeviceEnablePeerAccess(0, 0); // <- this enables peer to peer access
MyKernel<<<1000,128>>>(p0);
关于从一个设备到另一个设备的内存复制,编程指南说cudaMemcpyPeer()可以完成这项工作并提供一个示例。 我在推文文档中找不到与您的问题相对应的内容,因此我认为最好的方法是尝试它。
答案 1 :(得分:0)
我不知道这是否是正确答案。所以如果我错了请纠正我,因为我不知道测试是否合适。所以我决定对载体添加进行如下测试
#include <thrust/device_vector.h>
#include <iostream>
__global__ void
vectorAdd(const int *A, const int *B, int *C, int numElements) {
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements) C[i] = A[i] + B[i];
};
int main(void)
{
int numElements = 1024;
int randacc = 30;
cudaSetDevice(0);
thrust::device_vector<int> a(numElements, 1);
thrust::device_vector<int> b(numElements, 2);
thrust::device_vector<int> c(numElements);
int* a_d = thrust::raw_pointer_cast(&a[0]);
int* b_d = thrust::raw_pointer_cast(&b[0]);
int* c_d = thrust::raw_pointer_cast(&c[0]);
int threadsPerBlock = 64;
int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(a_d, b_d, c_d, numElements);
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) std::cerr << cudaGetErrorString(err) << std::endl;
std::cout << "random access on dev 0, c = " << c[randacc] << std::endl;
a.clear(); thrust::device_vector<int>().swap(a); //deallocate the vector
b.clear(); thrust::device_vector<int>().swap(b); //deallocate the vector
c.clear(); thrust::device_vector<int>().swap(c); //deallocate the vector
cudaSetDevice(1); //set to device:1
a.resize(numElements, 1);
b.resize(numElements, 2);
c.resize(numElements);
a_d = thrust::raw_pointer_cast(&a[0]);
b_d = thrust::raw_pointer_cast(&b[0]);
c_d = thrust::raw_pointer_cast(&c[0]);
threadsPerBlock = 64;
blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(a_d, b_d, c_d, numElements);
err = cudaGetLastError();
if (err != cudaSuccess) std::cerr << cudaGetErrorString(err) << std::endl;
std::cout << "random access on dev 1, c = " << c[randacc] << std::endl;
return 0;
}
我得到了结果:
dev 0上的随机访问,c = 3
dev 1上的随机访问,c = 3
注意:在同一主机上至少需要2个GPU才能对其进行测试。我在我的GTX690上测试了