diff --git a/docs/papers/joss/paper.md b/docs/papers/joss/paper.md index f5f8ee71d..29803d895 100644 --- a/docs/papers/joss/paper.md +++ b/docs/papers/joss/paper.md @@ -51,7 +51,7 @@ Some crucial considerations relevant to these packages include: - Ease of use - whether the software requires a complex setup. -- Portability - running on different machines with different schedulers, hardware, MPI runners with minimal modification to user scripts. +- Portability - running on different machines with different schedulers, hardware, and MPI runners with minimal modification to user scripts. - Scalability - working efficiently with large simulations and many concurrent simulations. @@ -65,11 +65,11 @@ Some crucial considerations relevant to these packages include: LibEnsemble stands out primarily through its generator-simulator paradigm, which eliminates the need for users to explicitly define task dependencies. Instead, it emphasizes data dependencies between customizable Python user functions. This modular design also lends itself to exploiting the large library of example user functions that are provided with libEnsemble, maximizing code reuse. For instance, users can readily choose an existing generator function and tailor a simulator function to their particular needs. -libEnsemble is a complete toolkit that includes generator in-the-loop and backend mechanisms. Some other packages cover a sub-set of the workflow. Colmena, for example, has a front-end that uses components to create and coordinate tasks while using Parsl to dispatch simulations. libEnsemble communicates between a manager and multiple workers using either Pythons built-in multiprocessing, MPI (via mpi4py), or TCP. +libEnsemble is a complete toolkit that includes generator in-the-loop and backend mechanisms. Some other packages cover a sub-set of the workflow. Colmena, for example, has a front-end that uses components to create and coordinate tasks while using Parsl to dispatch simulations. libEnsemble communicates between a manager and multiple workers using either Python's built-in multiprocessing, MPI (via mpi4py), or TCP. libEnsemble takes the philosophy of minimizing required dependencies while supporting various back-end mechanisms when needed. For example, the vast majority of users do not require to be running a database application or special run-time to use libEnsemble, but for those that do, Balsam can be used on the back-end by substituting the regular MPI executor for the Balsam executor. This approach simplifies the user experience and reduces the initial setup and adoption costs when using libEnsemble. -To achieve portability, libEnsemble employs system detection beyond other packages. It detects crucial system information such as scheduler details, MPI runners, core counts, GPU counts (for different types of GPU), and uses these to produce run-lines and GPU settings for these systems, without the user having to alter scripts. For example, on a system using "srun", libEnsemble will use srun options to assign GPUs, while on other systems it may assign via environment variables such as ROCR_VISIBLE_DEVICES or CUDA_VISIBLE_DEVICES, while the user only states the number of GPUs needed for each simulation. For cases where autodetection is insufficient, the user can supply platform information or the name of a known system via scripts or an environment variable. +To achieve portability, libEnsemble employs system detection beyond other packages. It detects crucial system information such as scheduler details, MPI runners, core counts, and GPU counts (for different types of GPU) and uses these to produce run-lines and GPU settings for these systems, without the user having to alter scripts. For example, on a system using "srun", libEnsemble will use srun options to assign GPUs, while on other systems it may assign via environment variables such as ROCR_VISIBLE_DEVICES or CUDA_VISIBLE_DEVICES, while the user only states the number of GPUs needed for each simulation. For cases where autodetection is insufficient, the user can supply platform information or the name of a known system via scripts or an environment variable. By default, libEnsemble divides available compute resources amongst workers. However, when simulation parameters are created, the number of processes and GPUs can also be specified for each simulation. Combined with the portability features, this makes it very simple to transfer user scripts between platforms.