{"id":6393,"date":"2017-04-14T15:11:43","date_gmt":"2017-04-14T20:11:43","guid":{"rendered":"https:\/\/blogs.mathworks.com\/simulink\/?p=6393"},"modified":"2017-09-24T19:48:11","modified_gmt":"2017-09-25T00:48:11","slug":"simulating-models-in-parallel-made-easy-with-parsim","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2017\/04\/14\/simulating-models-in-parallel-made-easy-with-parsim\/","title":{"rendered":"Simulating models in parallel made easy with parsim"},"content":{"rendered":"<p>Some time ago, I wrote a series of posts to highlight the different factors to take into account when trying to run simulations in parallel. In R2017a, we are making it significantly easier with the introduction of a new function: <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/parsim.html\">parsim<\/a><\/p>\n<p>Let's see how that works!<\/p>\n<p><strong>Simulink.SimulationInput<\/strong><\/p>\n<p>If you are going to use the <a href=\"https:\/\/www.mathworks.com\/products\/parallel-computing.html\">Parallel Computing Toolbox<\/a> to simulate a model multiple times, there is obviously something you want to change to make each run different. This is done through the <a title=\"https:\/\/www.mathworks.com\/help\/releases\/R2017a\/simulink\/slref\/simulink.simulationinput-class.html (link no longer works)\">Simulink.SimulationInput<\/a> object.<\/p>\n<p>By creating one <a title=\"https:\/\/www.mathworks.com\/help\/releases\/R2017a\/simulink\/slref\/simulink.simulationinput-class.html (link no longer works)\">Simulink.SimulationInput<\/a> per simulation, you can define the properties specific to each run, including initial states, model parameters, block parameters, input signals, and variables used by the model.<\/p>\n<p>Let's take this simple bouncing ball model, and try to simulate it in parallel for different coefficient of restitution.<\/p>\n<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/bounce.png\n\" alt=\"Bouncing ball\" \/><\/p>\n<p>In this case, we will simulate the model for 10 different values, from 0.2 to 0.9. For that, I create an array of 10 Simulink.SimulationInput objects, and use the <a title=\"https:\/\/www.mathworks.com\/help\/releases\/R2017a\/simulink\/slref\/in.setblockparameter.html (link no longer works)\">setBlockParameter<\/a> method to specify the coefficient of restitution for each simulation. I can then simply pass this array of Simulink.SimulationInput to <tt>parsim<\/tt>, and I will receive as output an array of <a title=\"https:\/\/www.mathworks.com\/help\/releases\/R2017a\/simulink\/slref\/simulink.simulationoutput-class.html (link no longer works)\">Simulink.SimulationOutput<\/a> objects.<\/p>\n<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/simpleParsim.png\" alt=\"Parsim simple example\" \/><\/p>\n<p><strong>A More Realistic Example<\/strong><\/p>\n<p>Let's make this bouncing ball example more realistic by adding the following:<\/p>\n<p><strong>Workspace Variables:<\/strong> Before <tt>parsim<\/tt>, one of the challenges when simulating a model in parallel was to manage the variables needed by the model. I tried to provide tips and tricks to help with that in <a href=\"https:\/\/blogs.mathworks.com\/simulink\/2016\/05\/05\/tips-for-simulating-models-in-parallel\/\">this previous post<\/a>. For our bouncing ball example, instead of hard-coding the value of parameters like gravity and coefficient of restitution in block dialogs, let's have those be variables in the MATLAB base workspace, created by a MATLAB script.<\/p>\n<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/modelWithVars.png\" alt=\"Bouncing ball Model with workspace variables\" \/><\/p>\n<p><strong>Output Processing:<\/strong> In most cases, a simulation produces a large amount of data. If you are simulating on a remote cluster, you probably want to avoid transferring all this data. Instead, you can post-process the logged data and reduce it to what you are really interested in.<\/p>\n<p>For the post processing, we need to create a function that receives as input the simulation output object and returns a structure output. For example, I can use the logged position to computer how long it took for the ball to stop bouncing, and how many rebounds it did.<\/p>\n<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/postSimFcn.png\" alt=\"Post Simulation Function\" \/><\/p>\n<p>With that setup, we can create our array of Simulink.SimulationInput object, and use the <a title=\"https:\/\/www.mathworks.com\/help\/releases\/R2017a\/simulink\/slref\/in.setvariable.html (link no longer works)\">setVariable<\/a> method to specify different values for the workspace variable <tt>Cr<\/tt>. For the post-processing function, we specify a handle to it to the postSimFcn property of the simulation input object.<\/p>\n<p>Here is what it looks like:<\/p>\n<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/secondParsim.png\" alt=\"Parsim example\" \/><\/p>\n<p>Notice how I also use the <tt>UseFastRestart<\/tt> option to speed things up even more by compiling the model only once on each worker.<\/p>\n<p><strong>Handling Errors<\/strong><\/p>\n<p>One of the thing I like about <tt>parsim<\/tt> is how it behaves when the simulation errors out.<\/p>\n<p>In this case, the Simulink.SimulationOutput object contains all the logged data until the error happened, and a <tt>ErrorMessage<\/tt> field describing the cause of the error.<\/p>\n<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/outputError.png\" alt=\"Parsim error output\" \/><\/p>\n<p>This is very useful to understand what went wrong without the need to re-simulate the model.<\/p>\n<p>If you cannot figure out what went wrong based on the logged data, you will very likely want to add more instrumentation to the model and re-simulate it on your host machine. In that case, you will like the applyToModel method of the simulation input object. As its name implies,<br \/>\n this method will configure your current MATLAB session and model so that you can simulate it as it did on the worker.<\/p>\n<p><strong>Now it's your turn<\/strong><\/p>\n<p>Give a try at the new <tt>parsim<\/tt> function in R2017a and let us know what you think in the comments below.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2017Q2\/outputError.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>Some time ago, I wrote a series of posts to highlight the different factors to take into account when trying to run simulations in parallel. In R2017a, we are making it significantly easier with the... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2017\/04\/14\/simulating-models-in-parallel-made-easy-with-parsim\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[15,143,16],"tags":[493,494],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/6393"}],"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=6393"}],"version-history":[{"count":25,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/6393\/revisions"}],"predecessor-version":[{"id":6773,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/6393\/revisions\/6773"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=6393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=6393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=6393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}