2011-01-20 59 views
1

我在互聯網上搜索了很多,以找到在我的CUDA設備上,在內核中生成隨機數的方法。數字必須來自高斯分佈。從CUDA中的高斯分佈生成隨機數

The best thing I found來自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]; 
    } 

首先,很多聲明的變量甚至沒有在函數中使用!我真的不明白第二回路中的「8」是什麼。我知道其他循環中的「4」與4x4正交矩陣塊有關,對嗎?任何人都可以更好地瞭解這裏發生的事情嗎?

無論如何,有沒有人有我可以使用的任何好的代碼示例?還是有人有另一種方式在CUDA內核中產生隨機高斯數字?代碼示例將不勝感激。

謝謝!

回答

3

您可以使用CUDA工具包(版本3.2和更高版本)附帶的CURAND。這會更簡單!

你發佈的代碼的幾個注意事項:

  • 華萊士發電機將高斯高斯(即不統一高斯)
  • CUDA代碼有兩個隱含的變量:blockIdxthreadIdx - 這些定義塊索引和線程索引,請參閱CUDA Programming Guide以獲取更多信息
  • 代碼在sm_20上使用__mul24,後面這實際上比「普通」32位乘法要慢,所以我會避免它(即使在較舊的體系結構中簡單)
1

Box-Muller method也不錯。

+0

查找出的不穩定性,當U1幾乎爲零,不過,我剛剛被咬傷由那一個 - 堅硬。 – endian 2011-06-13 14:10:39

1

Fast Walsh Hadamard變換是通過加法和減法的模式完成的。因此,中心極限定理適用。經歷Walsh Hadamard變換的均勻隨機數組將具有高斯/正態分佈。這裏有一些細微的技術細節。算法沒有被華萊士發現。它自己在1993/1994左右首次在伺服雜誌上發表。 我對沃爾什阿達瑪碼在www.code.google.com/p/lemontree變換 問候, 肖恩·奧康納