Restart random numbers with parallel loop

조회 수: 2 (최근 30일)
Dominic Steinitz
Dominic Steinitz 2021년 2월 3일
댓글: Edric Ellis 2021년 2월 15일
I want to be able to restart my simulation from where I left off and also for it to be reproducible
if isfile("State.mat")
% If we previously saved the state, start from there
load("State");
globalStream.State = rngState;
...
else
% Otherwise start from scratch
rng(42,'twister');
globalStream = RandStream.getGlobalStream;
rngState = globalStream.State;
...
save("State", "current_time", "B", "rngState");
dlmwrite("data/tvol_sim_mat.csv", tvol_mat(1, :), 'precision', 15);
end
...
for t = 1:2
for i = 1:n
% Simulates the system forward
end
globalStream = RandStream.getGlobalStream;
rngState = globalStream.State;
save("State", "current_time", "B", "rngState");
end
But I want to replace for by parfor. I've read the docs and tried
if isfile("State.mat")
% If we previously saved the state, start from there
load("State");
s = RandStream('mlfg6331_64', 'Seed', parameters_for_inference.filter.seed);
options = statset('UseParallel', true, 'Streams', s, 'UseSubstreams', true);
s.State = rngState;
...
else
% Otherwise start from scratch
s = RandStream('mlfg6331_64', 'Seed', parameters_for_inference.filter.seed);
options = statset('UseParallel', true, 'Streams', s, 'UseSubstreams', true);
rngState = s.State;
save("State", "current_time", "B", "rngState");
end
...
for t = 1:2
parfor i = 1:n
% Simulates the system forward
end
rngState = s.State;
save("State", "current_time", "B", "rngState");
end
But I get this error when trying to restart
Error using matlab.internal.math.RandStream_getset_mex
State array class is invalid for a mlfg6331_64 generator.
Error in RandStream/subsasgn (line 646)
matlab.internal.math.RandStream_getset_mex('state',a.StreamID,b);
Error in emacsrunregion (line 23)
evalin('base',evalTxt);
Is it possible to do what I want in Matlab? Apologies if this is obvious but I am very new to Matlab. Many thanks :)

채택된 답변

Edric Ellis
Edric Ellis 2021년 2월 4일
The error that you're seeing there I think is because you've got an old version of your "State.mat" file - the error is the one that you receive when you try to set the State property of a 'mlfg6331_64' generator using the State extracted from a 'twister' generator. So maybe you simply need to delete or rename your old "State.mat" file.
Also, can I suggest you review this page which describes how to use Parallel Computing together with Statistics and Machine Learning Toolbox. Basically, if you're using statset with option 'UseParallel' -> true, then you do not need to write the parfor loop yourself to get parallel execution of the stats functions. (Although perhaps you're not calling stats functions inside your parfor loop?)
  댓글 수: 4
Dominic Steinitz
Dominic Steinitz 2021년 2월 15일
Thanks very much for this but I have e.g.
r_vec_pd = makedist('Normal', 'mu', 0.0, 'sigma', r_sigma);
...
random(r_vec_pd, 1, 1))
And there doesn't seem to be a way to say which stream to use for the call to random?
Also I think this means having to go through someone else's model and change the code. In Haskell, I would create as many generators as I need and then run each thread with its own generator with no changes to the model. I hope I have misunderstood :)
Edric Ellis
Edric Ellis 2021년 2월 15일
For methods that don't accept the RandStream as an input, you can set the "global" stream using RandStream.setGlobalStream. You'd want to wrap your code something like this (untested...)
oldStream = RandStream.getGlobalStream();
restoreStream = onCleanup(@() RandStream.setGlobalStream(oldStream));
RandStream.setGlobalStream(someStream);
% Now, "random" will use "someStream"; when "restoreStream" goes out of
% scope, MATLAB's global stream will be restored.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by