mercredi 22 novembre 2017

Metal - Namespace variable that is local to a thread?

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