2

我已经使用 JCuda 几个月了,我无法将多维数组从设备内存复制到主机内存。有趣的是,我在相反的方向上这样做没有问题(我可以使用多维数组调用我的内核,并且一切都使用正确的值)。

简而言之,我将内核的结果放在一个二维数组中,这个数组的第一个维度是线程的数量,这样每个人都可以在不同的位置写入。

这里有一个例子:

CUdeviceptr pointer_dev = new CUdeviceptr();
cuMemAlloc(pointer_dev, Sizeof.POINTER); // in this case, as an example, it's an array with one element (one thread), but it doesn't matter

// Invoke kernel with pointer_dev as parameter. Now it should contain some results

CUdeviceptr[] arrayPtr = new CUdeviceptr[1]; // It will point to the result
arrayPtr[0] = new CUdeviceptr();
short[] resultArray = new short[3]; // an array of 3 shorts was allocated in the kernel

cuMemAlloc(arrayPtr[0], 3 * Sizeof.SHORT);
cuMemcpyDtoH(Pointer.to(arrayPtr), pointer_dev, Sizeof.POINTER); // Its seems, using the debugger, that the value of arrayPtr[0] isn't changed here!
cuMemcpyDtoH(Pointer.to(resultArray), arrayPtr[0], 3 * Sizeof.SHORT); // Not the expected values in resultArray, probably because of the previous instruction

我究竟做错了什么?

编辑

显然,有一些限制不允许将设备分配的内存复制回主机,如此(以及更多)线程中所述:link

任何解决方法?我正在使用 CUDA Toolkit v5.0

4

1 回答 1

4

在这里,我们将一个二维整数数组从设备复制到主机。

  1. 首先,创建一个大小等于另一个一维数组(此处blockSizeX)的大小的一维数组。

    CUdeviceptr[] hostDevicePointers = new CUdeviceptr[blockSizeX];
    for (int i = 0; i < blockSizeX; i++)
    {
        hostDevicePointers[i] = new CUdeviceptr();
        cuMemAlloc(hostDevicePointers[i], size * Sizeof.INT);
    }
    
  2. 为指向另一个数组的指针数组分配设备内存,并将数组指针从主机复制到设备。

    CUdeviceptr hostDevicePointersArray = new CUdeviceptr();
    cuMemAlloc(hostDevicePointersArray, blockSizeX * Sizeof.POINTER);
    cuMemcpyHtoD(hostDevicePointersArray, Pointer.to(hostDevicePointers), blockSizeX * Sizeof.POINTER);
    
  3. 启动内核。

    kernelLauncher.call(........, hostDevicePointersArray);
    
  4. 将输出从设备传输到主机。

    int hostOutputData[] = new int[numberofelementsInArray * blockSizeX];
    cuMemcpyDtoH(Pointer.to(hostOutputData), hostDevicePointers[i], numberofelementsInArray * blockSizeX * Sizeof.INT);
    
    for (int j = 0; j < size; j++)
    {
        sum = sum + hostOutputData[j];
    }
    
于 2014-01-27T11:55:10.760 回答