{"id":5432,"date":"2016-05-05T10:40:05","date_gmt":"2016-05-05T15:40:05","guid":{"rendered":"https:\/\/blogs.mathworks.com\/simulink\/?p=5432"},"modified":"2017-12-21T17:01:25","modified_gmt":"2017-12-21T22:01:25","slug":"tips-for-simulating-models-in-parallel","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2016\/05\/05\/tips-for-simulating-models-in-parallel\/","title":{"rendered":"Tips for simulating models in parallel"},"content":{"rendered":"<p><strong><em>Update: In MATLAB R2017a the function <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/parsim.html\">PARSIM<\/a> got introduced. For a better experience simulating models in parallel, we recommend using PARSIM instead of SIM inside parfor. See the more recent blog post <a href=\"https:\/\/blogs.mathworks.com\/simulink\/2017\/04\/14\/simulating-models-in-parallel-made-easy-with-parsim\">Simulating models in parallel made easy with parsim<\/a> for more details.<\/em><\/strong><\/p>\r\n\r\n<p>---------------<\/p>\r\n\r\n<p>As I mentioned many times on this blog, running simulation in parallel using the <a href=\"https:\/\/www.mathworks.com\/products\/parallel-computing\/\">Parallel Computing Toolbox<\/a> can save you a lot of time. Today I want to share a few tips to help you getting started with running simulations in parallel.<\/p>\r\n\r\n<p><strong>Serial Parameter Sweep<\/strong><\/p>\r\n\r\n<p>Before going parallel, let's first look at the standard loop simulating a model. There are tons of ways to setup MATLAB and Simulink to do a parameter sweep. The most common simple setup I see is the following, where we do:<\/p>\r\n<ul>\r\n\t<li>Load the model using <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/load_system.html\">load_system<\/a><\/li>\r\n\t<li>Initialize the MATLAB base workspace using a script<\/li>\r\n\t<li>Define a vector of values over which you want to sweep<\/li>\r\n\t<li>Inside the loop, index into the parameter vector<\/li>\r\n\t<li>Simulate using <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/sim.html\">sim<\/a><\/li>\r\n<\/ul>\r\n\r\n<p>For this example, let's use a simple mass-spring-damper model simulation.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/testMdl.png\" alt=\"Model to be simulated\" \/><\/p>\r\n\r\n\r\n<p>We have an initialization script that initializes three variables.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/initScript.png\" alt=\"initialization script\" \/><\/p>\r\n\r\n<p>And we do the parameter sweep using this code.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/runSerial.png\" alt=\"Serial run\" \/><\/p>\r\n\r\n<p><strong>Simulink and Transparency<\/strong><\/p>\r\n\r\n<p>When simulating models inside <a href=\"https:\/\/www.mathworks.com\/help\/distcomp\/parfor.html\">parfor<\/a>, there are a few intricacies about how parfor manages variables that need to be taken into account. To begin on that topic, I recommend going through the documentation pages about <a title=\"https:\/\/www.mathworks.com\/help\/distcomp\/classification-of-variables-in-parfor-loops.html (link no longer works)\">Classification of Variables in parfor-Loops<\/a>, and <a href=\"https:\/\/www.mathworks.com\/help\/distcomp\/transparency.html\">Transparency<\/a>.<\/p>\r\n\r\n<p>Let me resume in a few bullets the important lessons you will learn in those documentation pages:<\/p>\r\n\r\n<ul>\r\n\t<li>Parallel workers are independent MATLAB sessions to which parfor sends code and data to process.<\/li>\r\n\t<li>For efficiency, parfor classifies variables in many categories and sends only the ones it sees as needed<\/li>\r\n\t<li>The code sent to the workers is not executed in their base workspace, but in a special function workspace<\/li>\r\n\t<li>Variables needed by a Simulink model are not \"visible\" to parfor, and consequently not sent automatically to the workers<\/li>\r\n\t<li>By default, Simulink looks in the base workspace for the variables it needs<\/li>\r\n<\/ul>\r\n\r\n<p>Because of those facts, making simulink run inside parfor requires a few tricks. Let's see two techniques to simulate model inside parfor.<\/p>\r\n\r\n<p><strong>Parameter Sweep in the Base Workspace<\/strong><\/p>\r\n\r\n<p>In this first technique, we counteract the fact that Simulink is not transparent by violating transparency using <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/evalin.html\">evalin<\/a> and\/or <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/assignin.html\">assignin<\/a>. Yes... I like to live dangerously!<\/p>\r\n\r\n<p>To be as efficient as possible, we first use an <a href=\"https:\/\/www.mathworks.com\/help\/distcomp\/spmd.html\">spmd<\/a> statement to put in the worker's base workspace the data needed by the model that remains constant during the parameter sweep. Then inside the parfor loop, we put in the base workspace the data that changes every iteration, and call <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/sim.html\">sim<\/a>.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/parallelRun.png\" alt=\"Parallel sweep in base workspace\" \/><\/p>\r\n\r\n<p><strong>Parameter Sweep in a Function Workspace<\/strong><\/p>\r\n\r\n<p>In this second technique, we do the opposite. We hide the fact that Simulink is not transparent by doing everything inside a function workspace.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/parallelRunFcn.png\" alt=\"Parallel sweep in function workspace\" \/><\/p>\r\n\r\n<p>Where the function calling sim sets the SrcWorkspace parameter to point to the current workspace:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2016Q2\/runSim.png\" alt=\"Calling sim\" \/><\/p>\r\n\r\n<p><strong>Note about the future<\/strong><\/p>\r\n\r\n<p>Be reassured that we are actively working on features to make simulating models inside parfor easier in the future. However, since we are unfortunately forced to live in the present, I thought sharing some of those intricacies might help a few of you setting up their environment to simulate models in parallel.<\/p>\r\n\r\n<p><strong>Now it's your turn<\/strong><\/p>\r\n\r\n<p>Try setting up your models to simulate in parallel and let us know how that goes by leaving a <a href=\"https:\/\/blogs.mathworks.com\/simulink\/?p=5432&#comment\">comment here<\/a>.<\/p>\r\n\r\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/simulink\/files\/parallelRun.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Update: In MATLAB R2017a the function PARSIM got introduced. For a better experience simulating models in parallel, we recommend using PARSIM instead of SIM inside parfor. See the more recent blog... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2016\/05\/05\/tips-for-simulating-models-in-parallel\/\">read more >><\/a><\/p>","protected":false},"author":41,"featured_media":5477,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[69,143,33],"tags":[84,161],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/5432"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=5432"}],"version-history":[{"count":21,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/5432\/revisions"}],"predecessor-version":[{"id":6966,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/5432\/revisions\/6966"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media\/5477"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=5432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=5432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=5432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}