问题
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.
回答1:
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?
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/35924226/openmpi-mpmd-get-communication-size