Это выполнимо, хотя и немного громоздко, чтобы получить это. Принцип состоит в том, чтобы разделить MPI_COMM_WORLD
на коммуникаторы на основе значения argv[0]
, которое содержит имя исполняемого файла.
Это может быть что-то вроде этого:
#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;
}
На моей машине, я собрал и запустил его следующим образом:
~> 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
В идеале это может быть значительно упрощается при использовании MPI_Comm_split_type()
, если соответствующий тип для сортировки по двоичным файлам. К сожалению, нет такого MPI_COMM_TYPE_
, предварительно определенного в стандарте 3.1 MPI. Единственным предопределенным является MPI_COMM_TYPE_SHARED
для сортировки между процессами, запущенными на одних и тех же узлах вычисления общей памяти ... Слишком плохо! Может быть, что-то рассмотреть для следующей версии стандарта?