Restart random numbers with parallel loop

10 ビュー (過去 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 Center および File ExchangeParallel for-Loops (parfor) についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by