Я работаю над реализацией алгоритма Монте-Карло цепи Маркова (MCMC) на NVIDIA CUDA GPU. Алгоритм CPU MCMC использует высококачественный генератор случайных чисел Mersenne Twister, и я хотел бы использовать его в написанных мною ядрах графического процессора. Я давно искал примеры кода cuRand MT. К сожалению, я никогда не видел примеров кода ядра, использующего Twister Мерсенна. Стандартная документация библиотеки cuRand предоставляет набор функций для MTGP (MT для графического процессора), но неясно, как их использовать.
Примеры CUDA содержат пример MersenneTwisterGP11213.tar.gz , но, похоже, он предназначен исключительно для кода хоста, который запрашивает быстрое создание массива случайных чисел на GPU, загружает их в память CPU и обрабатывает CPU. Существует также статья «Массово параллельный ГСЧ с использованием CUDA C, Thrust и C #» а>. Опять же, автор в последнем разделе «Реализация Mersenne Twister с использованием CUDA C» предоставляет только упрощенную часть вышеупомянутого кода хоста из «Примеры CUDA».
Итак, мой первый вопрос: может ли кто-нибудь привести мне пример функции global или device, которая использует twister cuRand Mersenne?
У меня есть еще один вопрос. В настоящее время я использую генератор случайных чисел библиотеки 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 ...) здесь используется (собственно, по умолчанию)?