control random number generator in async programming

My problem is very simple. I am using asynchronous programing to generate random number dependent data.
I would like to have reproducible results, but I can't.
For example:
rng(1);
fA = parfeval(backgroundPool,@rand,1,10000);
B = rand(10000);
wait(fA)
C = max(fetchOutputs(fA),B);
B(1:5)
C(1:5)
If I repeat this code multiple times, only array B is reproducible. I want array C to be reproducible as well. Seems a different random number generator is used there. How can I control that generator?

Respuestas (1)

Walter Roberson
Walter Roberson el 29 de Nov. de 2024
parpool are defined to seed random number generators differently. See https://www.mathworks.com/help/parallel-computing/control-random-number-streams-on-workers.html

5 comentarios

André A
André A el 30 de Nov. de 2024
Movida: Walter Roberson el 30 de Nov. de 2024
I already did what explained there, but doesn't work:
rng(1, 'twister');
fA = parfeval(backgroundPool,@rand,1,10000);
B = rand(1,10000);
wait(fA)
C = max(fetchOutputs(fA),B);
B(1:5)
C(1:5)
I still get different results for C.
Calling rng('default') does not solve the problem.
backgroundPool = backgroundPool();
F = parfevalOnAll(backgroundPool, @() rng(1,'twister'), 0);
fetchOutputs(F);
fA = parfeval(backgroundPool,@rand,1,1,10000);
rng(1,'twister');
B = rand(1,10000);
wait(fA)
C = max(fetchOutputs(fA),B);
B(1:5)
ans = 1×5
0.4170 0.7203 0.0001 0.3023 0.1468
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
C(1:5)
ans = 1×5
0.4170 0.7203 0.0001 0.3023 0.1468
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
rng(1,'twister');
That sets the seed for the client process
fA = parfeval(backgroundPool,@rand,1,10000);
Note that command asks to run parfeval() on the backgroundpool, asking to run the function @rand, expecting 1 output, and passing parameter 10000 to rand. rand(10000) is the same as rand(10000,10000)
By default, each pool member is initialized with a different seed, ignoring the current seed for the client process. So you need to set the seed for the workers by using parfevalOnAll.
B = rand(1,10000);
That asks to run rand producing a 1 x 10000 output. not a 10000 x 10000 output.
So you were asking for diffferent sizes of output from rand.
I see. Then if I want to specify a different seed for each worker, how do I proceed? parfevalOnAll seems to only allow to specify the same seed for all workers.
NumWorkers = backgroundPool.NumWorkers;
random_seeds = [appropriate list];
F = parfevalOnAll(backgroundPool, @() getCurrentTask().ID, 1);
IDs = fetchOutputs(F);
D = dictonary(IDs, random_seeds);
F = parfevalOnAll(backgroundPool, @() rng(D(getCurrentTask.ID), 'twister'), 0);
fetchOutputs(F);
Now you can
fA = parfevalOnAll(backgroundPool,@rand,1,1,10000);
A = cell(NumWorkers,1);
for idx = 1 : NumWorkers
[~, A{idx}] = fetchNext(fA);
end

Iniciar sesión para comentar.

Categorías

Más información sobre Background Processing en Centro de ayuda y File Exchange.

Preguntada:

el 29 de Nov. de 2024

Comentada:

el 4 de Dic. de 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by