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.GeneratorRandom number generator.
This class inherits from
numpy.random.Generatorand 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
installanduninstallmethods.A new instance of this class should be obtained using
new_rng.- Parameters:
seed_seq – A
SeedSequenceto 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
SeedSequenceof the current globalrandom number generator.This function returns the
SeedSequencewith which pyMOR’s currently installed globalrandom number generatorhas been initialized. The returned instance can be used to deterministically create a newSeedSequencevia thespawnmethod, 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 generatorand returns it.- Parameters:
seed_seq – Entropy to seed the generator with. Either a
SeedSequenceor anintor list ofintsfrom which theSeedSequencewill be created. IfNone, entropy is sampled from the operating system.- Returns:
The newly created |RNG|.
- pymor.tools.random.spawn_rng(f)[source]¶
Wraps a function or coroutine to create a new
random number generatorin 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.