我正在研究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 ...)(实际上,默认情况下)?
答案 0 :(得分:3)
curand documentation包含有关设备API examples的部分。第二个例子使用MTGP在设备代码中生成随机数,然后在同一个内核中对生成的随机数进行基本计算(计算具有最低位设置的数字)。这似乎就是你所要求的for(如何在设备上生成随机数并在设备代码中使用它们)。那里缺少什么?
另外,in the documentation,它表示curand使用的默认生成器是XORWOW:
默认伪随机生成器,XORWOW,...
和here也是。