我正在研究 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 ...)(实际上,默认情况下)?