2

数か月間 JCuda を使用してきましたが、多次元配列をデバイス メモリからホスト メモリにコピーできません。面白いことに、反対方向に実行しても問題はありません (多次元配列を使用してカーネルを呼び出すことができ、すべてが正しい値で機能します)。

簡単に言うと、カーネルの結果を short の 2 次元配列に入れます。このような配列の最初の次元はスレッドの数であり、それぞれが異なる場所に書き込むことができるようにします。

ここに例があります:

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

私は何を間違っていますか?

編集

どうやら、この (およびその他の多くの) スレッドで述べられているように、デバイスに割り当てられたメモリをホストにコピーすることを許可しないいくつかの制限があります:リンク

回避策はありますか?CUDA ツールキット v5.0 を使用しています

4

1 に答える 1

4

ここでは、整数の 2 次元配列をデバイスからホストにコピーしています。

  1. まず、別の 1 次元配列のサイズと同じサイズの 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 に答える