<commit_before>.. _configuration-section:

Configuration
=============

Parsl workflows are developed completely independently from their execution environment.
There are very many different execution environments in which Parsl programs and their apps can run, and
many of these environments have multiple options of how those programs and apps run, which makes
configuration somewhat complex, and also makes determining how to set up Parsl's configuration
for a particular set of choices fairly complex, though we think the actual configuration
itself is reasonable simple.

Parsl offers an extensible configuration model through which the execution environment and
communication with that environment is configured. Parsl is configured
using :class:`~parsl.config.Config` object. For more information, see
the :class:`~parsl.config.Config` class documentation. The following shows how the
configuration can be specified.

   .. code-block:: python

      import parsl
      from parsl.config import Config
      from parsl.executors.threads import ThreadPoolExecutor

      config = Config(
          executors=[ThreadPoolExecutor()],
          lazy_errors=True
      )
      parsl.load(config)

.. contents:: Configuration How-To and Examples:

.. note::
   Please note that all configuration examples below require customization for your account, 
   allocation, Python environment, etc. 

How-to Configure
----------------

The configuration provided to Parsl tells Parsl what resources to use to run the Parsl
program and apps, and how to use them.
Therefore it is important to carefully evaluate certain aspects of the Parsl program and apps,
and the planned compute resources, to determine an ideal configuration match. These aspects are:
1) where the Parsl apps will execute;
2) how many nodes will be used to execute the apps, and how long the apps will run;
3) should the scheduler allocate multiple nodes at one time; and
4) where will the main parsl program run and how will it communicate with the apps.

Stepping through the following question should help you formulate a suitable configuration.
In addition, examples for some specific configurations follow.


1. Where would you like the apps in the Parsl program to run?

+---------------------+----------------------------+------------------------+
| Target              | Executor                   | Provider               |
+=====================+============================+========================+
| Laptop/Workstation  | * `ThreadPoolExecutor`     | `LocalProvider`        |
|                     | * `IPyParallelExecutor`    |                        |
|                     | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Amazon Web Services | * `IPyParallelExecutor`    | `AWSProvider`          |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Google Cloud        | * `IPyParallelExecutor`    | `GoogleCloudProvider`  |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Slurm based cluster | * `IPyParallelExecutor`    | `SlurmProvider`        |
| or supercomputer    | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Torque/PBS based    | * `IPyParallelExecutor`    | `TorqueProvider`       |
| cluster or          | * `HighThroughputExecutor` |                        |
| supercomputer       | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Cobalt based cluster| * `IPyParallelExecutor`    | `CobaltProvider`       |
| or supercomputer    | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| GridEngine based    | * `IPyParallelExecutor`    | `GridEngineProvider`   |
| cluster or grid     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Condor based        | * `IPyParallelExecutor`    | `CondorProvider`       |
| cluster or grid     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Kubernetes cluster  | * `IPyParallelExecutor`    | `KubernetesProvider`   |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+

2. How many nodes will you use to run them? What task durations give good performance on different executors?


+--------------------------+----------------------+------------------------------------+
| Executor                 | Number of Nodes [*]_ | Task duration for good performance |
+==========================+======================+====================================+
| `ThreadPoolExecutor`     | 1 (Only local)       |  Any                               |
+--------------------------+----------------------+------------------------------------+
| `LowLatencyExecutor`     | <=10                 |  10ms+                             |
+--------------------------+----------------------+------------------------------------+
| `IPyParallelExecutor`    | <=128                |  50ms+                             |
+--------------------------+----------------------+------------------------------------+
| `HighThroughputExecutor` | <=2000               |  Task duration(s)/#nodes >= 0.01   |
|                          |                      | longer tasks needed at higher scale|
+--------------------------+----------------------+------------------------------------+
| `ExtremeScaleExecutor`   | >1000, <=8000 [*]_   |  >minutes                          |
+--------------------------+----------------------+------------------------------------+


.. [*] We assume that each node has 32 workers. If there are fewer workers launched
       per node, a higher number of nodes could be supported.

.. [*] 8000 nodes with 32 workers each totalling 256000 workers is the maximum scale that
       we've tested the `ExtremeScaleExecutor` at.

.. warning:: `IPyParallelExecutor` will be deprecated as of Parsl v0.8.0, with `HighThroughputExecutor`
             as the recommended replacement.


3. If you are running on a cluster or supercomputer, will you request multiple nodes per batch (scheduler) job?
(Here we use the term block to be equivalent to a batch job.)

+----------------------------------------------------------------------------+
| ``nodes_per_block = 1``                                                    |
+---------------------+--------------------------+---------------------------+
| Provider            | Executor choice          | Suitable Launchers        |
+=====================+==========================+===========================+
| Systems that don't  | Any                      | * `SingleNodeLauncher`    |
| use Aprun           |                          | * `SimpleLauncher`        |
+---------------------+--------------------------+---------------------------+
| Aprun based systems | Any                      | * `AprunLauncher`         |
|                     |                          |                           |
+---------------------+--------------------------+---------------------------+

+-------------------------------------------------------------------------------------+
| ``nodes_per_block > 1``                                                             |
+---------------------+--------------------------+------------------------------------+
| Provider            | Executor choice          | Suitable Launchers                 |
+=====================+==========================+====================================+
| `TorqueProvider`    | Any                      | * `AprunLauncher`                  |<commit_msg>A few more small changes in conf docs (#990)<commit_after>.. _configuration-section:

Configuration
=============

Parsl workflows are developed completely independently from their execution environment.
There are very many different execution environments in which Parsl programs and their apps can run, and
many of these environments have multiple options of how those Parsl programs and apps run, which makes
configuration somewhat complex, and also makes determining how to set up Parsl's configuration
for a particular set of choices fairly complex, though we think the actual configuration
itself is reasonable simple.

Parsl offers an extensible configuration model through which the execution environment and
communication within that environment is configured. Parsl is configured
using :class:`~parsl.config.Config` object. For more information, see
the :class:`~parsl.config.Config` class documentation. The following shows how the
configuration can be specified.

   .. code-block:: python

      import parsl
      from parsl.config import Config
      from parsl.executors.threads import ThreadPoolExecutor

      config = Config(
          executors=[ThreadPoolExecutor()],
          lazy_errors=True
      )
      parsl.load(config)

.. contents:: Configuration How-To and Examples:

.. note::
   Please note that all configuration examples below require customization for your account, 
   allocation, Python environment, etc. 

How to Configure
----------------

The configuration provided to Parsl tells Parsl what resources to use to run the Parsl
program and apps, and how to use them.
Therefore it is important to carefully evaluate certain aspects of the Parsl program and apps,
and the planned compute resources, to determine an ideal configuration match. These aspects are:
1) where the Parsl apps will execute;
2) how many nodes will be used to execute the apps, and how long the apps will run;
3) should the scheduler allocate multiple nodes at one time; and
4) where will the main parsl program run and how will it communicate with the apps.

Stepping through the following question should help you formulate a suitable configuration.
In addition, examples for some specific configurations follow.


1. Where would you like the apps in the Parsl program to run?

+---------------------+----------------------------+------------------------+
| Target              | Executor                   | Provider               |
+=====================+============================+========================+
| Laptop/Workstation  | * `ThreadPoolExecutor`     | `LocalProvider`        |
|                     | * `IPyParallelExecutor`    |                        |
|                     | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Amazon Web Services | * `IPyParallelExecutor`    | `AWSProvider`          |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Google Cloud        | * `IPyParallelExecutor`    | `GoogleCloudProvider`  |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Slurm based cluster | * `IPyParallelExecutor`    | `SlurmProvider`        |
| or supercomputer    | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Torque/PBS based    | * `IPyParallelExecutor`    | `TorqueProvider`       |
| cluster or          | * `HighThroughputExecutor` |                        |
| supercomputer       | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| Cobalt based cluster| * `IPyParallelExecutor`    | `CobaltProvider`       |
| or supercomputer    | * `HighThroughputExecutor` |                        |
|                     | * `ExtremeScaleExecutor`   |                        |
+---------------------+----------------------------+------------------------+
| GridEngine based    | * `IPyParallelExecutor`    | `GridEngineProvider`   |
| cluster or grid     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Condor based        | * `IPyParallelExecutor`    | `CondorProvider`       |
| cluster or grid     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+
| Kubernetes cluster  | * `IPyParallelExecutor`    | `KubernetesProvider`   |
|                     | * `HighThroughputExecutor` |                        |
+---------------------+----------------------------+------------------------+

2. How many nodes will you use to run them? What task durations give good performance on different executors?


+--------------------------+----------------------+------------------------------------+
| Executor                 | Number of Nodes [*]_ | Task duration for good performance |
+==========================+======================+====================================+
| `ThreadPoolExecutor`     | 1 (Only local)       |  Any                               |
+--------------------------+----------------------+------------------------------------+
| `LowLatencyExecutor`     | <=10                 |  10ms+                             |
+--------------------------+----------------------+------------------------------------+
| `IPyParallelExecutor`    | <=128                |  50ms+                             |
+--------------------------+----------------------+------------------------------------+
| `HighThroughputExecutor` | <=2000               |  Task duration(s)/#nodes >= 0.01   |
|                          |                      | longer tasks needed at higher scale|
+--------------------------+----------------------+------------------------------------+
| `ExtremeScaleExecutor`   | >1000, <=8000 [*]_   |  >minutes                          |
+--------------------------+----------------------+------------------------------------+


.. [*] We assume that each node has 32 workers. If there are fewer workers launched
       per node, a higher number of nodes could be supported.

.. [*] 8000 nodes with 32 workers each totalling 256000 workers is the maximum scale at which
       we've tested the `ExtremeScaleExecutor`.

.. warning:: `IPyParallelExecutor` will be deprecated as of Parsl v0.8.0, with `HighThroughputExecutor`
             as the recommended replacement.


3. If you are running on a cluster or supercomputer, will you request multiple nodes per batch (scheduler) job?
(Here we use the term block to be equivalent to a batch job.)

+----------------------------------------------------------------------------+
| ``nodes_per_block = 1``                                                    |
+---------------------+--------------------------+---------------------------+
| Provider            | Executor choice          | Suitable Launchers        |
+=====================+==========================+===========================+
| Systems that don't  | Any                      | * `SingleNodeLauncher`    |
| use Aprun           |                          | * `SimpleLauncher`        |
+---------------------+--------------------------+---------------------------+
| Aprun based systems | Any                      | * `AprunLauncher`         |
|                     |                          |                           |
+---------------------+--------------------------+---------------------------+

+-------------------------------------------------------------------------------------+
| ``nodes_per_block > 1``                                                             |
+---------------------+--------------------------+------------------------------------+
| Provider            | Executor choice          | Suitable Launchers                 |
+=====================+==========================+====================================+
| `TorqueProvider`    | Any                      | * `AprunLauncher`                  |
{'fraction_non_alphanumeric': 0.30817910447761193, 'fraction_numerical': 0.00626865671641791, 'mean_word_length': 1.123605476673428, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 23, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6621026', 'n_tokens_mistral': 3355, 'n_tokens_neox': 3080, 'n_words': 1086}