|
1 | 1 | How-to Guides
|
2 | 2 | =============
|
3 | 3 |
|
4 |
| -To be written. |
| 4 | +How to save and resume long computation |
| 5 | +--------------------------------------- |
| 6 | + |
| 7 | +:class:`RandomState` is pickleable, and pickling allows to save and restore |
| 8 | +the internal state of the quasi-random number generators. |
| 9 | + |
| 10 | +.. code-block:: python |
| 11 | + :caption: Saving state of quasi-random basic random number generators |
| 12 | +
|
| 13 | + import numpy as np |
| 14 | + import mkl_random |
| 15 | + import pickle |
| 16 | +
|
| 17 | + rs = mkl_random.RandomState(seed=777, brng="r250") |
| 18 | + draw = rs.standard_normal(size=1357913) |
| 19 | +
|
| 20 | + # pickle random state |
| 21 | + saved = pickle.dumps(rs) |
| 22 | +
|
| 23 | + # draw some numbers as if computation were to continue |
| 24 | + post_draw = rs.gamma(5, 1, size=100) |
| 25 | +
|
| 26 | + # restore random state, and continue from |
| 27 | + restored_rs = pickle.loads(saved) |
| 28 | + resumed_draw = restored_rs.gamma(5, 1, size=100) |
| 29 | + |
| 30 | + # sample from restored stated is the same as sample |
| 31 | + # from the original one |
| 32 | + assert np.array_equal(restored_rs, resumed_draw) |
| 33 | +
|
| 34 | +
|
| 35 | +Stochastic computations in parallel with multiprocessing |
| 36 | +-------------------------------------------------------- |
| 37 | + |
| 38 | +When performing stochastic computations in parallel, care is due to ensure |
| 39 | +statistical independence of samples drawn in parallel. |
| 40 | + |
| 41 | +Basic quasi-random number generators provide different means to accomplishing |
| 42 | +this. Some support :meth:`skipahead` method or :meth:`leapfrog` method, while |
| 43 | +others provide a fixed-size family of generators with nice property that generators |
| 44 | +from such family, initialized equally, produce streams of randomness statistically |
| 45 | +indistunguishable from independent. |
| 46 | + |
| 47 | +.. py:method:: skipahead(nskips) |
| 48 | + :canonical: mkl_random.RandomState.skipahead |
| 49 | + |
| 50 | + Advance the state of the generator using skip-ahead method, or raise :code:`ValueError` |
| 51 | + exception if not supported. |
| 52 | + |
| 53 | + The argument `nskips` must be a positive Python integer. |
| 54 | + |
| 55 | + The method is supported for :ref:`"philox4x32x10" <philox4x32x10_brng>`, :ref:`"mrg32k3a" <mrg32k3a_brng>`, |
| 56 | + :ref:`"mcg31m1" <mcg31m1_brng>`, :ref:`"mcg59" <mcg59_brng>`, :ref:`"wh" <wh_brng>`, |
| 57 | + :ref:`"mt19937" <mt19937_brng>`, :ref:`"sfmt19937" <sfmt19937_brng>`, and :ref:`"ars5" <ars5_brng>` |
| 58 | + basic random number generators. |
| 59 | + |
| 60 | +.. note:: |
| 61 | + When using :meth:`skipahead`, it is important to ensure that a parallel task does not consume more than |
| 62 | + :code:`nskips` states, otherwise streams of randomness begin to overlap and the assumption of statistical |
| 63 | + independence breaks down. |
| 64 | + |
| 65 | +.. py:method:: leapfrog(k, nstreams) |
| 66 | + :canonical: mkl_random.RandomState.leapfrog |
| 67 | + |
| 68 | + Initialize the state of the generator using leap-frog method, or raise :code:`ValueError` |
| 69 | + exception if not supported. |
| 70 | + |
| 71 | + The leap-frog method partitions state tragectory into :code:`nstream` interleaved non-overlapping |
| 72 | + sub-sequences, and argument :code:`k` identifies the subsequence. |
| 73 | + |
| 74 | + The method is supported for :ref:`"mcg31m1" <mcg31m1_brng>`, :ref:`"mcg59" <mcg59_brng>`, and :ref:`"wh" <wh_brng>` |
| 75 | + basic pseudo-random number generators. |
| 76 | + |
| 77 | +.. note:: |
| 78 | + When using :meth:`leapfrog` or :meth:`skipahead` methods one must remember that parallel tasks partition |
| 79 | + generators period and choose a generator with sufficiently long period to avoid cycling over the period |
| 80 | + more than once, as doing so also breaks the assumption of statistical independence and may compromise |
| 81 | + correctness of the simulation. |
| 82 | + |
| 83 | +:mod:`mkl_random` also provides two families of basic pseudo-random number generators, :ref:`"mt2203" <mt2203_brng>` and |
| 84 | +:ref:`"wh" <wh_brng>`, with property that members from particular family, initialized equally, produce streams of |
| 85 | +randomness stasistically indistunguishable from independent. To use such families in parallel computation, assign |
| 86 | +difference family generators to different parallel workers and sample those assigned generators in each parallel worker. |
| 87 | +Please refer to "examples/" folder in the `GitHub repo <https://github.com/IntelPython/mkl_random>`_ for more details. |
0 commit comments