我想在CUDA5.0中将东西从主机复制到设备更方便。所以我想创建一个函数,将主机向量作为参数并返回如下结构:
template <typename T>
struct devArr
{
unsigned int size; //array size
T *address; //address on device
};
目的是将数据复制到代码中的任何位置,然后仅将该结构传递给使用数据的任何设备函数,而不必单独处理数组边界。
返回结构的函数可以看起来像:
template <typename T>
struct cudaArr<T> VectorToDevice(vector<T> arr)
{
struct devArr<T> darr;
darr.size = arr.size();
cudaMalloc((void**)&darr.address, arr.size()*sizeof(T));
cudaMemcpy(darr.address,&arr[0], arr.size()*sizeof(T), cudaMemcpyHostToDevice);
return darr;
}
所以这一切都很好。但是使用这段代码,我的struct中的指针并没有指向正确的地址。它一般是如何处理结构中的指针的问题。那么如何在结构中使用指针正确使用cudaMalloc?
谢谢。
答案 0 :(得分:1)
这正是你如何做到的。困扰我并在这里注意的事情是指针包含设备存储器上的地址,因此它仅在设备功能中有效。在主机代码中,它指向错误的数据。
答案 1 :(得分:1)
看起来Thrust可能对您有用,所以如果您的用例符合我的推荐值。
您的代码使用cuda api,但VectorToDevice
的返回类型应为devArr
。
如果您要执行以下操作,则应将整个devArr
结构作为值传递给某个内核函数。然后您可以使用设备指针。
目的是将数据复制到代码中的任何位置,然后仅将该结构传递给使用数据的任何设备函数,而不必单独处理数组边界。
例如,您可以编写如下的内核函数:
__global__ void add(devArr x, devArr y, devArr z) {
if (threadIdx.x < x.size) {
z.address[threadIdx.x] = x.address[threadIdx.x] + y.address[threadIdx.x]
}
}
然后你可以从你的主机代码中调用它,比如说:
devArr x = VectorToDevice(x_host);
// prepare y and z similarly.
add<<<1, 100, 0>>>(x, y, z);
但是你不能直接在主机代码中使用x.address指向的内容。