If parameter p.deterministic is true, we'll initialize the RNG with the seed specified in parameter p.RNGSeed, otherwise we'll initialize the RNG with a random seed. This initializes both the Marsaglia and the Jenkins algorithms. The member function operator() determines which algorithm is actually used.
| 28 | // the Jenkins algorithms. The member function operator() determines |
| 29 | // which algorithm is actually used. |
| 30 | void RandomUintGenerator::initialize() |
| 31 | { |
| 32 | if (p.deterministic) { |
| 33 | // Initialize Marsaglia. Overflow wrap-around is ok. We just want |
| 34 | // the four parameters to be unrelated. In the extremely unlikely |
| 35 | // event that a coefficient is zero, we'll force it to an arbitrary |
| 36 | // non-zero value. Each thread uses a different seed, yet |
| 37 | // deterministic per-thread. |
| 38 | rngx = p.RNGSeed + 123456789 + omp_get_thread_num(); |
| 39 | rngy = p.RNGSeed + 362436000 + omp_get_thread_num(); |
| 40 | rngz = p.RNGSeed + 521288629 + omp_get_thread_num(); |
| 41 | rngc = p.RNGSeed + 7654321 + omp_get_thread_num(); |
| 42 | rngx = rngx != 0 ? rngx : 123456789; |
| 43 | rngy = rngy != 0 ? rngy : 123456789; |
| 44 | rngz = rngz != 0 ? rngz : 123456789; |
| 45 | rngc = rngc != 0 ? rngc : 123456789; |
| 46 | |
| 47 | // Initialize Jenkins determinstically per-thread: |
| 48 | a = 0xf1ea5eed; |
| 49 | b = c = d = p.RNGSeed + omp_get_thread_num(); |
| 50 | if (b == 0) { |
| 51 | b = c = d + 123456789; |
| 52 | } |
| 53 | } else { |
| 54 | // Non-deterministic initialization. |
| 55 | // First we will get a random number from the built-in mt19937 |
| 56 | // (Mersenne twister) generator and use that to derive the |
| 57 | // starting coefficients for the Marsaglia and Jenkins RNGs. |
| 58 | // We'll seed mt19937 with time(), but that has a coarse |
| 59 | // resolution and multiple threads might be initializing their |
| 60 | // instances at nearly the same time, so we'll add the thread |
| 61 | // number to uniquely seed mt19937 per-thread. |
| 62 | std::mt19937 generator(time(0) + omp_get_thread_num()); |
| 63 | |
| 64 | // Initialize Marsaglia, but don't let any of the values be zero: |
| 65 | do { rngx = generator(); } while (rngx == 0); |
| 66 | do { rngy = generator(); } while (rngy == 0); |
| 67 | do { rngz = generator(); } while (rngz == 0); |
| 68 | do { rngc = generator(); } while (rngc == 0); |
| 69 | |
| 70 | // Initialize Jenkins, but don't let any of the values be zero: |
| 71 | a = 0xf1ea5eed; |
| 72 | do { b = c = d = generator(); } while (b == 0); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | |
| 77 | // This returns a random 32-bit integer. Neither the Marsaglia nor the Jenkins |
nothing calls this directly
no outgoing calls
no test coverage detected