2013-05-27 3 views
1

Я работаю над реализацией алгоритма Марковской цепи Монте-Карло (MCMC) на графическом процессоре NVIDIA CUDA. Алгоритм CPU MCMC использует высококачественный генератор случайных чисел Twister Misterenne, и я хотел бы использовать его в ядрах GPU, которые я написал. Я долго искал примеры кода cuRand MT. К сожалению, я никогда не видел ни одного примера кода ядра, использующего Twers Mersenne. Стандартная документация библиотеки cuRand предоставляет набор функций для MTGP (MT для графического процессора), но неясно, как их использовать.cuRand Mersenne twister __device__ пример кода ядра ядра

The CUDA Samples предоставляет MersenneTwisterGP11213.tar.gz пример, но, по-видимому, он предназначен исключительно для хост-кода, который запрашивает быстрое генерирование массива случайных чисел на графическом процессоре, загружает их в память процессора и переходит на CPU. Существует также бумага "Massively Parallel RNG using CUDA C, Thrust and C#". Опять же, автор в последнем разделе «« Внедрение Mersenne Twister с использованием CUDA C » обеспечивает просто упрощенную часть вышеупомянутого кода хоста от « Образцы CUDA ».

Итак, мой первый вопрос: кто-нибудь может дать мне пример глобального или устройства функции, которая использует твистер cuRand Мерсенна?

У меня есть еще один вопрос. В настоящее время я использую генератор случайных чисел библиотеки 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, ЛВП, mtgp. ..) используется здесь (фактически, по умолчанию)?

ответ

2

curand documentation содержит раздел о API устройства examples. Второй пример использует MTGP для генерации случайных чисел в коде устройства, а затем в том же ядре выполняется базовое вычисление на случайных числах, сгенерированных (подсчитайте число, которое имеет самый низкий бит). Это, похоже, то, что вы просите для (как создавать случайные числа на устройстве и использовать их в коде устройства). Что-то там отсутствует?

Кроме того, in the documentation, это указывает на то, что генератор по умолчанию, используемый curand является XORWOW:

генератор псевдослучайных по умолчанию, XORWOW ...

и here также.

+0

Роберт, спасибо вам большое. Похоже, это ТОЧНО, о чем я просил! – Benkevitch

+0

@Benkevitch: Если ответ Роберта ответил на ваш вопрос (кажется, он и сделал), пожалуйста, примите его ответ, чтобы вопрос был удален из списка неотвеченных вопросов. – njuffa

Смежные вопросы