Is dynare compatible with parfor? That is, can one call dynare within a parfor loop?
Dynare itself features parallelization capabilities. But we have never tried to parallelize around Dynare. My hunch would be that it does not work due to the complexity of the underlying codes. But you might try. Any feedback on your experiences is highly appreciated.
I was able to do it. Within parfor, call a function of the iteration index that (i) cds into a distinct, index dependent directory and (ii) runs dynare. That way, dynare is run in the workspace of a function call and files are not rewritten.
Has anyone else been able to do this? The problem I am running into is that parfor does not work well with globals, and dynare uses globals. Alternatively, is there a way to run dynare without globals (M_, oo_) so that I can then figure out how to parallelize it?
Adam
Either you follow what Dr. En Ami suggested in doing separate calls to Dynare, which then separates the global variables by using different instances of Dynare.
The second alternative is using Dynare subfunctions directly. Many of them use local instances of the global variables.
I set up a parallelization around Dynare using parfor that seems to work. At this point, I can’t share the files but I can sketch how I did it. Feedback/suggestions welcome!
First, there is a script containing the parfor loop over array_of_scenarios (which differ in the sets of policy shocks) - with obvious notation:
addpath([MainFolder,'/folder_containing_pielin_simul'])
parfor s = 1:length(array_of_scenarios)
interm_simul_dir = [MainFolder,'/',char(array_of_scenarios(s))];
if ~exist(interm_simul_dir, 'dir')
mkdir(interm_simul_dir)
end
copyfile([MainFolder,'/files_model/model.mod'],interm_simul_dir)
cd(interm_simul_dir)
try
pielin_simul(array_of_scenarios{s},dynare_option1,dynare_option2,some_other_object);
catch ME
disp(['Error in iteration ', num2str(s), ': ', ME.message]);
end
end
rmpath([MainFolder,'/folder_containing_pielin_simul'])
delete(gcp)
Second, the function pielin_simul looks like this:
function pielin_simul(scenario,dynare_option1,dynare_option2,some_other_object)
options = { '-Doption1=dynare_option1', ['-Doption2="',char(dynare_option2),'"'], ['-Dscen="',scenario,'"']};
assignin('base','dynare_option2',dynare_option2);
assignin('base','some_other_object',some_other_object);
dynare('model',options{:});
end
where ‘dynare_option1’ and ‘dynare_option2’ are options for the preprocessor and ‘dynare_option2’ and ‘some_other_object’ could be any array or variable used in the mod-file: for example, the simulation horizon if it is not hard coded into the mod-file. Note that ‘dynare_option2’ is both used as an assignment to the preprocessor and then again directly in the mod-file.
Without the lines
assignin('base','dynare_option2',dynare_option2);
assignin('base','some_other_object',some_other_object);
Dynare, for some reason, deletes these objects from the worker’s workspace.
[EDIT: Actually, this is not required. Everything works fine with the original dynare.m file.] Finally - and this is where suggestions would be highly appreciated - the parfor loop messes with the dynareroot assignment in the dynare.m file. I had to replace the line
dynareroot = strrep(which('dynare'),'dynare.m','');
by
dynareroot = 'C:\dynare\6.1\matlab\';
I’m using version 6.1. It seems that parfor adds a temporary path per worker on top of path.m file, one of which is then assigned to dynareroot for some reason. My fix is an ugly work-around.