Я пытаюсь создать генератор псевдослучайных чисел (PRNG) в металле, сродни thrust
ГСЧ, где каждый раз, когда вы вызываете ГСЧ в потоке он производит другое случайное число, заданное конкретным начальным числом, которое в этом случае будет thread_position_in_grid
, У меня все отлично настроено, и сейчас я получаю красивую равномерно случайную картинку, используя код, который у меня есть.
Тем не менее, мой код работает только один раз на поток. Я хочу реализовать next_rng()
функция, которая возвращает новый rng
используя последний результат в качестве семени. Однако у меня возникли проблемы с сохранением этого последнего результата, поскольку мой ГСЧ является пространством имен, и я могу сохранить только последний результат в constant
адресное пространство, которое не подлежит обновлению. Есть ли способ обойти это / реструктурировать мой код, чтобы избежать этого?
Лучшая помощь, которую я мог найти в Интернете, была этот ТАК пост это, к сожалению, не работает со мной, потому что я не могу объявить переменную как статическую внутри функции, как они делают в своем решении.
Я открыт для реструктуризации своего кода любым способом, если это поможет. Могу ли я превратить это в статический класс или класс или что-то? Понятия не имею, но я просто хочу PRNG
Мой код (упрощенный) в основном имеет ту же структуру, что и этот пост:
namespace metal_rng {
thread unsigned* last_seed() {
thread uint last_seed = 1; // Doesn't work because last-seed falls out of scope after the function quits
// The following comment line doesn't even compile:
// thread static uint last_seed = 1;
return &last_seed;
}
unsigned TausStep(const unsigned z, const int s1, const int s2, const int s3, const unsigned M)
{
unsigned b=(((z << s1) ^ z) >> s2);
return (((z & M) << s3) ^ b);
}
device float rng(const int initial_seed) {
int seed = initial_seed * 1099087573UL;
unsigned hashed = (1664525*(*last_seed()) + 1013904223UL);
*last_seed() = hashed
return (hashed) * 2.3283064365387e-10;
}
device float next_rng() {
if (*last_seed() == 0) {
return 0.0;
} else {
unsigned hashed = (1664525*(*last_seed()) + 1013904223UL);
return (hashed) * 2.3283064365387e-10;
}
}
}
Фреймворк сделан и упакован аккуратно здесь: Ссылка на сайт
В конечном итоге я использовал предложения @KenThomases и просто создал класс для ГСЧ. Я упаковал код и позвонил в ГСЧ Loki
, Вот ссылка на репо если кто-то хочет использовать его в будущем.
Других решений пока нет …