Skip to content

Commit

Permalink
Limits maximum number of task groups to 2048.
Browse files Browse the repository at this point in the history
To protect system stability, maximum number of task groups is limited to 2048
':'-separated executable groups. This caps the number of allocations per unique
ALPS Reservation-Application ID pair. ALPS chokes when the number of allocations
in an application is large, but no practical maximum is discussed in the Cray
documentation. As such, this number is arbitrarily chosen and is being reduced
as administrators report issues.
  • Loading branch information
mpbelhorn committed Aug 22, 2016
1 parent 755930e commit 6d1f531
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 25 deletions.
58 changes: 39 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
# wraprun
`wraprun` is a utility that enables independent execution of multiple MPI applications under a single `aprun` call.
`wraprun` is a utility that enables independent execution of multiple MPI
applications under a single `aprun` call.

## To install:
`wraprun` includes a Smithy formula to automate deployment, for centers not using Smithy the build looks as follow:
`wraprun` includes a Smithy formula to automate deployment, for centers not
using Smithy the build looks as follow:

```
$ mkdir build
$ cmake -DCMAKE_INSTALL_PREFIX=/path/to/install ..
$ make
$ make install
```
Inside of `/path/to/install` a `bin` directory will be created containing the `wraprun` scripts and a `lib` directory will be created containing `libsplit.so`. The `WRAPRUN_PRELOAD` environment variable must be correctly set to point to `libsplit.so` and in the case of fortran applications `libfmpich.so` at runtime.
e.g. `WRAPRUN_PRELOAD=/path/to/install/lib/libsplit.so:/path/to/mpi_install/lib/libfmpich.so`
Inside of `/path/to/install` a `bin` directory will be created containing the
`wraprun` scripts and a `lib` directory will be created containing
`libsplit.so`. The `WRAPRUN_PRELOAD` environment variable must be correctly set
to point to `libsplit.so` and in the case of fortran applications
`libfmpich.so` at runtime. e.g.
`WRAPRUN_PRELOAD=/path/to/install/lib/libsplit.so:/path/to/mpi_install/lib/libfmpich.so`

On some systems libfmpich has a programming environment specific suffix that must be taken into account:
e.g. `WRAPRUN_PRELOAD=/path/to/install/lib/libsplit.so:/path/to/mpi_install/lib/libfmpich_pgi.so`
On some systems libfmpich has a programming environment specific suffix that
must be taken into account: e.g.
`WRAPRUN_PRELOAD=/path/to/install/lib/libsplit.so:/path/to/mpi_install/lib/libfmpich_pgi.so`

## To run:
Assuming that the module file created by the Smithy formula is used, or a similar one created, basic running looks like the following examples.
Assuming that the module file created by the Smithy formula is used, or a
similar one created, basic running looks like the following examples.

```
$ module load python wraprun
$ wraprun -n 80 ./foo.out : -n 160 ./bar.out ...
```
A maximum of 2048 separate `:` separated task groups is enforced to protect
ALPS stability.

In addition to the standard process placement flags available to aprun the `--w-cd` flag can be set to change the current working directory for each executable:
In addition to the standard process placement flags available to aprun the
`--w-cd` flag can be set to change the current working directory for each
executable:
```
$ wraprun -n 80 --w-cd /foo/dir ./foo.out : -n 160 --w-cd /bar/dir ./bar.out ...
```
This is particularly useful for legacy Fortran applications that use hard coded input and output file names.
This is particularly useful for legacy Fortran applications that use hard coded
input and output file names.

Multiple instances of an application can be placed on a node using
comma-separated PES syntax `PES1,PES2,...,PESN` syntax, for instance:
Expand All @@ -37,14 +50,18 @@ $ wraprun -n 2,2,2 ./foo.out : ...
```
would launch 3 two-process instances of foo.out on a single node.

In this case the number of allocated nodes must be at least equal to the sum of processes in the comma-separated list of processing elements divided by the maximum number of processes per node.
In this case the number of allocated nodes must be at least equal to the sum of
processes in the comma-separated list of processing elements divided by the
maximum number of processes per node.

This may also be combined with the `--w-cd` flag :
```
$ wraprun -n 2,2,2 --w-cd /foo/dir1,/foo/dir2,/foo/dir3 ./foo.out : ...
```

For non MPI executables a wrapper application, `serial`, is provided. This wrapper ensures that all executables will run to completion before aprun exits. To use, place `serial` in front of your application and arguments:
For non MPI executables a wrapper application, `serial`, is provided. This
wrapper ensures that all executables will run to completion before aprun exits.
To use, place `serial` in front of your application and arguments:
```
$ wraprun -n 1 serial ./foo.out -foo_args : ...
```
Expand All @@ -60,20 +77,21 @@ ${JOBNAME}.${JOBID}_w${INSTANCE}.${TASKID}.err
```

where `JOBNAME` is the batch job name (value of `$PBS_JOBNAME` for instance),
`JOBID` is the batch job number (or PID of parent shell if `$PBS_JOBID` is unavailable),
`INSTANCE` is the unique wraprun invocation called within the parent shell, and
`TASKID` is the task index among all bundled tasks. The instance index is
required so that multiple concurrent wraprun invocations in a single batch job
do not collide with each other. The task index is fixed in the order that tasks are
passed to wraprun such that for the following invocation:
`JOBID` is the batch job number (or PID of parent shell if `$PBS_JOBID` is
unavailable), `INSTANCE` is the unique wraprun invocation called within the
parent shell, and `TASKID` is the task index among all bundled tasks. The
instance index is required so that multiple concurrent wraprun invocations in a
single batch job do not collide with each other. The task index is fixed in the
order that tasks are passed to wraprun such that for the following invocation:
```
$ wraprun -n 1,2 ./foo.out : -n 3 ./bar.out
```

task '0' is the instance of `foo.out` having 1 PE; task '1' is the 2 PE split of
`foo.out`, and task '2' is the instance of `bar.out`.

The default names can be overridden by supplying a basename path to the group flag `--w-oe`:
The default names can be overridden by supplying a basename path to the group
flag `--w-oe`:

```
$ wraprun -n 1,2 --w-oe name_a ./a.out : \
Expand Down Expand Up @@ -188,7 +206,9 @@ See the testing/example_config.yaml file for format information.


## Disclaimer
`wraprun` works by intercepting <i>all</i> MPI function calls that contain an `MPI_Comm` argument. If an application calls an MPI function, containing an `MPI_Comm` argument, not included in `src/split.c` the results are undefined.
`wraprun` works by intercepting <i>all</i> MPI function calls that contain an
`MPI_Comm` argument. If an application calls an MPI function, containing an
`MPI_Comm` argument, not included in `src/split.c` the results are undefined.

If any executable is not dynamically linked the results are undefined.

Expand Down
4 changes: 4 additions & 0 deletions python/wraprun/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ def add_task(self, string=None, **kwargs):
self._rank_and_color = {
k: v + 1 for k, v in task_group.last_rank_and_color().items()}
self._task_groups.append(task_group)
if len(self._task_groups) > 2048:
raise WraprunError(
'Too many task groups (> 2048) in bundle: '
'Aborting to protect ALPS stability.')
self._update_file(task_group)

def _debug_mode(self):
Expand Down
10 changes: 5 additions & 5 deletions share/man/man1/wraprun.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH WRAPRUN "1" "May 2016" "wraprun 0.2.3+" "User Commands"
.TH WRAPRUN "1" "Aug 2016" "wraprun 0.2.4+" "User Commands"
.SH NAME
.B wraprun
\- an ensemble task wrapper for aprun
Expand All @@ -16,10 +16,10 @@ options] [: task ]...
.B wraprun
--w-conf file
.SH DESCRIPTION
Wraps an arbitrary number of independent MPI and/or serial executables into an ensemble
that runs under a single aprun call. MPI executables must be dynamically linked
to run correctly under wraprun. However, serial applications can be run as-is
when declared with the keyword 'serial'.
Wraps independent MPI and/or serial executables into an ensemble that runs under
a single aprun call. A maximum of 2048 separate executables may be bundled. MPI
executables must be dynamically linked to run correctly under wraprun. However,
serial applications can be run as-is when declared with the keyword 'serial'.
.SH OPTIONS
.PP
.SS "Global Options"
Expand Down
2 changes: 1 addition & 1 deletion wraprun_formula.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class WraprunFormula < Formula
homepage "https://github.com/olcf/wraprun"
url "https://github.com/olcf/wraprun/archive/v0.2.3.tar.gz"
url "https://github.com/olcf/wraprun/archive/v0.2.4.tar.gz"

supported_build_names /python2.7/, /python3/

Expand Down

0 comments on commit 6d1f531

Please sign in to comment.