2013-05-15 71 views
0

我想发送大小size的在每一维的3D阵列src,展平为大小length = size * size * size的一维数组,为一个内核,计算结果并将其存储在dst。但是,最后,dst不正确地包含全部0。这里是我的代码:正确使用cudaMalloc3D与cudaMemcpy

int size = 256; 
int length = size * size * size; 
int bytes = length * sizeof(float); 

// Allocate source and destination arrays on the host and initialize source array 

float *src, *dst; 
cudaMallocHost(&src, bytes); 
cudaMallocHost(&dst, bytes); 
for (int i = 0; i < length; i++) { 
    src[i] = i; 
} 

// Allocate source and destination arrays on the device 

struct cudaPitchedPtr srcGPU, dstGPU; 
struct cudaExtent extent = make_cudaExtent(size*sizeof(float), size, size); 
cudaMalloc3D(&srcGPU, extent); 
cudaMalloc3D(&dstGPU, extent); 

// Copy to the device, execute kernel, and copy back to the host 

cudaMemcpy(srcGPU.ptr, src, bytes, cudaMemcpyHostToDevice); 
myKernel<<<numBlocks, blockSize>>>((float *)srcGPU.ptr, (float *)dstGPU.ptr); 
cudaMemcpy(dst, dstGPU.ptr, bytes, cudaMemcpyDeviceToHost); 

我已经离开了的cudaMallocHost()cudaMalloc()cudaMemcpy()为清楚起见,我的错误检查。无论如何这个代码都不会触发错误。

cudaMalloc3D()cudaMemcpy()的正确用法是什么?

请让我知道我是否应该发布内核的最小测试用例,或者如果问题可以在上面的代码中找到。

+1

考虑看看您可能会感兴趣[这个提问/回答(http://stackoverflow.com/questions/16119943/how-and-当我应该使用pitched指针与cuda-api) –

+0

谢谢,我已经偶然发现,这是非常有益的。 –

+0

现在可以在[从cuda 3D内存复制到线性内存:复制数据不在我预期的地方](http:// stackoverflow。COM /问题/ 16107480 /复制从 - CUDA-3D-存储器到线性存储器复制的数据 - 是 - 不其中-I-人口会/ 23052768#23052768)。 – JackOLantern

回答

2

编辑:程度取如果使用CUDA数组元素的数量,但实际上取的字节数,如果不使用CUDA阵列(例如存储器用的cudaMalloc一些非阵列变体分配)

the Runtime API CUDA documentation

范围字段定义元素中传输区域的尺寸。如果一个CUDA数组正在参与复制,则该数组的范围将根据该数组的元素进行定义。如果没有CUDA数组参与复制,则范围在无符号字符

同样的元素来定义,cudaMalloc3D返回指针,这意味着它必须至少提供您的尺寸程度,但可能更多的对齐原因。访问和复制设备内存时,必须考虑到这一点。见here有关cudaPitchedPtr结构

至于使用cudaMalloc3DcudaMemcpy的文档,你可能想看看使用cudaMemcpy3Ddocumentation here),它可能使你的生活更容易一点,采取主机的间距和考虑到设备内存。要使用cudaMemcpy3D,您必须创建一个cudaMemcpy3DParms结构以及相应的信息。它的成员有:

cudaArray_t dstArray 
struct cudaPos dstPos 
struct cudaPitchedPtr dstPtr 
struct cudaExtent extent 
enumcudaMemcpyKind kind 
cudaArray_t srcArray 
struct cudaPos srcPos 
struct cudaPitchedPtr srcPtr 

,你必须指定的srcArraysrcPtr一个和dstArraydstPtr之一。另外,文档建议在使用它之前将结构初始化为0,例如 cudaMemcpy3DParms myParms = {0};

而且,你可能有兴趣在此other SO question

+0

我可以使用srcGPU作为dstPtr,但我应该为srcArray或srcPtr使用?我从float * src复制,它既不是cuda数组,也不是cuda pitched指针。 –

+1

@ 1“”我想尝试做一个'cudaPitchedPtr'你'src'指针,与步幅是大小为您的宽度 – alrikai

+0

好主意一样,我想试试。然而,我没有错误检查内核本身,并且它给出了当前代码的错误“无效参数”。为什么我不能将srcPtr.ptr和dstPtr.ptr传递给期望float *的内核? –