Created
December 4, 2020 22:37
-
-
Save imneme/4b9b81af58d35318a07e823128a25576 to your computer and use it in GitHub Desktop.
This code shows self-similarity issues with Vigna's xoshiro256**. The original version of this code was written by Tyge Løvset.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Show self-similarity issues with Vigna's xoshiro256** | |
* | |
* Originally posted in a NumPy developers discussion by Tyge Løvset | |
* but simplified to only mix 32 outputs. | |
* | |
* Compile, and then test with PractRand by running | |
* | |
* ./xoshiro256-similarity \ | |
* | ./RNG_test stdin64 -te 1 -tlmin 15 -tlmax 50 -tlmaxonly -multithreaded | |
* | |
* It should produce output like this | |
* | |
* rng=RNG_stdin64, seed=unknown | |
* length= 8 gigabytes (2^33 bytes), time= 189 seconds | |
* Test Name Raw Processed Evaluation | |
* [Low4/64]BCFN(0+0,13-1,T) R= +9.5 p = 1.3e-4 unusual | |
* [Low1/64]FPF-14+6/4:(0,14-0) R= +18.2 p = 1.7e-16 FAIL | |
* [Low1/64]FPF-14+6/4:(1,14-0) R= +11.3 p = 4.7e-10 very suspicious | |
* [Low1/64]FPF-14+6/4:all R= +15.1 p = 1.1e-13 FAIL | |
* ...and 618 test result(s) without anomalies | |
* | |
* rng=RNG_stdin64, seed=unknown | |
* length= 16 gigabytes (2^34 bytes), time= 345 seconds | |
* Test Name Raw Processed Evaluation | |
* [Low4/64]BCFN(0+0,13-0,T) R= +23.1 p = 6.9e-12 FAIL | |
* [Low1/64]FPF-14+6/4:(0,14-0) R= +39.3 p = 5.9e-36 FAIL !!! | |
* [Low1/64]FPF-14+6/4:(1,14-0) R= +21.5 p = 1.7e-19 FAIL ! | |
* [Low1/64]FPF-14+6/4:(2,14-0) R= +8.7 p = 1.2e-7 mildly suspicious | |
* [Low1/64]FPF-14+6/4:all R= +28.9 p = 1.3e-26 FAIL !! | |
* ...and 655 test result(s) without anomalies | |
* | |
* Original code here | |
* https://github.com/numpy/numpy/issues/16313#issuecomment-642847859 | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
static inline uint64_t rotl(const uint64_t x, int k) { | |
return (x << k) | (x >> (64 - k)); | |
} | |
static inline uint64_t xoshiro256starstar_rand(uint64_t* s) { | |
const uint64_t result = rotl(s[1] * 5, 7) * 9; | |
const uint64_t t = s[1] << 17; | |
s[2] ^= s[0]; | |
s[3] ^= s[1]; | |
s[1] ^= s[2]; | |
s[0] ^= s[3]; | |
s[2] ^= t; | |
s[3] = rotl(s[3], 45); | |
return result; | |
} | |
int main() | |
{ | |
// Only necessary on Windows, but harmless elsewhere. | |
// FILE* f = freopen(NULL, "wb", stdout); | |
#ifndef NTHREADS | |
enum {NTHREADS = 32}; | |
#endif | |
uint64_t seed = 1591888413; // <- e.g. this fails. // (uint64_t) time(NULL); | |
fprintf(stderr, "seed: %lu\n", seed); | |
static uint64_t xo[NTHREADS][4]; | |
for (size_t i = 0; i < NTHREADS; ++i) { | |
xo[i][0] = xo[i][1] = xo[i][2] = xo[i][3] = seed + (12839732 * i); | |
for (int j=0; j<12; ++j) | |
xoshiro256starstar_rand(xo[i]); | |
} | |
static uint64_t buffer[NTHREADS]; | |
while (1) { | |
for (int i=0; i<NTHREADS; ++i) | |
buffer[i] = xoshiro256starstar_rand(xo[i]); | |
fwrite((void*) buffer, sizeof(buffer[0]), NTHREADS, stdout); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment