Control Random Number Streams on Workers
The random number generation functions rand
, randi
, and randn
behave differently for parallel calculations compared to your
MATLAB® client. You can change the behavior of random number generators on
parallel workers or on the client to generate reproducible streams of random numbers.
By default, the MATLAB client and MATLAB workers use different random number generators, even if the workers are part of a local cluster on the same machine as the client. The table below summarizes the default settings for the client and workers:
Generator | Seed | Normal Transform | |
---|---|---|---|
Client | 'Twister' or
'mt19937ar' | 0 | 'Ziggurat' |
Worker (local or remote) | 'Threefry' or
'Threefry4x64_20' | 0 | 'Inversion' |
For more information about the available generators and normal transforms, see Choosing a Random Number Generator.
Each worker in a cluster draws random numbers from an independent stream with the
properties in the table. By default, the random numbers generated on each worker in a
parfor
loop are different from each other and from the random
numbers generated on the client.
Note
If you have a GPU on your worker, different settings apply to random number streams on the GPU. For more information, see Random Number Streams on a GPU.
Client and Workers
If it is necessary to generate the same stream of numbers in the client and
workers, you can set one to match the other. You can set the generator algorithm and
seed using rng
.
For example, you might run a script as a batch job on a worker, and need the same
generator or sequence as the client. Suppose you start with a script file named
randScript1.m
that contains the line:
R = rand(1,4);
You can run this script in the client, and then as a batch job on a worker. Notice that the default generated random number sequences in the results are different.
randScript1; % In client
R
R = 0.8147 0.9058 0.1270 0.9134
parallel.defaultClusterProfile('Processes') c = parcluster(); j = batch(c,'randScript1'); % On worker wait(j);load(j); R
R = 0.1349 0.6744 0.9301 0.5332
For identical results, you can set the client and worker to use the same generator
and seed. Here, the file randScript2.m
contains the following
code:
rng(1,'Threefry');
R = rand(1,4);
Now, run the new script in the client and on a worker:
randScript2; % In client
R
R = 0.1404 0.8197 0.1073 0.4131
j = batch(c,'randScript2'); % On worker wait(j); load(j); R
R = 0.1404 0.8197 0.1073 0.4131
To reset the settings of the random number generator to their default values in
the client and on the worker, you can add this code to the end of
randScript2.m
.
rng('default')
Different Workers
By default, each worker in a cluster working on the same job has an independent
random number stream. If rand
, randi
, or
randn
are called in parallel, each worker produces a unique
sequence of random numbers.
Note
Because rng('shuffle')
seeds the random number
generator based on the current time, do not use this command to set the
random number stream on different workers if you want to ensure independent
streams. This is especially true when the command is sent to multiple
workers simultaneously, such as inside a parfor
,
spmd
, or a communicating job. For independent streams
on the workers, use the default behavior; or if that is not sufficient for
your needs, consider using a unique substream on each worker using RandStream
.
This example uses two workers in a parallel pool to show they generate unique random number sequences.
p = parpool(2); spmd R = rand(1,4); % Different on each worker end R{1},R{2}
ans = 0.1349 0.6744 0.9301 0.5332 ans = 0.6383 0.5195 0.1398 0.6509
delete(p)
If you need all workers to generate the same sequence of numbers, you can set each worker to use the same generator settings:
p = parpool(2); spmd rng(0,'Philox'); % Default seed 0. R = rand(1,4); % Same on all workers end R{1},R{2}
ans = 0.3655 0.6975 0.1789 0.4549 ans = 0.3655 0.6975 0.1789 0.4549
delete(p)
If you need to control the random numbers at each iteration of a
parfor
-loop, see Repeat Random Numbers in parfor-Loops.
Normally Distributed Random Numbers
If you are working with normally distributed random numbers using the
randn
function, you can use the same methods as above using
RandStream
to set the generator type,
seed, and normal transformation algorithm on each worker and the client.
For example, suppose the file randScript3.m
contains the
code:
stream = RandStream('Threefry','Seed',0,'NormalTransform','Inversion'); RandStream.setGlobalStream(stream); R = randn(1,7)
batch
or spmd
) to
produce the same sequence of random
numbers:R = -0.3479 0.1057 0.3969 0.6544 -1.8228 0.9587 0.5360