Генератор случайных чисел в CUDA

Я боролся с этим весь день, я пытаюсь получить генератор случайных чисел для потоков в моем коде CUDA. Я просмотрел все форумы, и да, эта тема подходит немного, но я потратил часы, пытаясь разгадать все виды кодов безрезультатно. Если кто-нибудь знает простой метод, вероятно,устройства ядро, которое может быть вызвано для возврата случайного поплавка между 0 и 1, или целое число, которое я могу преобразовать, я был бы очень благодарен.

опять же, я надеюсь используйте случайное число в ядре, как, например, rand ().

спасибо заранее

8 ответов


Я не уверен, что понимаю, почему вам нужно что-то особенное. Любой традиционный PRNG должен портировать более или менее напрямую. А линейный конгруэнтный должно работать нормально. У вас есть какие-то особые свойства, которые вы пытаетесь установить?


для тех, кто заинтересован, теперь вы можете сделать это через cuRAND.


Я думаю, что любое обсуждение этого вопроса должно ответить на первоначальный запрос Зенны, и это для нить уровень реализация. В частности устройства Это можно вызвать изнутри ядро или поток. Извините, если я переборщил с "жирными" фразами, но я действительно думаю, что ответы до сих пор не совсем касаются того, что здесь ищут.

библиотека Куранда - ваш лучший выбор. Я ценю, что люди хотят изобретите колесо (это заставляет ценить и более правильно использовать сторонние библиотеки), но высокопроизводительные высококачественные генераторы чисел многочисленны и хорошо протестированы. Лучшая информация, которую я могу порекомендовать, - это документация для библиотеки GSL на разных генераторах here:http://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

для любого серьезного кода лучше всего использовать один из основных алгоритмов, которые математики / компьютерщики снова и снова ищут системные недостатки. "Mersenne twister" - это что-то с периодом (цикл повторения) порядка 10^6000 (алгоритм MT19997 означает" Mersenne Twister 2^19997"), который был специально адаптирован для Nvidia для использования на уровне потока в потоках той же основы с использованием вызовов идентификаторов потоков в качестве семян. Смотри документ here:http://developer.download.nvidia.com/compute/cuda/2_2/sdk/website/projects/MersenneTwister/doc/MersenneTwister.pdf - ... Я действительно работаю над реализацией somehting с помощью этой библиотеки, и если я заставлю ее работать правильно, я опубликую свой код. Nvidia имеет несколько примеров на своем сайте документации для текущего набора инструментов CUDA.

Примечание: просто для записи я не работаю для Nvidia, но я признаю, что их документация и дизайн абстракции для CUDA-это то, что я до сих пор впечатлен.



в зависимости от вашего приложения вы должны быть осторожны с использованием LCGs, не учитывая, будут ли потоки (один поток на поток) перекрываться. Вы можете реализовать чехарду с LCG, но тогда вам понадобится достаточно длительный период LCG, чтобы гарантировать, что последовательность не повторится.

пример чехарда может быть:

template <typename ValueType>
__device__ void leapfrog(unsigned long &a, unsigned long &c, int leap)
{
    unsigned long an = a;
    for (int i = 1 ; i < leap ; i++)
        an *= a;
    c = c * ((an - 1) / (a - 1));
    a = an;
}

template <typename ValueType>
__device__ ValueType quickrand(unsigned long &seed, const unsigned long a, const unsigned long c)
{
    seed = seed * a;
    return seed;
}

template <typename ValueType>
__global__ void mykernel(
    unsigned long *d_seeds)
{
    // RNG parameters
    unsigned long a = 1664525L;
    unsigned long c = 1013904223L;
    unsigned long ainit = a;
    unsigned long cinit = c;
    unsigned long seed;

    // Generate local seed
    seed = d_seeds[bid];
    leapfrog<ValueType>(ainit, cinit, tid);
    quickrand<ValueType>(seed, ainit, cinit);
    leapfrog<ValueType>(a, c, blockDim.x);

    ...
}

но тогда период этого генератора, вероятно, недостаточен в большинстве случаев.

честно говоря, я бы посмотрел на использование сторонней библиотеки, такой как пилить. В SDK также есть некоторые пакетные генераторы, но это, вероятно, не то, что вы ищете в этом случае.

редактировать

Так как это только что проголосовало, я считаю, что стоит обновить, чтобы упомянуть, что cuRAND, как упоминалось в более поздних ответах на этот вопрос, доступен и предоставляет ряд генераторов и распределений. Это определенно самое простое место начать.


лучший способ для этого-написать свой собственный устройства


существует пакет MDGPU (GPL), который включает в себя реализацию функции GNU rand48 () для CUDA здесь.

Я нашел его (довольно легко, используя Google, который, я полагаю, вы пробовали: -) на форумах NVidia здесь.


Я не нашел хорошего генератора параллельных чисел для CUDA, однако я нашел генератор параллельных случайных чисел, основанный на академических исследованиях здесь:http://sprng.cs.fsu.edu/


вы можете попробовать Мерсенн Твистер для графических процессоров

Он основан на SIMD-ориентированном быстром Mersenne Twister (SFMT), который является довольно быстрым и надежным генератором случайных чисел. Он проходит тесты MARSAGLIAS DIEHARD для генераторов случайных чисел.