2

我正在研究 NVIDIA CUDA GPU 上的马尔可夫链蒙特卡洛 (MCMC) 算法实现。CPU MCMC 算法使用高质量的 Mersenne twister 随机数生成器,我想在我编写的 GPU 内核中使用相同的。我一直在寻找 cuRand MT 代码示例。不幸的是,我从未见过任何使用 Mersenne twister 的内核代码示例。标准的 cuRand 库文档为 MTGP(MT for Graphic Processor)提供了一组函数,但不清楚如何使用它们。

CUDA 示例为 MersenneTwisterGP11213.tar.gz 提供了一个示例,但它似乎专门用于请求在 GPU 上快速生成随机数数组、将它们下载到 CPU 内存并在 CPU 上进行的主机代码。还有一篇论文“Massively Parallel RNG using CUDA C, Thrust and C#”。同样,上一节“使用 CUDA C 的 Mersenne Twister 实现”中的作者仅提供了来自“CUDA 示例”的上述主机代码的简化片段。

所以,我的第一个问题是:谁能给我一个使用 cuRand Mersenne twister 的全局设备函数示例?

我还有一个问题。目前我使用 cuRand 库随机数生成器,但我不知道使用的是什么生成器!让我提供几段我的代码。这是生成器初始化:

 __global__ void init_rng(Cmcmcfit *mc) {

        int ist = threadIdx.x*gridDim.x + blockIdx.x;

        if (ist >= mc->nrndst) return; // The last block can have extra threads

        unsigned long long offset = 0;

        curand_init(mc->seed, ist, offset, &mc->rndst[ist]);
}

在其他内核中,我从均匀分布和正态分布中采样数字。所有blockDim.x*gridDim.x生成器的状态数组都保存在全局内存数组mc->rndst[]中。例如,curand_uniform()用于:

  .   .   .   .   .   .
  do { /* Randomly select parameter number k to make step */
    r = curand_uniform(&mc->rndst[ist]);
    k = (int) (mc->nprm*r); /* Random parameter index 0..nprm-1 into ivar[] */
  } while (k >= mc->nprm);
  .   .   .   .   .   .   .   .   .

或者,从高斯分布中采样,curand_normal()使用:

  std = mc->pstp[(Nbeta*k + Ibeta)*Nseq + Iseq]; /* pstp[k,ibeta,iseq] */
  randn = curand_normal(&mc->rndst[ist]);
  p = p + std*randn;

谁能告诉我这里使用了哪些 cuRand 生成器(xorwow、lcs、mtgp ...)(实际上,默认情况下)?

4

1 回答 1

3

curand文档包括有关设备 API示例的部分。第二个示例使用 MTGP 在设备代码中生成随机数,然后在同一个内核中对生成的随机数进行基本计算(计算具有最低位设置的数字。)这似乎是您要问的for(如何在设备上生成随机数并在设备代码中使用它们)。那里缺少什么吗?

此外,在文档中,它表明 curand 使用的默认生成器是 XORWOW:

默认的伪随机生成器 XORWOW...

也在这里。

于 2013-05-27T19:47:50.817 回答