{"id":300,"date":"2021-04-01T14:28:40","date_gmt":"2021-04-01T12:28:40","guid":{"rendered":"https:\/\/logbooks.ifosim.org\/pykat\/?p=300"},"modified":"2021-04-01T14:33:41","modified_gmt":"2021-04-01T12:33:41","slug":"using-parakat-to-speed-up-2d-finesse-runs","status":"publish","type":"post","link":"https:\/\/logbooks.ifosim.org\/pykat\/blog\/using-parakat-to-speed-up-2d-finesse-runs\/","title":{"rendered":"Using parakat to speed up 2D Finesse runs"},"content":{"rendered":"\n<p>A more complex\/realistic example demonstrating how <code>parakat<\/code> can be used to speed up 2-dimentional simulations is provided <a href=\"https:\/\/logbooks.ifosim.org\/pykat\/wp-admin\/post.php?post=275&amp;action=edit#adfeg\">at the end of this post<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"adfeg\"> <\/h2>\n\n\n\n<p>The example Finesse code used in <a href=\"https:\/\/logbooks.ifosim.org\/pykat\/blog\/parallelising-finesse-2-pykat-three-ways\/\" data-type=\"post\" data-id=\"275\">Parallelising Finesse 2 + PyKat: three ways<\/a> is deliberately simple and quick so we can demonstrate some basic functionality. However it&#8217;s not a situation you&#8217;d realistically encounter, or one that would likely motivate you to try parallelising your code in the first place.<\/p>\n\n\n\n<p>In this example, the user wanted to model a 2-mirror cavity that has a slightly misaligned input mirror (therefore requiring the use of higher order modes). They are interested in understanding how the cavity resonant conditions change with this misalignment, so want to compare cavity scans (circulating power as a function of cavity tuning) as the value of the misalignment is varied. <\/p>\n\n\n\n<p>The base Finesse code, parsed directly to Pykat, is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>base = finesse.kat()\nbase.verbose=False\nbase.parse(\"\"\"\nl L0 1 0 n0\ns s0 0 n0 n1\nm m1 0.95 0.05 0 n1 n2\ns s1 100 n2 n3\nm m2 0.95 0.05 0 n3 n4\nattr m2 Rc 150\nattr m2 xbeta 1u\ncav c1 m1 n2 m2 n3\npd pow n2\nmaxtem 3\n\"\"\")<\/code><\/pre>\n\n\n\n<p><em>NB: as-written, this example uses <code>maxtem 3<\/code> and few (80) steps along each axis, so that it runs quite fast for demonstration purposes. it will quickly get a lot slower when these numbers are increased, as you would likely need to do for a more complete and accurate understanding of the result.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Standard, non-parallel method<\/h2>\n\n\n\n<p>Finesse can handle multiple x-axes commands. It does this in series by <strong>scanning the parameter of the <code>xaxis<\/code> for each <code>x2axis<\/code> value in sequence.<\/strong> The syntax is simply:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kat = base.deepcopy()\nkat.parse(\"\"\"\nxaxis m2 phi lin -90 90 80\nx2axis m1 xbeta lin 0 80u 80\n\"\"\")\nout = kat.run()<\/code><\/pre>\n\n\n\n<p> which will directly (eventually) produce a 2D output object <code>out[\"pow\"]<\/code>, along with a list of the input parameter choices in <code>out.x<\/code> and <code>out.y<\/code> <strong>[check!]<\/strong> for the <code>xaxis<\/code> and <code>x2axis<\/code> parameters respectively, that can be plotted however you like. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using parakat to speed things up<\/h2>\n\n\n\n<p>We can speed this up by instead just calculating the <code>xaxis<\/code> and splitting the <code>x2axis<\/code> into chunks that run in parallel on different engines. <\/p>\n\n\n\n<p>Using <code>ipcluster<\/code> via <code>subprocess<\/code> we first start 8 engines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>n_eng = 8 # max number of parallel tasks\n\nsubprocess.run(f\"ipcluster start -n {n_eng} --daemonize\",shell=True) \ntime.sleep(10) # wait a few sec for the cluster to start up<\/code><\/pre>\n\n\n\n<p>Then set up the equivalent of the <code>x2axis<\/code> command above, using a <code>for<\/code>-loop to create each <code>kat<\/code> object we&#8217;ll need and distribute these between the 8 engines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>xstart = 0\nxstop = 80e-6\nxpoints = 201\nxaxis = np.linspace(xstart,xstop, xpoints) #equivalent to x2axis above\nsp = np.array_split(xaxis,n_eng) #separate this into 8 smaller sections that run simultaneously\n\npk = parakat()\nfor T in np.arange(n_eng):\n    kat = base.deepcopy()\n    kat.parse(\"xaxis m2 phi lin -90 90 200\") #same as before\n    kat.parse(f\"x2axis m1 xbeta lin {sp&#091;T]&#091;0]}  {sp&#091;T]&#091;-1]} {len(sp&#091;T])-1}\") # sub-section of old x2axis\n    pk.run(kat)\nouts = pk.getResults() \n\n# Stopping the cluster\nsubprocess.run(f\"ipcluster stop\",shell=True)\ntime.sleep(3) #wait a sec for the cluster to shut down<\/code><\/pre>\n\n\n\n<p>This time, we have to manually merge our 8 pieces of output data back into one plot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def twod(b):\n    # reducing output data from 3D array (1,n,m) to 2D array (n,m)\n    #print(np.shape(b))\n    return np.reshape(b, (b.shape&#091;1], b.shape&#091;2]))\n\nx = outs&#091;0].x\ny = xaxis\ndata = twod(outs&#091;0].z)\nfor T in np.arange(1,n_eng):\n    #print(T)\n    data = np.vstack(&#091;data,twod(outs&#091;T].z)])<\/code><\/pre>\n\n\n\n<p>Now, as before, we can use the final 2D object called <code>data<\/code>, along with full input parameter lists <code>x<\/code> and <code>y<\/code>, to plot the data as we want. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fig, ax = plt.subplots(1,1, figsize=(12,6))\nax.imshow(data, norm=LogNorm(), aspect='equal')<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"864\" height=\"432\" src=\"https:\/\/logbooks.ifosim.org\/pykat\/wp-content\/uploads\/sites\/4\/2021\/04\/parakat_example.png\" alt=\"\" class=\"wp-image-443\" srcset=\"https:\/\/logbooks.ifosim.org\/pykat\/wp-content\/uploads\/sites\/4\/2021\/04\/parakat_example.png 864w, https:\/\/logbooks.ifosim.org\/pykat\/wp-content\/uploads\/sites\/4\/2021\/04\/parakat_example-300x150.png 300w, https:\/\/logbooks.ifosim.org\/pykat\/wp-content\/uploads\/sites\/4\/2021\/04\/parakat_example-768x384.png 768w\" sizes=\"auto, (max-width: 864px) 100vw, 864px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A more complex\/realistic example demonstrating how parakat can be used to speed up 2-dimentional simulations is provided at the end of this post. The example Finesse code used in Parallelising Finesse 2 + PyKat: three ways is deliberately simple and quick so we can demonstrate some basic functionality. However it&#8217;s not a situation you&#8217;d realistically [&hellip;]<\/p>\n","protected":false},"author":63,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ssl_alp_hide_revisions":false,"footnotes":"","ssl_alp_hide_crossreferences_to":false},"categories":[14],"tags":[94,89,93],"ssl-alp-coauthor":[70,7],"class_list":["post-300","post","type-post","status-publish","format-standard","hentry","category-finesse-2","tag-2d","tag-parallel","tag-pykat"],"_links":{"self":[{"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/posts\/300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/comments?post=300"}],"version-history":[{"count":7,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/posts\/300\/revisions"}],"predecessor-version":[{"id":445,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/posts\/300\/revisions\/445"}],"wp:attachment":[{"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/media?parent=300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/categories?post=300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/tags?post=300"},{"taxonomy":"ssl-alp-coauthor","embeddable":true,"href":"https:\/\/logbooks.ifosim.org\/pykat\/wp-json\/wp\/v2\/ssl-alp-coauthor?post=300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}