I have two openmpi programs which I start like this
mpirun -n 4 ./prog1 : -n 2 ./prog2
Now how do I use MPI_Comm_size(MPI_COMM_WORLD, &size)
such that i get size values as
prog1 size=4
prog2 size=2.
As of now I get "6" in both programs.
I have two openmpi programs which I start like this
mpirun -n 4 ./prog1 : -n 2 ./prog2
Now how do I use MPI_Comm_size(MPI_COMM_WORLD, &size)
such that i get size values as
prog1 size=4
prog2 size=2.
As of now I get "6" in both programs.
This is doable albeit a bit cumbersome to get that. The principle is to split MPI_COMM_WORLD
into communicators based on the value of argv[0]
, which contains the executable's name.
That could be something like that:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mpi.h>
int main( int argc, char *argv[] ) {
MPI_Init( &argc, &argv );
int wRank, wSize;
MPI_Comm_rank( MPI_COMM_WORLD, &wRank );
MPI_Comm_size( MPI_COMM_WORLD, &wSize );
int myLen = strlen( argv[0] ) + 1;
int maxLen;
// Gathering the maximum length of the executable' name
MPI_Allreduce( &myLen, &maxLen, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD );
// Allocating memory for all of them
char *names = malloc( wSize * maxLen );
// and copying my name at its place in the array
strcpy( names + ( wRank * maxLen ), argv[0] );
// Now collecting all executable' names
MPI_Allgather( MPI_IN_PLACE, 0, MPI_DATATYPE_NULL,
names, maxLen, MPI_CHAR, MPI_COMM_WORLD );
// With that, I can sort-out who is executing the same binary as me
int binIdx = 0;
while( strcmp( argv[0], names + binIdx * maxLen ) != 0 ) {
binIdx++;
}
free( names );
// Now, all processes with the same binIdx value are running the same binary
// I can split MPI_COMM_WORLD accordingly
MPI_Comm binComm;
MPI_Comm_split( MPI_COMM_WORLD, binIdx, wRank, &binComm );
int bRank, bSize;
MPI_Comm_rank( binComm, &bRank );
MPI_Comm_size( binComm, &bSize );
printf( "Hello from process WORLD %d/%d running %d/%d %s binary\n",
wRank, wSize, bRank, bSize, argv[0] );
MPI_Comm_free( &binComm );
MPI_Finalize();
return 0;
}
On my machine, I compiled and ran it as follow:
~> mpicc mpmd.c
~> cp a.out b.out
~> mpirun -n 3 ./a.out : -n 2 ./b.out
Hello from process WORLD 0/5 running 0/3 ./a.out binary
Hello from process WORLD 1/5 running 1/3 ./a.out binary
Hello from process WORLD 4/5 running 1/2 ./b.out binary
Hello from process WORLD 2/5 running 2/3 ./a.out binary
Hello from process WORLD 3/5 running 0/2 ./b.out binary
Ideally, this could be greatly simplified by using MPI_Comm_split_type()
if the corresponding type for sorting out by binaries existed. Unfortunately, there is no such MPI_COMM_TYPE_
pre-defined in the 3.1 MPI standard. The only pre-defined one is MPI_COMM_TYPE_SHARED
to sort-out between processes running on the same shared memory compute nodes... Too bad! Maybe something to consider for the next version of the standard?
Since you are using Open MPI, there is a very simple OMPI-specific solution:
#include <stdlib.h>
MPI_Comm appcomm;
int app_id = atoi(getenv("OMPI_MCA_orte_app_num"));
MPI_Comm_split(MPI_COMM_WORLD, app_id, 0, &appcomm);
There will be now as many different appcomm
communicators as there are application contexts.
I know the question is outdated but I wanted to add to the answer by Hristo Lliev to make it work not just for OpenMPI:
you can use the value of an MPI parameter MPI_APPNUM which will be different for each executable as "color" and split the MPI_COMM_WORLD into separate communicators, then print the size of those sub-communicators. Use MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_APPNUM, &val, &flag ); to get the value of MPI_APPNUM.