How can I optimize parallel simulations of a SimBiology model?

4 次查看(过去 30 天)
In March of 2020, there was a question about parfor loops and simbiology. (https://www.mathworks.com/matlabcentral/answers/510565-issues-with-doses-variants-in-parfor-loop-in-simbiology?s_tid=srchtitle)
I currently use a parfor loop, but my model is fairly large and uses a lot of molecules -- around 40 species and 40 reactions. As a result, it takes a very long time to obtain my results. I was wondering if you think SimFunction (along with 'UseParallel' and 'AutoAccelerate') would be appropriate for me to use. -- Below, you'll find that I use a parfor appoach and make sure the files are accessible through the latter two functions. After seeing the aforementioned post, I'm wondering if I should be using SimFunction, sbiosimulate, sbioaccelerate, sbioensemblerun, or another method to optimize my approach.
Here is the general structure for what I am trying to accomplish:
I am using SimBiology 2019b. The solver I need to use is SSA, monte carlo style. I have a chemical reaction network set up. I add an event at 3000 seconds to set the concentration of an 'input' species to a given value.
I have a species in the chemical reaction network that I view as the 'output' species. My goal is to run 100 simulations for each given input amount. Then, I would like to increase the input amount over 100 steps in a uniformly increasing manner at each step and observe the behavior of the 'output' species.
Here is the structure of my code:
for i = 1:100 %100 steps with uniform increasing 'input' species amounts
sbioloadproject('model.sbproj');
cs = getconfigset(m1, 'default');
cs.SolverType = 'ssa';
solver = cs.SolverOptions;
solver.LogDecimation = 1000;
inputSpecies = sbioselect(m1,'Type','species','Name','inputSpecies'); %The 'input' species
inputSpecies.InitialAmount = 0;
parameterTimeunits = addparameter(m1,'Timeunits',1.0,'ValueUnits','minute','ConstantValue',true);
parameterMolunits = addparameter(m1,'Molunits',1.0,'ValueUnits','molecule','ConstantValue',true);
inputSpecies = addevent(m1, '(time/Timeunits) >= 3000', ['inputSpecies = (1500000*' num2str(i) ')*Molunits']);
sbiosaveproject modelParallel.sbproj m1 inputSpecies
clear m1;
%simulate the model
parfor j=1:100 %Number of simulation runs per input step
[m1,inputSpecies] = loadSimBiologyModel('modelParallel.sbproj');
[t,x,names] = sbiosimulate(m1);
parsave(['StochasticTest_Input' num2str(i) '_Instance' num2str(j)], inputSpecies, t, x, names);
end
end
function [m2,inputSpecies2] = loadSimBiologyModel(filename)
sbioloadproject(filename);
m2 = m1;
inputSpecies2 = inputSpecies;
end
function parsave(fname,inputSpecies,t,x, names)
save(fname,'inputSpecies','t','x','names');
end
%I'll then take all these datafiles, interpolate them, and combine it into one dateset.
%Then I'll observe the amount of output over time for the varying range of input.
With my current approach, I haven't become very familiar with parameters or doses. Would you be able to provide me some insights on A.) if SimFunciton (along with 'UseParallel' and 'AutoAccelerate') is appropriate and if so, B.) since the parameters and doses don't seem applicable to my setup, how can I adapt the function inputs appropriately? Any tips, suggestions, or critiques are happily welcomed. If you need any more info, please let me know.
  3 个评论
Fulden Buyukozturk
Fulden Buyukozturk 2020-9-15
Hi Colton,
Yes, using SimFunction would be better as it offers easy and efficient parallelization and avoids repeated compilation of the model. Also, instead of saving 100 variations of the model, you can update the event to set inputSpecies to some new parameter value that is an input to the SimFunction. For example, your event could look like:
addevent(m1,'(time/Timeunits) >= 3000', 'inputSpecies = newParam');
you could create simfunction as:
F = createSimFunction(m1,{'newParam'}, {'output'}, 'UseParallel', true);
and you could then run the simfunction as:
simdata = F(phi, t_stop)
Where phi is an array of input amount values.
If you could avoid using events as you mentioned, then you can also look into using exlptau or impltau instead of ssa to speed up simulations. These are faster than SSA but introduce approximations which you can read about here: https://www.mathworks.com/help/simbio/ug/stochastic-solvers.html
Additional things to consider:
  • Since you’re only interested in one output, it would be most efficient to only log this one output species when creating the SimFunction. This is the observables input to createSimFunction.
  • Lastly, SSA is probably reporting more simulation output times than you may be interested in. This could also slow things down due to the extra memory usage. So you may want to investigate reducing the number of times using OutputTimes (can be an input to SimFunction) or LogDecimation.
Fulden
Fulden Buyukozturk
Fulden Buyukozturk 2020-9-15
I should have also pointed out that if you could go around using events and just change the initial conditions to steady state values instead, this should make the simulations a lot faster.
One way to change the initial conditions to steadystate conditions would be to run sbiosteadystate and commit the steady state variant to the model. Note that this would require temporarily changing to a deterministic solver.
PS. I will also copy and paste my initial comment above to the answer field.

请先登录,再进行评论。

采纳的回答

Fulden Buyukozturk
Fulden Buyukozturk 2020-9-15
Hi Colton,
Yes, using SimFunction would be better as it offers easy and efficient parallelization and avoids repeated compilation of the model. Also, instead of saving 100 variations of the model, you can update the event to set inputSpecies to some new parameter value that is an input to the SimFunction. For example, your event could look like:
addevent(m1,'(time/Timeunits) >= 3000', 'inputSpecies = newParam');
you could create simfunction as:
F = createSimFunction(m1,{'newParam'}, {'output'}, 'UseParallel', true);
and you could then run the simfunction as:
simdata = F(phi, t_stop)
where phi is an array of input amount values.
If you could avoid using events as you mentioned and just change the initial conditions to steady state values instead, this should make the simulations a lot faster. Once you eliminate events, you can also look into using exlptau or impltau instead of ssa to speed up simulations. These are faster than SSA but introduce approximations which you can read about here: https://www.mathworks.com/help/simbio/ug/stochastic-solvers.html
Additional things to consider:
  • Since you’re only interested in one output, it would be most efficient to only log this one output species when creating the SimFunction. This is the observables input to createSimFunction.
  • Lastly, SSA is probably reporting more simulation output times than you may be interested in. This could also slow things down due to the extra memory usage. So you may want to investigate reducing the number of times using OutputTimes (can be an input to SimFunction) or LogDecimation.
Fulden
  3 个评论
Arthur Goldsipe
Arthur Goldsipe 2020-9-15
I can chime in to answer your followup question. Yes, it should be efficient to duplicate your parameter values to get ensemble results.
Glad to hear that you're seeing a significant speedup already. I would say that next biggest improvement would come from eliminating the event and switching and changing your initial conditions to steady state values. Switching the solver type to one of the tau leap solvers would be the next thing I'd suggest trying. This will also reduce the number of logged points, which would means it might not make that big of a difference to use LogDecimation. Also, I shouldn't have told Fulden to suggest using OutputTimes. I forgot that OutputTimes is only available for deterministic solvers.
-Arthur

请先登录,再进行评论。

更多回答(0 个)

社区

更多回答在  SimBiology Community

类别

Help CenterFile Exchange 中查找有关 Scan Parameter Ranges 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by