{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","results":{"codes":[]},"settings":"","params":[]},"next":{"description":"","pages":[]},"title":"About parallelizing tool executions","type":"basic","slug":"about-parallelizing-tool-executions","excerpt":"","body":"To achieve the parallelization of several executions of the same tool, the CGC implements a Common Workflow Language (CWL) feature called *scattering*.\n\nScattering is a mechanism that applies to a particular tool and one of its input ports. If a tool is passed a list of inputs on one port and that port is marked as \"scattered\", then one job will be created for each input in the list.\n\nThe scheduling algorithm will have these jobs be run in parallel, as far a the available compute resources allow it. If all jobs cannot be executed in parallel, they will be queued for execution as soon as more resources become available.\n\nScattering on a critical tool in your workflow may shorten the workflow's run time significantly. For an example of how this can be achieved, see this [blog post](blog:making-efficient-use-of-compute-resources#section-when-being-scattered-is-a-very-good-thing-optimising-a-whole-genome-analysis) explaining how a whole genome analysis workflow uses scattering.\n\nNote that scattering is different from [performing batch analyses](doc:about-batch-analyses). Batching launches multiple tasks, whereas scattering happens within a single task.\n\n### Scatter by single input port\n\nThis method performs the same in CWL sbg:draft-2 and v1.x versions.\n\nTo understand how scattering on a single input port works, please look at the explanation and the accompanying diagram below:\n\n* We have an input array with two elements, **A1** and **A2**, which can be two files, that we want to provide to an app through a single input port. We want the app to process both input values at the same time and produce an output for each of the values. Note that an input element within an input array can be any available value type, such as File, Directory, string, nested array, etc. A job is created for each element in the input array, regardless of the type of the element.\n* The input values are provided on an input port that has _scattering enabled_. Scattering means that the individual input values, **A1** and **A2**, will be processed in parallel if there are enough computation resources to support the workload.\n* Separate jobs (working instances of the app that does the processing) are generated and executed to process **A1** and **A2** in parallel.\n* Outputs resulting from both processing jobs are sent to a single output port.\n* The output port produces an array containing output values **B1** and **B2**, resulting from inputs **A1** and **A2** respectively. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/2a8217e-scatter_single_port.drawio.png\",\n        \"scatter_single_port.drawio.png\",\n        521,\n        324,\n        \"#edf0f0\"\n      ]\n    }\n  ]\n}\n[/block]\n\n### Scatter by multiple input ports\n\nThere are several methods for scattering by multiple input ports. Each of the methods is explained in more detail in the sections below.\n\n#### Dot Product\n\nThis method takes one value from each input port and uses them to create a job. There will be as many jobs as there are values provided to one input port. _Therefore, the method works properly only if the number of provided input values on each input port is the same_. If that is not the case, an error is thrown.\n\nTo understand how the **dot product** method works, please look at the explanation and the accompanying diagram below:\n\n* We have two input ports and the values provided to those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B. There are two values provided on each input port, which meets the requirement of having to provide an equal number of values on all scattered input ports if using the **dot product** method.\n* Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B.\n* Separate jobs (working instances of the app that does the processing) are generated by taking the first values from each input (**A1** and **B1**) to create one job, and the second ones (**A2** and **B2**) to create the second job. These are executed in parallel.\n* Outputs resulting from both processing jobs are sent to a single output port.\n* The output port produces an output array containing output values **C11** and **C22**, the first one resulting from inputs **A1** and **B1**, and the second one resulting from inputs **A2** and **B2**, respectively.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/2ced244-scatter_dot_product.drawio.png\",\n        \"scatter_dot_product.drawio.png\",\n        521,\n        324,\n        \"#ebeeee\"\n      ]\n    }\n  ]\n}\n[/block]\nThis is what the dot product scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"scatter: [A, B]\\nscatterMethod: \\\"dotproduct\\\"\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n#### Nested Cross Product\n\nThis method specifies the Cartesian product of the inputs, producing a job for every combination of input values provided on scattered input ports. The output must be a nested array for each level of scattering in the order in which the input arrays are listed in the scatter field.\n\nTo understand how the **nested cross product** method works, please look at the explanation and the accompanying diagram below:\n\n* We have two input ports and the values provided to those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B.\n* Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B.\n* Separate jobs (working instances of the app that does the processing) are generated by combining each input value from port A with each input value from port B (**A1** and **B1**, **A1** and **B2**, **A2** and **B1**, **A2** and **B2**), which gives us a total of 4 jobs when we have two input ports with two input values provided on each port. The jobs are executed in parallel.\n* Outputs resulting from both processing jobs are sent to a single output port.\n* The output port produces an output array containing one output value per job, in this case value **C11** resulting from inputs **A1** and **B1**, **C12** resulting from inputs **A1** and **B2**, **C21** resulting from inputs **A2** and **B1**, and **C22** resulting from inputs **A2** and **B2**. The important thing to note is that _outputs are grouped (nested) for each level of scattering in the order in which the input arrays are listed in the scatter field_. For example, if the first field that is selected for scattering is field A, the first group of outputs will be **C11** and **C12**, which are results of processing input value **A1** with input values **B1** and **B2** respectively. The second group of outputs will be **C21** and **C22**, which are results of processing input value **A2** with input values **B1** and **B2** respectively. Represented in array format, this would be the final output [[C11, C12], [C21, C22]].\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/10fea86-scatter_nested_crossproduct.drawio.png\",\n        \"scatter_nested_crossproduct.drawio.png\",\n        553,\n        492,\n        \"#ebefef\"\n      ]\n    }\n  ]\n}\n[/block]\nThis is what the **nested cross product** scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports and the first port in the scattering order being input port **A**:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"scatter: [A, B]\\nscatterMethod: \\\"nested_crossproduct\\\"\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n#### Flat Cross Product\n\nThis method specifies the Cartesian product of the inputs, producing a job for every combination of input values provided on scattered input ports. The jobs are created and outputs are produced in the order in which the input ports are selected for scattering. \n\nTo understand how the **flat cross product** method works, please look at the explanation and the accompanying diagram below:\n\n* There are two input ports and the values provided on those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B.\n* Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B.\n* Separate jobs (working instances of the app that does the processing) are generated by combining each input value from port A with each input value from port B (**A1** and **B1**, **A1** and **B2**, **A2** and **B1**, **A2** and **B2**), which gives us a total of 4 jobs when we have two input ports with two input values provided on each port. The jobs are executed in parallel.\n* Outputs resulting from both processing jobs are sent to a single output port.\n* The output port produces an array containing one output value per job, in this case value **C11** resulting from input values **A1** and **B1**, **C12** resulting from input values **A1** and **B2**, **C21** resulting from input values **A2** and **B1**, and **C22** resulting from input values **A2** and **B2**. Note that outputs are presented in the order in which the input ports are selected for scattering. For example, if the first field that is selected for scattering is field A, the first outputs will be **C11** and **C12**, which are results of processing input value **A1** with input values **B1** and **B2** respectively. The following outputs will be **C21** and **C22**, which are results of processing input value **A2** with input values **B1** and **B2** respectively. Unlike the **nested cross product** method where the output values are grouped, the **flat cross product** method outputs a completely _flat_ structure with no nesting (grouping) of output values. Represented as an array, this would be the final output [C11, C12, C21, C22].\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/30186e2-scatter_flat_crossproduct.drawio.png\",\n        \"scatter_flat_crossproduct.drawio.png\",\n        531,\n        493,\n        \"#ebefef\"\n      ]\n    }\n  ]\n}\n[/block]\nThis is what the **flat cross product** scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports and the first port in the scattering order being input port **A**:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"scatter: [A, B]\\nscatterMethod: \\\"flat_crossproduct\\\"\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n### Configuring scattering in the Workflow Editor\n\nTo configure scattering for an input port in a workflow step, first open the step configuration as follows:\n1. Navigate to a project.\n2. Click the **Apps** tab.\n3. Click the name of the workflow you want to edit.\n4. In the top-right corner click **Edit**. Workflow Editor opens.\n5. Double-click the node in the workflow whose input(s) you want to scatter. Object inspector opens.\n6. In the Object Inspector, click the **Step** tab. From this point on, follow the instructions below depending on the CWL version of your workflow.\n\nTo set scattering in CWL v1.x workflows:\n1. Under **Scatter**, select the input port(s) you want to scatter by. Hold `Cmd` (`Ctrl`) or `Shift` to select multiple ports.\n2. If you have selected _more than one port_ in the previous step, under **Scatter Method**, select the [method](#scatter-by-multiple-input-ports) that best matches the way you want the input values to be paired and processed.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/c7b058e-set-scatter-multiple-ports.png\",\n        \"set-scatter-multiple-ports.png\",\n        322,\n        669,\n        \"#f5f4f3\"\n      ]\n    }\n  ]\n}\n[/block]\n\n3. Click the save icon <i class=\"fa fa-floppy-o\" aria-hidden=\"true\"></i> to save the changes. You have now enabled scattering for the selected input ports.\n\nTo set scattering for workflow steps in `sbg:draft-2` workflows (this CWL version allows scattering only by one input port):\n1. Under **Scatter**, select the input port you want to scatter by.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/173980d-set-scatter-single-port.png\",\n        \"set-scatter-single-port.png\",\n        1222,\n        671,\n        \"#f6f7f6\"\n      ]\n    }\n  ]\n}\n[/block]\n\n2. Click the save icon <i class=\"fa fa-floppy-o\" aria-hidden=\"true\"></i> to save the changes. You have now enabled scattering for the input port.\n\n\n##Keeping scattering under control\n\nThe power of scattering to reduce analysis time lies in making full use of the available compute resources. You can control the resources available for the execution of an app by specifying instance type and the number of instances to be used in parallel. \n\nWhile scattering is a powerful tool to shorten your analysis run time, it may well increase the overall cost of your analysis if used in combination with certain other settings.\n\nThere are two ways in which you can fine-tune how the scattering works on a tool:\n  * Configuring computational instances on the tool.\n  * Setting the maximum number of parallel instances;\n\n\n###Controlling via instance type\n\nBased on the scattered [tool's resource requirements](doc:about-tool-resource-requirements), you may want to pick an instance that leaves the least CPU and memory to waste for a given number of scattered jobs and maximum number of parallel instances. [This blog post](blog:making-efficient-use-of-compute-resources#section-choosing-the-best-compute-instance-for-your-analysis) explains how to choose an instance suitable for your analysis.\n\nTo set the instance type, set the [`sbg:AWSInstanceType`](doc:list-of-execution-hints) or [`sbg:GoogleInstanceType`](doc:list-of-execution-hints) hint at [workflow level](doc:set-execution-hints-at-workflow-level).\n\n###Controlling via maximum number of parallel instances\n\nIf you anticipate that the execution of the tool which you are scattering is time-critical for the entire workflow, you can configure the maximum number of instances that the Scheduling Algorithm is allowed to have running at any one time.\n\nIf the jobs that would be started as a result of scattering cannot fit onto the provisioned instances according to their tool's resource requirements, those jobs will be queued for execution. As soon as enough resources become available following the completion of other jobs, queued jobs will be executed. This ensures there will be less idle time across the entire task. \n\nThe CGC bioinformaticians exploit this technique when tuning workflows in Public Apps\n\nTo set the maximum number of instances, set the [`sbg:maxNumberOfParallelInstances`](doc:list-of-execution-hints) hint at [workflow level](doc:set-execution-hints-at-workflow-level).","updates":[],"order":2,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"586d3d68d7f6a12f00c62444","user":"575e85ac41c8ba0e00259a44","version":{"version":"1.0","version_clean":"1.0.0","codename":"","is_stable":true,"is_beta":true,"is_hidden":false,"is_deprecated":false,"categories":["55faf11ca62ba1170021a9ab","55faf8f4d0e22017005b8272","55faf91aa62ba1170021a9b5","55faf929a8a7770d00c2c0bd","55faf932a8a7770d00c2c0bf","55faf94b17b9d00d00969f47","55faf958d0e22017005b8274","55faf95fa8a7770d00c2c0c0","55faf96917b9d00d00969f48","55faf970a8a7770d00c2c0c1","55faf98c825d5f19001fa3a6","55faf99aa62ba1170021a9b8","55faf99fa62ba1170021a9b9","55faf9aa17b9d00d00969f49","55faf9b6a8a7770d00c2c0c3","55faf9bda62ba1170021a9ba","5604570090ee490d00440551","5637e8b2fbe1c50d008cb078","5649bb624fa1460d00780add","5671974d1b6b730d008b4823","5671979d60c8e70d006c9760","568e8eef70ca1f0d0035808e","56d0a2081ecc471500f1795e","56d4a0adde40c70b00823ea3","56d96b03dd90610b00270849","56fbb83d8f21c817002af880","573c811bee2b3b2200422be1","576bc92afb62dd20001cda85","5771811e27a5c20e00030dcd","5785191af3a10c0e009b75b0","57bdf84d5d48411900cd8dc0","57ff5c5dc135231700aed806","5804caf792398f0f00e77521","58458b4fba4f1c0f009692bb","586d3c287c6b5b2300c05055","58ef66d88646742f009a0216","58f5d52d7891630f00fe4e77","59a555bccdbd85001bfb1442","5a2a81f688574d001e9934f5","5b080c8d7833b20003ddbb6f","5c222bed4bc358002f21459a","5c22412594a2a5005cc9e919","5c41ae1c33592700190a291e","5c8a525e2ba7b2003f9b153c","5cbf14d58c79c700ef2b502e","5db6f03a6e187c006f667fa4","5f894c7d3b0894006477ca01","6176d5bf8f59c6001038c2f7"],"_id":"55faf11ba62ba1170021a9aa","releaseDate":"2015-09-17T16:58:03.490Z","createdAt":"2015-09-17T16:58:03.490Z","project":"55faf11ba62ba1170021a9a7","__v":48},"category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"TASK EXECUTION","slug":"task-execution","order":23,"from_sync":false,"reference":false,"_id":"586d3c287c6b5b2300c05055","version":"55faf11ba62ba1170021a9aa","__v":0,"project":"55faf11ba62ba1170021a9a7","createdAt":"2017-01-04T18:17:12.683Z"},"parentDoc":null,"createdAt":"2017-01-04T18:22:32.979Z","githubsync":"","project":"55faf11ba62ba1170021a9a7","__v":0}

About parallelizing tool executions


To achieve the parallelization of several executions of the same tool, the CGC implements a Common Workflow Language (CWL) feature called *scattering*. Scattering is a mechanism that applies to a particular tool and one of its input ports. If a tool is passed a list of inputs on one port and that port is marked as "scattered", then one job will be created for each input in the list. The scheduling algorithm will have these jobs be run in parallel, as far a the available compute resources allow it. If all jobs cannot be executed in parallel, they will be queued for execution as soon as more resources become available. Scattering on a critical tool in your workflow may shorten the workflow's run time significantly. For an example of how this can be achieved, see this [blog post](blog:making-efficient-use-of-compute-resources#section-when-being-scattered-is-a-very-good-thing-optimising-a-whole-genome-analysis) explaining how a whole genome analysis workflow uses scattering. Note that scattering is different from [performing batch analyses](doc:about-batch-analyses). Batching launches multiple tasks, whereas scattering happens within a single task. ### Scatter by single input port This method performs the same in CWL sbg:draft-2 and v1.x versions. To understand how scattering on a single input port works, please look at the explanation and the accompanying diagram below: * We have an input array with two elements, **A1** and **A2**, which can be two files, that we want to provide to an app through a single input port. We want the app to process both input values at the same time and produce an output for each of the values. Note that an input element within an input array can be any available value type, such as File, Directory, string, nested array, etc. A job is created for each element in the input array, regardless of the type of the element. * The input values are provided on an input port that has _scattering enabled_. Scattering means that the individual input values, **A1** and **A2**, will be processed in parallel if there are enough computation resources to support the workload. * Separate jobs (working instances of the app that does the processing) are generated and executed to process **A1** and **A2** in parallel. * Outputs resulting from both processing jobs are sent to a single output port. * The output port produces an array containing output values **B1** and **B2**, resulting from inputs **A1** and **A2** respectively.  [block:image] { "images": [ { "image": [ "https://files.readme.io/2a8217e-scatter_single_port.drawio.png", "scatter_single_port.drawio.png", 521, 324, "#edf0f0" ] } ] } [/block] ### Scatter by multiple input ports There are several methods for scattering by multiple input ports. Each of the methods is explained in more detail in the sections below. #### Dot Product This method takes one value from each input port and uses them to create a job. There will be as many jobs as there are values provided to one input port. _Therefore, the method works properly only if the number of provided input values on each input port is the same_. If that is not the case, an error is thrown. To understand how the **dot product** method works, please look at the explanation and the accompanying diagram below: * We have two input ports and the values provided to those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B. There are two values provided on each input port, which meets the requirement of having to provide an equal number of values on all scattered input ports if using the **dot product** method. * Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B. * Separate jobs (working instances of the app that does the processing) are generated by taking the first values from each input (**A1** and **B1**) to create one job, and the second ones (**A2** and **B2**) to create the second job. These are executed in parallel. * Outputs resulting from both processing jobs are sent to a single output port. * The output port produces an output array containing output values **C11** and **C22**, the first one resulting from inputs **A1** and **B1**, and the second one resulting from inputs **A2** and **B2**, respectively. [block:image] { "images": [ { "image": [ "https://files.readme.io/2ced244-scatter_dot_product.drawio.png", "scatter_dot_product.drawio.png", 521, 324, "#ebeeee" ] } ] } [/block] This is what the dot product scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports: [block:code] { "codes": [ { "code": "scatter: [A, B]\nscatterMethod: \"dotproduct\"", "language": "java" } ] } [/block] #### Nested Cross Product This method specifies the Cartesian product of the inputs, producing a job for every combination of input values provided on scattered input ports. The output must be a nested array for each level of scattering in the order in which the input arrays are listed in the scatter field. To understand how the **nested cross product** method works, please look at the explanation and the accompanying diagram below: * We have two input ports and the values provided to those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B. * Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B. * Separate jobs (working instances of the app that does the processing) are generated by combining each input value from port A with each input value from port B (**A1** and **B1**, **A1** and **B2**, **A2** and **B1**, **A2** and **B2**), which gives us a total of 4 jobs when we have two input ports with two input values provided on each port. The jobs are executed in parallel. * Outputs resulting from both processing jobs are sent to a single output port. * The output port produces an output array containing one output value per job, in this case value **C11** resulting from inputs **A1** and **B1**, **C12** resulting from inputs **A1** and **B2**, **C21** resulting from inputs **A2** and **B1**, and **C22** resulting from inputs **A2** and **B2**. The important thing to note is that _outputs are grouped (nested) for each level of scattering in the order in which the input arrays are listed in the scatter field_. For example, if the first field that is selected for scattering is field A, the first group of outputs will be **C11** and **C12**, which are results of processing input value **A1** with input values **B1** and **B2** respectively. The second group of outputs will be **C21** and **C22**, which are results of processing input value **A2** with input values **B1** and **B2** respectively. Represented in array format, this would be the final output [[C11, C12], [C21, C22]]. [block:image] { "images": [ { "image": [ "https://files.readme.io/10fea86-scatter_nested_crossproduct.drawio.png", "scatter_nested_crossproduct.drawio.png", 553, 492, "#ebefef" ] } ] } [/block] This is what the **nested cross product** scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports and the first port in the scattering order being input port **A**: [block:code] { "codes": [ { "code": "scatter: [A, B]\nscatterMethod: \"nested_crossproduct\"", "language": "java" } ] } [/block] #### Flat Cross Product This method specifies the Cartesian product of the inputs, producing a job for every combination of input values provided on scattered input ports. The jobs are created and outputs are produced in the order in which the input ports are selected for scattering.  To understand how the **flat cross product** method works, please look at the explanation and the accompanying diagram below: * There are two input ports and the values provided on those ports are input array containing values **A1** and **A2** for input port A, and input array containing values **B1** and **B2** for input port B. * Scattering is enabled on _all_ input ports we want to scatter by, in this case both port A and B. * Separate jobs (working instances of the app that does the processing) are generated by combining each input value from port A with each input value from port B (**A1** and **B1**, **A1** and **B2**, **A2** and **B1**, **A2** and **B2**), which gives us a total of 4 jobs when we have two input ports with two input values provided on each port. The jobs are executed in parallel. * Outputs resulting from both processing jobs are sent to a single output port. * The output port produces an array containing one output value per job, in this case value **C11** resulting from input values **A1** and **B1**, **C12** resulting from input values **A1** and **B2**, **C21** resulting from input values **A2** and **B1**, and **C22** resulting from input values **A2** and **B2**. Note that outputs are presented in the order in which the input ports are selected for scattering. For example, if the first field that is selected for scattering is field A, the first outputs will be **C11** and **C12**, which are results of processing input value **A1** with input values **B1** and **B2** respectively. The following outputs will be **C21** and **C22**, which are results of processing input value **A2** with input values **B1** and **B2** respectively. Unlike the **nested cross product** method where the output values are grouped, the **flat cross product** method outputs a completely _flat_ structure with no nesting (grouping) of output values. Represented as an array, this would be the final output [C11, C12, C21, C22]. [block:image] { "images": [ { "image": [ "https://files.readme.io/30186e2-scatter_flat_crossproduct.drawio.png", "scatter_flat_crossproduct.drawio.png", 531, 493, "#ebefef" ] } ] } [/block] This is what the **flat cross product** scatter method is noted in an app's CWL description, with **A** and **B** being identifiers of the scattered input ports and the first port in the scattering order being input port **A**: [block:code] { "codes": [ { "code": "scatter: [A, B]\nscatterMethod: \"flat_crossproduct\"", "language": "java" } ] } [/block] ### Configuring scattering in the Workflow Editor To configure scattering for an input port in a workflow step, first open the step configuration as follows: 1. Navigate to a project. 2. Click the **Apps** tab. 3. Click the name of the workflow you want to edit. 4. In the top-right corner click **Edit**. Workflow Editor opens. 5. Double-click the node in the workflow whose input(s) you want to scatter. Object inspector opens. 6. In the Object Inspector, click the **Step** tab. From this point on, follow the instructions below depending on the CWL version of your workflow. To set scattering in CWL v1.x workflows: 1. Under **Scatter**, select the input port(s) you want to scatter by. Hold `Cmd` (`Ctrl`) or `Shift` to select multiple ports. 2. If you have selected _more than one port_ in the previous step, under **Scatter Method**, select the [method](#scatter-by-multiple-input-ports) that best matches the way you want the input values to be paired and processed. [block:image] { "images": [ { "image": [ "https://files.readme.io/c7b058e-set-scatter-multiple-ports.png", "set-scatter-multiple-ports.png", 322, 669, "#f5f4f3" ] } ] } [/block] 3. Click the save icon <i class="fa fa-floppy-o" aria-hidden="true"></i> to save the changes. You have now enabled scattering for the selected input ports. To set scattering for workflow steps in `sbg:draft-2` workflows (this CWL version allows scattering only by one input port): 1. Under **Scatter**, select the input port you want to scatter by. [block:image] { "images": [ { "image": [ "https://files.readme.io/173980d-set-scatter-single-port.png", "set-scatter-single-port.png", 1222, 671, "#f6f7f6" ] } ] } [/block] 2. Click the save icon <i class="fa fa-floppy-o" aria-hidden="true"></i> to save the changes. You have now enabled scattering for the input port. ##Keeping scattering under control The power of scattering to reduce analysis time lies in making full use of the available compute resources. You can control the resources available for the execution of an app by specifying instance type and the number of instances to be used in parallel. While scattering is a powerful tool to shorten your analysis run time, it may well increase the overall cost of your analysis if used in combination with certain other settings. There are two ways in which you can fine-tune how the scattering works on a tool: * Configuring computational instances on the tool. * Setting the maximum number of parallel instances; ###Controlling via instance type Based on the scattered [tool's resource requirements](doc:about-tool-resource-requirements), you may want to pick an instance that leaves the least CPU and memory to waste for a given number of scattered jobs and maximum number of parallel instances. [This blog post](blog:making-efficient-use-of-compute-resources#section-choosing-the-best-compute-instance-for-your-analysis) explains how to choose an instance suitable for your analysis. To set the instance type, set the [`sbg:AWSInstanceType`](doc:list-of-execution-hints) or [`sbg:GoogleInstanceType`](doc:list-of-execution-hints) hint at [workflow level](doc:set-execution-hints-at-workflow-level). ###Controlling via maximum number of parallel instances If you anticipate that the execution of the tool which you are scattering is time-critical for the entire workflow, you can configure the maximum number of instances that the Scheduling Algorithm is allowed to have running at any one time. If the jobs that would be started as a result of scattering cannot fit onto the provisioned instances according to their tool's resource requirements, those jobs will be queued for execution. As soon as enough resources become available following the completion of other jobs, queued jobs will be executed. This ensures there will be less idle time across the entire task. The CGC bioinformaticians exploit this technique when tuning workflows in Public Apps To set the maximum number of instances, set the [`sbg:maxNumberOfParallelInstances`](doc:list-of-execution-hints) hint at [workflow level](doc:set-execution-hints-at-workflow-level).