1

是否可以更改推力::设备向量的设备 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);

是否可以?谢谢

4

2 回答 2

1

我不知道它是否以及如何与推力完全配合,以及您是否尝试更改不使用推力的设备阵列的设备 ID,以及您是否知道点对点内存访问。

这是一个有趣的问题,但我可以自己做实验。但是,根据 CUDA 编程指南(第 3.2.6.4 节),如果您使用Tesla 卡使用计算能力 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() 可以完成这项工作并提供了一个示例。我在推力文档中找不到与您的问题相对应的内容,因此我认为最好的方法是尝试一下。

于 2013-10-09T14:34:16.073 回答
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

开发 1 上的随机访问,c = 3

注意:您需要在同一主机上至少有 2 个 GPU 来测试它。我在我的 GTX690 上测试过

于 2013-10-10T03:22:46.507 回答