While MPI_COMM_SPAWN is sufficient for most cases, it does not allow the spawning of multiple binaries, or of the same binary with multiple sets of arguments. The following routine spawns multiple binaries or the same binary with multiple sets of arguments, establishing communication with them and placing them in the same MPI_COMM_WORLD.
MPI_COMM_SPAWN_MULTIPLE(count,
array_of_commands, array_of_argv, array_of_maxprocs,
array_of_info, root, comm, intercomm, array_of_errcodes)
[ IN count] number of commands
(positive integer, significant to MPI only at root --- see advice to users)
[ IN array_of_commands] programs to be executed
(array of strings, significant only at root)
[ IN array_of_argv] arguments for commands (array
of array of strings, significant only at root)
[ IN array_of_maxprocs] maximum number of processes to start for
each command (array of integer, significant only at root)
[ IN array_of_info] info objects telling the runtime system where
and how to start processes (array of handles, significant only at root)
[ IN root] rank of process in which previous arguments are
examined (integer)
[ IN comm] intracommunicator containing group of spawning processes (handle)
[ OUT intercomm] intercommunicator between original group and
newly spawned group (handle)
[ OUT array_of_errcodes] one error code per process
(array of integer)
int MPI_Comm_spawn_multiple(int count, char *array_of_commands[], char **array_of_argv[], int array_of_maxprocs[], MPI_Info array_of_info[], int root, MPI_Comm comm, MPI_Comm *intercomm, int array_of_errcodes[])
MPI_COMM_SPAWN_MULTIPLE(COUNT, ARRAY_OF_COMMANDS, ARRAY_OF_ARGV, ARRAY_OF_MAXPROCS, ARRAY_OF_INFO, ROOT, COMM, INTERCOMM, ARRAY_OF_ERRCODES, IERROR)
INTEGER COUNT, ARRAY_OF_INFO(*), ARRAY_OF_MAXPROCS(*), ROOT, COMM, INTERCOMM, ARRAY_OF_ERRCODES(*), IERROR
CHARACTER*(*) ARRAY_OF_COMMANDS(*), ARRAY_OF_ARGV(COUNT, *)
MPI::Intercomm MPI::Intracomm::Spawn_multiple(int count, const char* array_of_commands[], const char** array_of_argv[], const int array_of_maxprocs[], const MPI::Info array_of_info[], int root, int array_of_errcodes[])
MPI::Intercomm MPI::Intracomm::Spawn_multiple(int count, const char* array_of_commands[], const char** array_of_argv[], const int array_of_maxprocs[], const MPI::Info array_of_info[], int root)
MPI_COMM_SPAWN_MULTIPLE is identical to MPI_COMM_SPAWN except
that there are multiple executable specifications. The first argument,
count, gives the number of specifications. Each of the
next four arguments are simply arrays of the corresponding arguments
in MPI_COMM_SPAWN.
For the Fortran version of array_of_argv, the element
array_of_argv(i,j) is the jth argument
to command number i.
[] Rationale.
This may seem backwards to
Fortran programmers who are familiar with Fortran's
column-major ordering. However, it is necessary to do
it this way to allow MPI_COMM_SPAWN to sort out
arguments. Note that the leading dimension of
array_of_argv must be the same as
count.
( End of rationale.)
[] Advice to users.
The argument count is interpreted by MPI only at the root,
as is array_of_argv. Since the leading dimension
of array_of_argv is count, a non-positive
value of count at a non-root node could theoretically
cause a runtime bounds check error, even though
array_of_argv should be ignored by the
subroutine. If this happens, you should explicitly
supply a reasonable value of count on the non-root
nodes.
( End of advice to users.)
In any language, an application may use the constant MPI_ARGVS_NULL (which is likely to be (char ***)0 in C) to specify that no arguments should be passed to any commands. The effect of setting individual elements of array_of_argv to MPI_ARGV_NULL is not defined. To specify arguments for some commands but not others, the commands without arguments should have a corresponding argv whose first element is null ( (char *)0 in C and empty string in Fortran).
All of the spawned processes have the same MPI_COMM_WORLD. Their ranks in MPI_COMM_WORLD correspond directly to the order in which the commands are specified in MPI_COMM_SPAWN_MULTIPLE. Assume that m1 processes are generated by the first command, m2 by the second, etc. The processes corresponding to the first command have ranks . The processes in the second command have ranks . The processes in the third have ranks , etc.
[] Advice to users.
Calling MPI_COMM_SPAWN multiple times
would create many sets of children with different MPI_COMM_WORLDs
whereas MPI_COMM_SPAWN_MULTIPLE creates children with
a single MPI_COMM_WORLD, so the two methods
are not completely equivalent.
There are also two performance-related reasons why,
if you need to spawn multiple executables, you may want to use
MPI_COMM_SPAWN_MULTIPLE instead of calling MPI_COMM_SPAWN
several times. First, spawning several
things at once may be faster than spawning them sequentially. Second,
in some implementations,
communication between processes spawned at the same time may be
faster than communication between processes spawned separately.
( End of advice to users.)
The array_of_errcodes argument is 1-dimensional
array of size
,
where ni is the ith element of array_of_maxprocs.
Command number i corresponds to the ni contiguous
slots in this array from element
to
.
Error codes are treated
as for MPI_COMM_SPAWN.
Example Examples of array_of_argv in C and Fortran
To run the program ``ocean'' with arguments ``-gridfile'' and
``ocean1.grd'' and the program ``atmos'' with argument ``atmos.grd''
in C:
char *array_of_commands[2] = {"ocean", "atmos"}; char **array_of_argv[2]; char *argv0[] = {"-gridfile", "ocean1.grd", (char *)0}; char *argv1[] = {"atmos.grd", (char *)0}; array_of_argv[0] = argv0; array_of_argv[1] = argv1; MPI_Comm_spawn_multiple(2, array_of_commands, array_of_argv, ...);Here's how you do it in Fortran:
CHARACTER*25 commands(2), array_of_argv(2, 3) commands(1) = ' ocean ' array_of_argv(1, 1) = ' -gridfile ' array_of_argv(1, 2) = ' ocean1.grd' array_of_argv(1, 3) = ' 'commands(2) = ' atmos ' array_of_argv(2, 1) = ' atmos.grd ' array_of_argv(2, 2) = ' '
call MPI_COMM_SPAWN_MULTIPLE(2, commands, array_of_argv, ...)