5

を使用して割り当てられたデバイス配列を初期化するにはどうすればよいcudaMalloc()ですか?

を試しましたが、値が 5 に初期化されている cudaMemset が以下のようになっているため、 cudaMemset以外のすべての値を初期化できませんでした。0.code

cudaMemset(devPtr,value,number_bytes)
4

2 に答える 2

12

ご存じcudaMemsetのように、C 標準ライブラリのように動作しますmemset。ドキュメントからの引用:

cudaError_t cudaMemset  (   void *      devPtr,
                            int         value,
                            size_t      count    
                        )           

devPtr が指すメモリ領域の最初の count バイトを定数バイト値 value で埋めます。

バイト値value同様です。次のようなことをすると:

int *devPtr;
cudaMalloc((void **)&devPtr,number_bytes);
const int value = 5;
cudaMemset(devPtr,value,number_bytes);

あなたが求めているのは、 の各バイトdevPtr5 に設定されることです。devPtrが整数の配列である場合、結果は各整数ワードが値 84215045 を持つことになります。これはおそらくあなたが考えていたものではありません。

ランタイム API を使用すると、独自の汎用カーネルを作成してこれを行うことができます。それは次のように簡単かもしれません

template<typename T>
__global__ void initKernel(T * devPtr, const T val, const size_t nwords)
{
    int tidx = threadIdx.x + blockDim.x * blockIdx.x;
    int stride = blockDim.x * gridDim.x;

    for(; tidx < nwords; tidx += stride)
        devPtr[tidx] = val;
}

(標準的な免責事項: ブラウザーで記述され、コンパイルもテストもされていないため、自己責任で使用してください)。

必要な型のテンプレートをインスタンス化し、適切なグリッドとブロック サイズで呼び出すだけです。最後の引数が のようなバイト カウントではなく、ワード カウントになっていることに注意してcudaMemsetください。これは、とにかく行うこととまったく違いはありませんcudaMemset。その API 呼び出しを使用すると、上記で投稿したものとは大きく異なるカーネルが起動されます。

または、ドライバー API を使用できる場合は、 と がcuMemsetD16ありcuMemsetD32、同じことを行いますが、ハーフおよびフル 32 ビット ワード タイプ用です。64 ビット以上の型 (double または vector 型) を設定する必要がある場合は、独自のカーネルを使用することをお勧めします。

于 2012-05-15T10:51:17.047 に答える
1

この質問に対する解決策も必要でしたが、他の提案された解決策を本当に理解していませんでした。for(; tidx < nwords; tidx += stride)特に、グリッドブロックを反復する理由、さらに言えば、カーネルの呼び出し、および直感に反するワードサイズを使用する理由がわかりませんでした。

したがって、私ははるかに単純なモノリシック汎用カーネルを作成し、ストライドでカスタマイズしました。つまり、行または列を任意の値に設定するなど、複数の方法でマトリックスを初期化するために使用できます。

template <typename T>
__global__ void kernelInitializeArray(T* __restrict__ a, const T value, 
   const size_t n, const size_t incx) {
      int tid = threadIdx.x + blockDim.x * blockIdx.x;
      if (tid*incx < n) {
           a[tid*incx] = value;
       }
}

次に、次のようにカーネルを起動できます。

template <typename T>
void deviceInitializeArray(T* a, const T value, const size_t n, const size_t incx) {
      int number_of_blocks = ((n / incx) + BLOCK_SIZE - 1) / BLOCK_SIZE;
      dim3 gridDim(number_of_blocks, 1);
      dim3 blockDim(BLOCK_SIZE, 1);
      kernelInitializeArray<T> <<<gridDim, blockDim>>>(a, value, n, incx);
}
于 2014-01-24T08:19:39.477 に答える