Skip to content

Support non deterministic generator #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 5, 2019

Conversation

oleksandr-pavlyk
Copy link
Contributor

  1. Introduces support for non-deterministic hardware instruction RDRAND-based basic random number generator on relevant architectures.
In [1]: import mkl_random, numpy as np

In [2]: rs = mkl_random.RandomState(brng='NON_DETERMINISTIC')

In [3]: rs.randn(10)
Out[3]: 
array([ 1.69156146,  0.56649183,  0.26323201,  0.46801072, -0.97351586,
       -1.43365592, -0.73531088, -0.90349218,  0.23288929, -0.24443191])

Because it is hardware-based TRNG, reading pickled state does not produce the same randomness:

In [10]: import pickle

In [11]: rs = mkl_random.RandomState(brng='non_deterministic')

In [12]: rs2 = pickle.loads(pickle.dumps(rs))

In [13]: rs.randint(0, 2**32, size=5)
Out[13]: array([ 649482295, 3967010060, 2807993698, 1176520041, 2802939972])

In [14]: rs2.randint(0, 2**32, size=5)
Out[14]: array([  58520572, 2008182244, 2128388840, 2600218768, 2531220520])

compare to doing the same with pseudo-randomness generator:

In [15]: rs = mkl_random.RandomState(brng='SFMT19937')

In [16]: rs2 = pickle.loads(pickle.dumps(rs))

In [17]: rs.randint(0, 2**32, size=5)
Out[17]: array([3569610330,  417479194,  261680738, 3266235240, 3210854201])

In [18]: rs2.randint(0, 2**32, size=5)
Out[18]: array([3569610330,  417479194,  261680738, 3266235240, 3210854201])
  1. Use Intel(R) Math Kernel Library viRngMultinomial directly to draw samples from multinomial distribution
In [19]: pvec = mkl_random.rand(100)

In [20]: pvec /= pvec.sum()

In [21]: pvec.sum()
Out[21]: 1.0

In [22]: %timeit mkl_random.multinomial(1000, pvec, size=10**5)
642 ms ± 1.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [23]: s = mkl_random.multinomial(1000, pvec, size=10**5)

In [24]: s[:, 0].mean()
Out[24]: 8.29136

In [25]: pvec[0] * 1000
Out[25]: 8.28811517092862

```
rs = mkl_random.RandomState(brng='NON_DETERMINSTIC')
rs.randn(10)
```

The non-deterministic generator is True RNG, based on processor
instruction RDRAND, see

https://software.intel.com/en-us/mkl-developer-reference-c-basic-generators

Also reorgnalized setup to use mkl_random/_version.py, and bumped
the version to 1.1.0
```
In [1]: import mkl_random, numpy as np

In [2]: %time mkl_random.multinomial(527, np.array([1/16, 3/16, 5/16, 7/16], 'd'), size=10**6)
CPU times: user 820 ms, sys: 0 ns, total: 820 ms
Wall time: 819 ms
Out[2]:
array([[ 29,  90, 176, 232],
       [ 32,  91, 185, 219],
       [ 35,  90, 169, 233],
       ...,
       [ 42,  93, 157, 235],
       [ 28, 105, 152, 242],
       [ 32,  79, 179, 237]], dtype=int32)

In [3]: %timeit mkl_random.multinomial(527, np.array([1/16, 3/16, 5/16, 7/16], 'd'), size=10**6)
803 ms ± 9.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [4]: %timeit mkl_random.multinomial(527, np.array([1/16, 3/16, 5/16, 7/16], 'd'), size=10**5)
80.5 ms ± 874 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
```

Previously,

```
In [1]: import mkl_random, numpy as np

In [2]: %timeit mkl_random.multinomial(527, np.array([1/16, 3/16, 5/16, 7/16], 'd'), size=10**6)
1.35 s ± 2.35 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit mkl_random.multinomial(527, np.array([1/16, 3/16, 5/16, 7/16], 'd'), size=10**5)
135 ms ± 613 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
```
@oleksandr-pavlyk oleksandr-pavlyk merged commit 5b2ee1a into master Sep 5, 2019
@oleksandr-pavlyk oleksandr-pavlyk deleted the support-non-deterministic-generator branch September 5, 2019 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant