I'm trying to create a Pseudo Random Number Generator (PRNG) in Metal, akin to thrust
's RNG , where every time you call the RNG within a thread it produces a different random number given a particular seed, which in this case, will be the thread_position_in_grid
. I have it set up perfectly, and I get a nice uniformly random picture right now using the code I have.
However, my code only works once per thread. I want to implement a next_rng()
function that returns a new rng
using the last result as a seed. I am having trouble storing that last result, however, as my RNG is a namespace, and I can only store the last result in constant
address space, which is un-updateable. Is there any way to get around this/restructure my code to avoid this?
The best help I could find online was this SO post that unfortunately doesn't work with me because I can't declare a variable as static within a function as they do in their solution.
My code (simplified) basically has the same structure as that post's:
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;
}
}
}
Aucun commentaire:
Enregistrer un commentaire