cuRand Mersenne twister __device__方内核代码示例

时间:2013-05-27 19:01:25

标签: random cuda mcmc mersenne-twister

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

The CUDA Samples提供MersenneTwisterGP11213.tar.gz示例,但它似乎专门用于请求在GPU上快速生成随机数组的主机代码,将它们下载到CPU内存,然后继续中央处理器。 还有一篇论文"Massively Parallel RNG using CUDA C, Thrust and C#"。同样,最后一节“使用CUDA C的Mersenne Twister实现”中的作者仅提供了“CUDA Samples”中上述主机代码的简化部分。

所以,我的第一个问题是:有人能给我一个使用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 ...)(实际上,默认情况下)?

1 个答案:

答案 0 :(得分:3)

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

另外,in the documentation,它表示curand使用的默认生成器是XORWOW:

  

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

here也是。