1

デバイス関数内で使用するために、デバイスで一様乱数を生成したいと思います。各スレッドは、異なる一様乱数を生成する必要があります。このコードがありますが、セグメンテーション違反が発生します。

int main{
  curandStateMtgp32 *devMTGPStates;
  mtgp32_kernel_params *devKernelParams;

  cudaMalloc((void **)&devMTGPStates, NUM_THREADS*NUM_BLOCKS * sizeof(curandStateMtgp32));
  cudaMalloc((void**)&devKernelParams,sizeof(mtgp32_kernel_params));

  curandMakeMTGP32Constants(mtgp32dc_params_fast_11213, devKernelParams);
  curandMakeMTGP32KernelState(devMTGPStates,
    mtgp32dc_params_fast_11213, devKernelParams,NUM_BLOCKS*NUM_THREADS, 1234);

  doHenry <<NUM_BLOCKS,NUM_THREADS>>> (devMTGPStates);
}

そして、デバイスで評価されるグローバル関数 doHenry 内に、次のように記述します。

    double rand1 = curand_uniform_double(&state[threadIdx.x+NUM_THREADS*blockIdx.x]);

これは、スレッドごとに乱数を生成する最良の方法ですか? devKernelParams が何をしているのかわかりませんが、スレッドごとに 1 つの状態が必要なのはわかっていますよね?

ご協力ありがとうございました。

4

1 に答える 1

2

この行でセグフォルトが発生していると思います:

curandMakeMTGP32KernelState(devMTGPStates,  mtgp32dc_params_fast_11213, devKernelParams,NUM_BLOCKS*NUM_THREADS, 1234);

seg fault の理由は、n渡しているパラメータが 200 を超えたためだと思いますNUM_BLOCKS*NUM_THREADS。あなたのコードのバージョンを試してみたところ、n=540 付近でセグ フォールトを再現できました。

MT ジェネレーターには、事前に生成されたカーネル パラメーターを使用するときに設定できる状態の量に制限があります ( mtgp32dc_params_fast_11213)。ドキュメントの関連セクションを読むことをお勧めします。(MTGP32ジェネレーターによるビット生成)

私は CURAND の専門家ではありませんが、他のジェネレーター (XORWOW など) にはこのような制限がないため、大量の独立したスレッド状態を簡単に生成したい場合は、他のジェネレーターのいずれかを検討してください。あなたが概説した特定のアプローチを使用すると、MTGP32 ジェネレーターは約 200*256 の独立したスレッド生成に制限されているようです。私がコメントで述べたこととは反対に (これは他のジェネレーターの種類にも当てはまります)、MTGP32 の状態は、最大 256 スレッドのブロックに対して 1 つの状態で十分なようです。また、ドキュメントに示されている例(2 番目の例を参照) では、そのタイプの状態生成とスレッドブロック階層を使用しています。

于 2013-06-24T04:33:58.473 に答える