Skip to content

Commit c2c3fb0

Browse files
Sheppard, KevinSheppard, Kevin
authored andcommitted
CLN: Ensure common entropy initialization
Verify entropy initialization for all PRNGs Initial appveyor build config
1 parent 4abf1d5 commit c2c3fb0

File tree

15 files changed

+182
-131
lines changed

15 files changed

+182
-131
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ identical sequence of random numbers for a given seed.
3636
It is essentially complete. There are a few rough edges that need to be smoothed.
3737

3838
* Pickling support
39-
* Verify entropy based initialization for some RNGs
4039
* Stream support for MLFG and MRG32K3A
4140
* Creation of additional streams from a RandomState where supported (i.e.
4241
a `next_stream()` method)

appveyor.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
skip_tags: true
2+
clone_depth: 1
3+
4+
os: Visual Studio 2015
5+
6+
environment:
7+
matrix:
8+
- PY_MAJOR_VER: 2
9+
PYTHON_ARCH: "x86"
10+
- PY_MAJOR_VER: 3
11+
PYTHON_ARCH: "x86_64"
12+
- PY_MAJOR_VER: 3
13+
PYTHON_ARCH: "x86"
14+
15+
build_script:
16+
- ps: Start-FileDownload "https://repo.continuum.io/miniconda/Miniconda$env:PY_MAJOR_VER-latest-Windows-$env:PYTHON_ARCH.exe" C:\Miniconda.exe; echo "Finished downloading miniconda"
17+
- cmd: C:\Miniconda.exe /S /D=C:\Py
18+
- SET PATH=C:\Py;C:\Py\Scripts;C:\Py\Library\bin;%PATH%
19+
- conda config --set always_yes yes
20+
- conda update conda
21+
- conda install numpy cython nose
22+
- pip install . -vvv
23+
24+
test_script:
25+
- nosetests randomstate

randomstate/interface.pyx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ cimport cython
1313
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t
1414
from cpython cimport Py_INCREF
1515

16+
import randomstate
1617
from binomial cimport binomial_t
1718
from cython_overrides cimport PyFloat_AsDouble, PyInt_AsLong, PyErr_Occurred, PyErr_Clear
1819

@@ -214,7 +215,7 @@ cdef class RandomState:
214215
def __reduce__(self):
215216
# TODO: This is wrong
216217
# TODO: Removed np.random.__RandomState_ctor - This is needed on a RNG-by-RNG basis
217-
return ((), (), self.get_state())
218+
return (randomstate.prng.__generic_ctor, (RNG_NAME,), self.get_state())
218219

219220
IF RNG_NAME == 'mt19937':
220221
def seed(self, seed=None):

randomstate/prng/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,23 @@
55
from randomstate.prng.pcg64 import pcg64
66
from randomstate.prng.xorshift1024 import xorshift1024
77
from randomstate.prng.xorshift128 import xorshift128
8+
9+
def __generic_ctor(rng_name='mt19937'):
10+
print(rng_name)
11+
if rng_name == 'mt19937':
12+
mod = mt19937
13+
elif rng_name == 'mlfg_1279_861':
14+
mod = mlfg_1279_861
15+
elif rng_name == 'mrg32k3a':
16+
mod = mrg32k3a
17+
elif rng_name == 'pcg32':
18+
mod = pcg32
19+
elif rng_name == 'pcg64':
20+
mod = pcg64
21+
elif rng_name == 'pcg32':
22+
mod = pcg32
23+
elif rng_name == 'xorshift128+':
24+
mod = xorshift128
25+
elif rng_name == 'xorshift1024*':
26+
mod = xorshift1024
27+
return mod.RandomState(0)

randomstate/shims/mlfg-1279-861/mlfg-1279-861-shim.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ extern inline uint32_t random_uint32(aug_state* state);
44

55
extern inline uint64_t random_uint64(aug_state* state);
66

7-
extern inline void set_seed(aug_state* state, uint64_t seed);
7+
extern inline double random_double(aug_state* state);
88

9-
extern inline void entropy_init(aug_state* state);
9+
void set_seed(aug_state* state, uint64_t val)
10+
{
11+
mlfg_seed(state->rng, val);
12+
}
1013

11-
extern inline double random_double(aug_state* state);
14+
void entropy_init(aug_state* state)
15+
{
16+
uint64_t seeds[1];
17+
entropy_fill((void*) seeds, sizeof(seeds));
18+
mlfg_seed(state->rng, seeds[0]);
19+
}

randomstate/shims/mlfg-1279-861/mlfg-1279-861-shim.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,6 @@ inline uint64_t random_uint64(aug_state* state)
3232
return out;
3333
}
3434

35-
inline void set_seed(aug_state* state, uint64_t val)
36-
{
37-
mlfg_seed(state->rng, val);
38-
}
39-
40-
inline void entropy_init(aug_state* state)
41-
{
42-
uint64_t seeds[1];
43-
entropy_fill((void*) seeds, sizeof(seeds));
44-
mlfg_seed(state->rng, seeds[0]);
45-
}
4635

4736
inline double random_double(aug_state* state)
4837
{
@@ -53,3 +42,7 @@ inline double random_double(aug_state* state)
5342
b = (rn & 0xFFFFFFFFULL) >> 6;
5443
return (a * 67108864.0 + b) / 9007199254740992.0;
5544
}
45+
46+
extern void set_seed(aug_state* state, uint64_t seed);
47+
48+
extern void entropy_init(aug_state* state);

randomstate/shims/mlfg-1279-861/mlfg-1279-861.pxi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ Parameters
8282
seed : {None, int}, optional
8383
Random seed initializing the pseudo-random number generator.
8484
Can be an integer in [0, 2**64] or ``None`` (the default).
85-
If `seed` is ``None``, then `mlfg_1279_861.RandomState` will try to read data
86-
from ``/dev/urandom`` (or the Windows analogue) if available or seed from
87-
the clock otherwise.
85+
If `seed` is ``None``, then `mlfg_1279_861.RandomState` will try to read
86+
entropy from ``/dev/urandom`` (or the Windows analogue) if available to
87+
produce a 64-bit seed. If unavailable, the a 64-bit hash of the time
88+
(and process ID on Unix) is used.
8889
8990
Notes
9091
-----
9192
The state of the MLFG(1279,861,*) PRNG is represented by 1279 64-bit unsigned
92-
integers as well as a single 32-bit integer representing the location in the
93-
state array of the next value.
93+
integers as well as a two 32-bit integers representing the location in the
94+
state array of the current and lagged values.
9495
"""

randomstate/shims/mrg32k3a/mrg32k3a-shim.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,39 @@ extern inline uint32_t random_uint32(aug_state* state);
44

55
extern inline uint64_t random_uint64(aug_state* state);
66

7-
extern inline void set_seed(aug_state* state, uint64_t seed);
7+
extern inline double random_double(aug_state* state);
88

9-
extern inline void entropy_init(aug_state* state);
9+
void entropy_init(aug_state* state)
10+
{
11+
uint32_t buf[6] = { 0 };
12+
int64_t seeds[6];
13+
uint32_t i, val;
14+
int all_zero = 0;
15+
while (!all_zero)
16+
{
17+
entropy_fill((void*) buf, sizeof(buf));
18+
for (i = 0; i<6; i++)
19+
{
20+
val = (i < 3) ? STATE_MAX_VALUE_1 : STATE_MAX_VALUE_2;
21+
seeds[i] = (int64_t)(buf[i] % val);
22+
all_zero = all_zero || (seeds[i] > 0);
23+
}
24+
}
25+
init_state(state, seeds);
26+
}
1027

11-
extern inline void init_state(aug_state* state, int64_t val[6]);
28+
void set_seed(aug_state* state, uint64_t val)
29+
{
30+
mrg32k3a_seed(state->rng, val);
31+
}
32+
33+
void init_state(aug_state* state, int64_t vals[6])
34+
{
35+
state->rng->s10 = vals[0];
36+
state->rng->s11 = vals[1];
37+
state->rng->s12 = vals[2];
38+
state->rng->s20 = vals[3];
39+
state->rng->s21 = vals[4];
40+
state->rng->s22 = vals[5];
41+
}
1242

13-
extern inline double random_double(aug_state* state);

randomstate/shims/mrg32k3a/mrg32k3a-shim.h

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,42 +31,15 @@ inline uint64_t random_uint64(aug_state* state)
3131
return (((uint64_t) mrg32k3a_random(state->rng) << 32) | mrg32k3a_random(state->rng));
3232
}
3333

34-
inline void set_seed(aug_state* state, uint64_t val)
34+
inline double random_double(aug_state* state)
3535
{
36-
mrg32k3a_seed(state->rng, val);
36+
int32_t a = random_uint32(state) >> 5, b = random_uint32(state) >> 6;
37+
return (a * 67108864.0 + b) / 9007199254740992.0;
3738
}
3839

39-
inline void init_state(aug_state* state, int64_t val[6])
40-
{
41-
state->rng->s10 = val[0];
42-
state->rng->s11 = val[1];
43-
state->rng->s12 = val[2];
44-
state->rng->s20 = val[3];
45-
state->rng->s21 = val[4];
46-
state->rng->s22 = val[5];
47-
}
40+
extern void set_seed(aug_state* state, uint64_t val);
4841

49-
inline void entropy_init(aug_state* state)
50-
{
51-
uint32_t buf[6] = { 0 };
52-
int64_t seeds[6];
53-
uint32_t i, val;
54-
int all_zero = 0;
55-
while (!all_zero)
56-
{
57-
entropy_fill((void*) buf, sizeof(buf));
58-
for (i = 0; i<6; i++)
59-
{
60-
val = (i < 3) ? STATE_MAX_VALUE_1 : STATE_MAX_VALUE_2;
61-
seeds[i] = (int64_t)(buf[i] % val);
62-
all_zero = all_zero || (seeds[i] > 0);
63-
}
64-
}
65-
init_state(state, seeds);
66-
}
42+
extern void init_state(aug_state* state, int64_t vals[6]);
43+
44+
extern void entropy_init(aug_state* state);
6745

68-
inline double random_double(aug_state* state)
69-
{
70-
int32_t a = random_uint32(state) >> 5, b = random_uint32(state) >> 6;
71-
return (a * 67108864.0 + b) / 9007199254740992.0;
72-
}

randomstate/shims/random-kit/random-kit-shim.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ extern inline uint32_t random_uint32(aug_state* state);
44

55
extern inline uint64_t random_uint64(aug_state* state);
66

7-
extern inline void set_seed(aug_state* state, uint32_t seed);
7+
extern inline double random_double(aug_state* state);
88

99
extern void set_seed_by_array(aug_state* state, unsigned long init_key[], int key_length)
1010
{
1111
init_by_array(state->rng, init_key, key_length);
1212
}
1313

14-
extern inline void entropy_init(aug_state* state);
14+
void set_seed(aug_state* state, uint32_t seed)
15+
{
16+
rk_seed(state->rng, seed);
17+
}
1518

16-
extern inline double random_double(aug_state* state);
19+
void entropy_init(aug_state* state)
20+
{
21+
uint32_t seeds[1];
22+
entropy_fill((void*) seeds, sizeof(seeds));
23+
set_seed(state, seeds[0]);
24+
}

0 commit comments

Comments
 (0)