@contextmanager<EOL>def random_seed(seed=None):
try:<EOL><INDENT>next_seed = np.random.randint(<NUM_LIT:0>, np.iinfo(np.int32).max)<EOL>if seed is None:<EOL><INDENT>np.random.seed()<EOL>seed = np.random.randint(<NUM_LIT:0>, np.iinfo(np.int32).max)<EOL><DEDENT>logger = default_logger()<EOL>logger.debug('<STR_LIT>', seed)<EOL>np.random.seed(seed)<EOL>mx.random.seed(seed)<EOL>random.seed(seed)<EOL>yield<EOL><DEDENT>finally:<EOL><INDENT>np.random.seed(next_seed)<EOL>mx.random.seed(next_seed)<EOL>random.seed(next_seed)<EOL><DEDENT>
Runs a code block with a new seed for np, mx and python's random.

Parameters
----------

seed : the seed to pass to np.random, mx.random and python's random.

To impose rng determinism, invoke e.g. as in:

with random_seed(1234):
    ...

To impose rng non-determinism, invoke as in:

with random_seed():
    ...

Upon conclusion of the block, the rng's are returned to
a state that is a function of their pre-block state, so
any prior non-determinism is preserved.