{"id":2188,"date":"2021-09-06T04:22:05","date_gmt":"2021-09-06T02:22:05","guid":{"rendered":"https:\/\/www.albertopassalacqua.com\/?p=2188"},"modified":"2021-09-07T19:07:25","modified_gmt":"2021-09-07T17:07:25","slug":"cfd-simulations-on-azure-batch-part-5","status":"publish","type":"post","link":"https:\/\/www.albertopassalacqua.com\/?p=2188","title":{"rendered":"CFD simulations on Azure Batch \u2013 Part 5"},"content":{"rendered":"\n<p style=\"text-align: justify;\">The last post of this series focused on setting up a pool of compute nodes on Azure Batch. In this part I show how to add jobs to a pool and then how to add tasks to a job. To summarize the nomenclature: a task is, in the context of CFD, a simulation, a job is a set of simulations.<\/p>\n<p style=\"text-align: justify;\">It is possible to configure jobs directly from the portal by selecting Jobs in the side bar, and clicking on the &#8220;+Add&#8221; button:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-2189\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1-1024x785.png\" alt=\"\" width=\"960\" height=\"736\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1-1024x785.png 1024w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1-300x230.png 300w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1-768x588.png 768w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs1.png 1035w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/p>\n<p>This will open the &#8220;Add job&#8221; screen:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2190\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs2.png\" alt=\"\" width=\"563\" height=\"526\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs2.png 563w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs2-300x280.png 300w\" sizes=\"auto, (max-width: 563px) 100vw, 563px\" \/><\/a><\/p>\n<p>where we have to select:<\/p>\n<ul>\n<li>The job id, following the rules indicated in the figure<\/li>\n<li>The pool (click and select the pool created in the previous part of this series of blog posts)<\/li>\n<\/ul>\n<p>The Advanced Settings concern options to manage the job:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2191\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs3.png\" alt=\"\" width=\"528\" height=\"401\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs3.png 528w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs3-300x228.png 300w\" sizes=\"auto, (max-width: 528px) 100vw, 528px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">They allow to specify:<\/p>\n<ul style=\"text-align: justify;\">\n<li>A display name, more descriptive than the job id.<\/li>\n<li>A maximum wall clock time, after which the job and all its tasks are terminated. This option is useful to control costs in case jobs may run for a long time (i.e. a simulation which unexpectedly reduce the time step to extremely small values and may last for significantly longer than estimated, increasing costs).<\/li>\n<li>The number of attempts Azure Batch should make to rerun the job.<\/li>\n<li>Priority and task dependencies.<\/li>\n<li>What to do when all tasks complete, choosing between two options:\n<ul>\n<li>No action (default)<\/li>\n<li>Terminate job<\/li>\n<\/ul>\n<\/li>\n<li>What to do when a task fails:\n<ul>\n<li>No action (default)<\/li>\n<li>Perform a specified action<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">For this guide, I only set to terminate the job when all tasks are completed. Wall time can be more effectively specified at the task level since it may be different for each task.<\/p>\n<p>The job manager, preparation and release tasks should be set to custom in our setup:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2192\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs4.png\" alt=\"\" width=\"533\" height=\"291\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs4.png 533w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs4-300x164.png 300w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><\/a><\/p>\n<p>Selecting this option will show the following screen:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2193\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs5.png\" alt=\"\" width=\"540\" height=\"658\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs5.png 540w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs5-246x300.png 246w\" sizes=\"auto, (max-width: 540px) 100vw, 540px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">where a set of instructions to prepare the job can be set up.&nbsp;<\/p>\n<p style=\"text-align: justify;\">In my setup, the job preparation task executes a bash script that installs OpenFOAM\u00ae on the compute nodes. In order to simplify the process, I created a bash script that I store in the file share, in a directory called <code>scripts<\/code>:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-2197\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8-1024x190.png\" alt=\"\" width=\"960\" height=\"178\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8-1024x190.png 1024w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8-300x56.png 300w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8-768x142.png 768w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs8.png 1037w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">The script to install the ESI version of OpenFOAM is called <code>installOpenFOAMCom.sh<\/code>, and its content is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">#!\/bin\/bash\n# Install OpenFOAM on nodes\n# Run as StartTask with Pool User Admin privileges\n\nwget -q -O - https:\/\/dl.openfoam.com\/add-debian-repo.sh | sudo bash\nsudo apt-get install -qq openfoam2106-default\nsource \/usr\/lib\/openfoam\/openfoam2106\/etc\/bashrc<\/code><\/pre>\n\n\n\n<p style=\"text-align: justify;\">while that for the Foundation release of OpenFOAM is called <code>installOpenFOAMOrg.sh<\/code> and contains the following instructions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">#!\/bin\/bash\n# Install OpenFOAM.org dev on nodes\n# Run as StartTask with Pool User Admin privileges\n\nsudo sh -c \"wget -O - http:\/\/dl.openfoam.org\/gpg.key | apt-key add -\"\nsudo add-apt-repository http:\/\/dl.openfoam.org\/ubuntu\nsudo add-apt-repository \"http:\/\/dl.openfoam.org\/ubuntu dev\"\nsudo apt-get update\nsudo apt-get -qq install openfoam-dev\nsource \/opt\/openfoam-dev\/etc\/bashrc<\/code><\/pre>\n\n\n\n<p>The command line to run the first script is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">\/bin\/bash -c '$AZ_BATCH_NODE_MOUNTS_DIR\/shareName\/scripts\/installOpenFOAMCom.sh'<\/code><\/pre>\n\n\n\n<p style=\"text-align: justify;\">which must invoke the shell since Azure Batch does not automatically execute commands in a shell. Also note the use of the environment variable<code> $AZ_BATCH_NODE_MOUNTS_DIR<\/code> which points to the mount directory where the file share is mounted. The name of the share <code>shareName<\/code> should be replaced with the actual name of the file share.<\/p>\n<p style=\"text-align: justify;\">The other options for the preparation task should be as in the figure. In particular:<\/p>\n<ul style=\"text-align: justify;\">\n<li>the job should wait for success of the preparation task before proceeding.<\/li>\n<li>the job must be executed as administrative user (it will install software) and on the pool (all nodes in the pool will need to run this task). The correct user identity is then: <code>Pool autouser, Admin<\/code>.<\/li>\n<li>If the node is rebooted, the preparation task must be repeated, or OpenFOAM won&#8217;t be available.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">The job configuration is complete, since we won&#8217;t configure a job manager task. Clicking on OK will create the job.<\/p>\n<p style=\"text-align: justify;\">The next step is adding a task, which is achieved by clicking on the job name, and in the job page, clicking on the &#8220;+Add&#8221; button. This will show the screen below:<\/p>\n<p><a href=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2195\" src=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs7.png\" alt=\"\" width=\"553\" height=\"824\" srcset=\"https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs7.png 553w, https:\/\/www.albertopassalacqua.com\/wp-content\/uploads\/2021\/09\/Jobs7-201x300.png 201w\" sizes=\"auto, (max-width: 553px) 100vw, 553px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><code>Task ID<\/code> and <code>Display name<\/code> follow the same rules we have already met in previous parts. The command line to execute the simulation, based on the preparation described in the first part of this blog series is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">\/bin\/bash -c \"cd $AZ_BATCH_NODE_MOUNTS_DIR\/shareName\/caseName\/ &amp;&amp; \/usr\/bin\/openfoam2106 .\/Allrun \"\n<\/code><\/pre>\n\n\n\n<p style=\"text-align: justify;\">Note that the <code>Allrun<\/code> script to execute OpenFOAM commands is executed using the OpenFOAM shell, so that OpenFOAM commands are available. This facilitates the setup of the environment without having to configure environment variables explicitly.<\/p>\n<p style=\"text-align: justify;\">Concerning the other options:<\/p>\n<ul style=\"text-align: justify;\">\n<li>The wall clock time should be set to a value sufficient to allow the simulation to complete.<\/li>\n<li>The User identity should be set to Pool autouser, Non-admin to execute the simulation without excessive privileges.<\/li>\n<li>Default values are used for the other options.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">The task setup is complete: clicking the Submit button will commit the task to Azure Batch. The system will start the task as soon as soon as a node is ready to accomodate it.<\/p>\n<p style=\"text-align: justify;\">One can add as many tasks as needed to a job, in order to complete a simulation campaign. However, if a wall time was specified for the job, it is worth remembering that only the tasks that will fit in that time will be completed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up jobs and tasks using C#<\/h2>\n\n\n\n<p>Setting up a job with the C# API for Azure Batch is straightforward:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">CloudJob job = _batchClient.JobOperations.CreateJob(\n    jobId: ...,\n    poolInformation: new PoolInformation { PoolId = ... });\n\njob.JobPreparationTask =\n    new JobPreparationTask\n    {\n        CommandLine = ...,\n        UserIdentity = new UserIdentity(\n            new AutoUserSpecification(\n                elevationLevel: ElevationLevel.Admin,\n                scope: AutoUserScope.Task)),\n        WaitForSuccess = true\n    };\n\nif (!string.IsNullOrEmpty(jobReleaseTaskCommand))\n{\n    job.JobReleaseTask\n        = new JobReleaseTask { CommandLine = ... };\n}\n\nawait job.CommitAsync();<\/code><\/pre>\n\n\n\n<p>where the &#8230; should be replaced by the corresponding strings.<\/p>\n<p>Adding tasks is done in the code as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">\/\/ Create a list of tasks \nprivate List&lt;CloudTask&gt; _taskList;\n\n\/\/ Create a task\nstring taskCommandLine = \"...\";\nCloudTask task = new CloudTask(taskId, taskCommandLine);\n\n\/\/ Add the task to the task list\n_taskList.Add(task);\n\n\/\/ Add the task to the job and commit it\nawait _batchClient.JobOperations.AddTaskAsync(jobId, _taskList);<\/code><\/pre>\n\n\n\n<p>where the <code>taskCommandLine<\/code> is the command to execute the task, as shown before.<\/p>\n<p style=\"text-align: justify;\">Now that the base concepts of how to use Azure Batch with OpenFOAM were shown, I recommend deepening your knowledge by reading the details in the official documentation for the service and the API, as well as exploring different storage options and setups.<\/p>\n<p>Enjoy \ud83d\ude42<\/p>\n\n\n\n<p><em>This offering is not approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM\u00ae and OpenCFD\u00ae trade marks. Alberto Passalacqua is neither associated to OpenCFD Ltd nor to Microsoft and did not receive funding from them to write this article. All registered trade marks belong to their legal owners.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The last post of this series focused on setting up a pool of compute nodes on Azure Batch. In this part I show how to add jobs to a pool and then how to add tasks to a job. To summarize the nomenclature: a task is, in the context of CFD, a simulation, a job is a set of simulations. It is possible to configure jobs directly from the portal by selecting Jobs in the side bar, and clicking on the &#8220;+Add&#8221; button: This will open the &#8220;Add job&#8221; screen: where we have to select: The job id, following the rules indicated in the figure The pool (click and select the pool created in the previous part of this series of blog posts) The Advanced Settings concern options to manage the job: They allow to specify: A display name, more descriptive than the job id. A maximum wall clock time, after which the job and all its tasks are terminated. This option is useful to control costs in case jobs may run for a long time (i.e. a simulation which unexpectedly reduce the time step to extremely small values and may last for significantly longer than estimated, increasing costs). The number of attempts Azure Batch should make to rerun the job. Priority and task dependencies. What to do when all tasks complete, choosing between two options: No action (default) Terminate job What to do when a task fails: No action (default) Perform a specified action For this guide, I only set to terminate the job when all tasks are completed. Wall time can be more effectively specified at the task level since it may be different for each task. The job manager, preparation and release tasks should be set to custom in our setup: Selecting this option will show the following screen: where a set of instructions to prepare the job can be set up.&nbsp; In my setup, the job preparation task executes a bash script that installs OpenFOAM\u00ae on the compute nodes. In order to simplify the process, I created a bash script that I store in the file share, in a directory called scripts: The script to install the ESI version of OpenFOAM is called installOpenFOAMCom.sh, and its content is: while that for the Foundation release of OpenFOAM is called installOpenFOAMOrg.sh and contains the following instructions: The command line to run the first script is: which must invoke the shell since Azure Batch does not automatically execute commands in a shell. Also note the use of the environment variable $AZ_BATCH_NODE_MOUNTS_DIR which points to the mount directory where the file share is mounted. The name of the share shareName should be replaced with the actual name of the file share. The other options for the preparation task should be as in the figure. In particular: the job should wait for success of the preparation task before proceeding. the job must be executed as administrative user (it will install software) and on the pool (all nodes in the pool will need to run this task). The correct user identity is then: Pool autouser, Admin. If the node is rebooted, the preparation task must be repeated, or OpenFOAM won&#8217;t be available. The job configuration is complete, since we won&#8217;t configure a job manager task. Clicking on OK will create the job. The next step is adding a task, which is achieved by clicking on the job name, and in the job page, clicking on the &#8220;+Add&#8221; button. This will show the screen below: Task ID and Display name follow the same rules we have already met in previous parts. The command line to execute the simulation, based on the preparation described in the first part of this blog series is: Note that the Allrun script to execute OpenFOAM commands is executed using the OpenFOAM shell, so that OpenFOAM commands are available. This facilitates the setup of the environment without having to configure environment variables explicitly. Concerning the other options: The wall clock time should be set to a value sufficient to allow the simulation to complete. The User identity should be set to Pool autouser, Non-admin to execute the simulation without excessive privileges. Default values are used for the other options. The task setup is complete: clicking the Submit button will commit the task to Azure Batch. The system will start the task as soon as soon as a node is ready to accomodate it. One can add as many tasks as needed to a job, in order to complete a simulation campaign. However, if a wall time was specified for the job, it is worth remembering that only the tasks that will fit in that time will be completed. Setting up jobs and tasks using C# Setting up a job with the C# API for Azure Batch is straightforward: where the &#8230; should be replaced by the corresponding strings. Adding tasks is done in the code as follows: where the taskCommandLine is the command to execute the task, as shown before. Now that the base concepts of how to use Azure Batch with OpenFOAM were shown, I recommend deepening your knowledge by reading the details in the official documentation for the service and the API, as well as exploring different storage options and setups. Enjoy \ud83d\ude42<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[139,117],"class_list":["post-2188","post","type-post","status-publish","format-standard","hentry","category-general","tag-cloud-computing","tag-openfoam"],"_links":{"self":[{"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/posts\/2188","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2188"}],"version-history":[{"count":8,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/posts\/2188\/revisions"}],"predecessor-version":[{"id":2226,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=\/wp\/v2\/posts\/2188\/revisions\/2226"}],"wp:attachment":[{"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2188"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2188"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.albertopassalacqua.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2188"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}