2

カーネル内のCUDAデバイスで乱数を生成する方法を見つけるために、インターネットで多くのことを検索しました。数値はガウス分布から取得する必要があります。

私が見つけた最高のものは、NVIDIA自体からのものでした。これは、一様分布を使用してガウス分布を構築するウォレスアルゴリズムです。しかし、それらが提供するコードサンプルには説明がなく、特にデバイスでアルゴリズムがどのように機能するかを理解する必要があります。たとえば、次のようになります。

 __device__ void generateRandomNumbers_wallace(  
unsigned seed,  // Initialization seed  
 float *chi2Corrections,  // Set of correction values  
 float *globalPool,  // Input random number pool  
 float *output  // Output random numbers  


    unsigned tid=threadIdx.x;  
    // Load global pool into shared memory.  
     unsigned offset = __mul24(POOL_SIZE, blockIdx.x);  
    for( int i = 0; i < 4; i++ )  
      pool[tid+THREADS*i] = globalPool[offset+TOTAL_THREADS*i+tid];  
    __syncthreads();  
      const unsigned lcg_a=241;  
      const unsigned lcg_c=59;  
      const unsigned lcg_m=256;  
      const unsigned mod_mask = lcg_m-1;  
      seed=(seed+tid)&mod_mask ;  
      // Loop generating outputs repeatedly  
     for( int loop = 0; loop < OUTPUTS_PER_RUN; loop++ )  
      {  
        Transform();  
        unsigned intermediate_address;  
        i_a = __mul24(loop,8*TOTAL_THREADS)+8*THREADS *  
          blockIdx.x + threadIdx.x;  
        float chi2CorrAndScale=chi2Corrections[  
          blockIdx.x * OUTPUTS_PER_RUN + loop];  
        for( i = 0; i < 4; i++ )  
          output[i_a + i*THREADS]=chi2CorrAndScale*pool[tid+THREADS*i];  
    }  

まず第一に、宣言された変数の多くは関数でさえ使用されていません!そして、2番目のループで「8」が何を意味するのか本当にわかりません。他のループの「4」は4x4の直交行列ブロックと関係があることを理解しています。誰かが私にここで何が起こっているのかについてより良い考えを教えてもらえますか?

とにかく、誰かが私が使用できる良いコードサンプルを持っていますか?または、CUDAカーネルでランダムなガウス数を生成する別の方法がありますか?コードサンプルは大歓迎です。

ありがとう!

4

3 に答える 3

4

CUDA Toolkit(バージョン3.2以降)に含まれているCURANDを使用できます。それははるかに簡単でしょう!

あなたが投稿したコードに関するいくつかのメモ:

  • Wallaceジェネレーターはガウスからガウスに変換します(つまり、ユニフォームからガウスに変換しません)
  • CUDAコードには2つの暗黙の変数があります:blockIdxおよびthreadIdx-これらはブロックインデックスとスレッドインデックスをブロックで定義します。詳細については、CUDAプログラミングガイドを参照してください。
  • コードはsm_20以降で__mul24を使用しますが、これは実際には「通常の」32ビット乗算よりも遅いため、回避します(簡単にするために古いアーキテクチャでも)
于 2011-01-22T18:40:28.293 に答える
1

高速ウォルシュ-アダマール変換は、加算と減算のパターンによって実行されます。したがって、中心極限定理が適用されます。ウォルシュアダマール変換を受ける均一な乱数の配列は、ガウス/正規分布になります。それについては、技術的な詳細がいくつかあります。アルゴリズムはウォレスによって発見されませんでした。1993/1994年頃に私自身がServoMagazineに最初に掲載されました。ウォルシュアダマール変換に関するコードはwww.code.google.com/p/lemontreeよろしく、SeanO'Connorにあります。

于 2012-06-19T05:47:28.277 に答える
1

ボックスミュラー法も良いです。

于 2011-01-20T05:34:21.180 に答える