pymor.tools.random
¶
Methods for managing random state in pyMOR.
Many algorithms potentially depend directly or indirectly on randomness.
To ensure reproducible execution of pyMOR code without having to pass around
a random number generator object everywhere, pyMOR manages a global random number generator
object. This object is initialized automatically from a configurable default
random seed during startup and can be obtained by calling get_rng
.
The returned object is a subclass of numpy.random.Generator
and
inherits all its sampling methods.
To locally reset the global random number generator
in order to deterministically sample random
numbers independently of previously executed code, a new random number generator
can be created
via new_rng
and installed by using it as a context manager. For
instance, to sample a deterministic initialization vector for an iterative
algorithm we can write:
with new_rng(12345):
U0 = some_operator.source.random()
Using a single global random state can lead to either non-deterministic or
correlated behavior in parallel or asynchronous code. get_rng
takes
provisions to detect such situations and issue a warning. In such cases
spawn_rng
needs to be called on the entry points of concurrent code
paths to ensure the desired behavior. For an advanced example, see
pymor.algorithms.hapod
.
Module Contents¶
- class pymor.tools.random.RNG(seed_seq)[source]¶
Bases:
numpy.random.Generator
Random number generator.
This class inherits from
np.random.Generator
and inherits all its sampling methods. Further, the class can be used as a context manager, which upon entry installs the RNG as pyMOR’s global RNG that is returned fromget_rng
. When the context is left, the previous global RNG is installed again.When using a context manager is not feasible, i.e. in an interactive workflow, this functionality can be accessed via the
install
andRNG:uninstall
methods.A new instance of this class should be obtained using
new_rng
.Parameters
- seed_seq
A
SeedSequence
to initialized the RNG with.
Methods
Installs the generator as pyMOR's global random generator.
Restores the previously set global random generator.
- pymor.tools.random.get_rng()[source]¶
Returns the current globally installed
random number generator
.
- pymor.tools.random.get_seed_seq()[source]¶
Returns
SeedSequence
of the current globalrandom number generator
.This function returns the
SeedSequence
with which pyMOR’s currently installed globalrandom number generator
has been initialized. The returned instance can be used to deterministically create a newSeedSequence
via thespawn
method, which then can be used to initialize a new random generator in external library code or concurrent code paths.
- pymor.tools.random.new_rng(seed_seq=42)[source]¶
Creates a new
random number generator
and returns it.Parameters
- seed_seq
Entropy to seed the generator with. Either a
SeedSequence
or anint
or list ofints
from which theSeedSequence
will be created. IfNone
, entropy is sampled from the operating system.
Returns
The newly created
random number generator
.
- pymor.tools.random.spawn_rng(f)[source]¶
Wraps a function or coroutine to create a new
random number generator
in concurrent code paths.Calling this function on a function or coroutine object creates a wrapper which will execute the wrapped function with a new globally installed
random number generator
. This ensures that random numbers in concurrent code paths (threads
,multiprocessing
,asyncio
) are deterministically generated yet uncorrelated.Warning
If the control flow within a single code path depends on communication events with concurrent code, e.g., the order in which some parallel jobs finish, deterministic behavior can no longer be guaranteed by just using
spawn_rng
. In such cases, the code additionally has to ensure that random numbers are sampled independently of the communication order.Parameters
- f
The function or coroutine to wrap.
Returns
The wrapped function or coroutine.