Ein Interkommunikator zwischen zwei Gruppen (eine mit den ungeraden Rängen und eine mit den geraden) wird gebildet. Dann wird aus den Interkommunikator mittels MPI_Intercomm_merge wieder ein Intrakommunikator gebildet, in welchem alle Prozesse mit ursprünglich ungeraden Rängen vor denen mit ursprünglich geraden Rängen angeordnet sind.
#include "mpi.h"
#include <stdio.h>
#define NUMGROUPS 2
#define TAG 99
#define LEADER_EVEN 0 /* IDs der Leader-Procs innerhalb des */
#define LEADER_ODD 1 /* Parent-Communicator MPI_COMM_WORLD */
#define ROOT 0
int main(int argc, char *argv[]) {
int me, newID, newintraID, numprocs, groupsize, color, high;
int local_leader, remote_leader;
MPI_Status stat;
MPI_Comm newcomm, intercomm, newintracomm;
if (MPI_Init(&argc, &argv)!=MPI_SUCCESS) {
fprintf(stderr,"MPI_Init failed.\n");
return -1;
}
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
color=me%NUMGROUPS;
if ((me==numprocs-1)&&(color!=1)) {
color=MPI_UNDEFINED;
}
MPI_Comm_split(MPI_COMM_WORLD, color, me, &newcomm);
if (color!=MPI_UNDEFINED) {
MPI_Comm_rank(newcomm, &newID);
MPI_Comm_size(newcomm, &groupsize);
fprintf(stderr,"Proc %d: I'm now number %d in a group (%d) of %d.\n",
me, newID, color, groupsize);
MPI_Barrier(newcomm);
if (color==0) {
remote_leader=LEADER_ODD;
}
else {
remote_leader=LEADER_EVEN;
}
MPI_Intercomm_create(newcomm, ROOT, MPI_COMM_WORLD,
remote_leader, TAG, &intercomm);
if (color==0) {
/* ... irgendwas Nützliches erledigen ... */
high=1;
}
else {
/* ... irgendwas Nützliches erledigen ... */
high=0;
}
MPI_Intercomm_merge(intercomm, high, &newintracomm);
MPI_Comm_rank(newintracomm, &newintraID);
fprintf(stderr,"Proc %d (%d in group %d): I'm %d in newintracomm\n",
me, newID, color, newintraID);
/* ... irgendwas Nützliches mit newintracomm erledigen ... */
MPI_Comm_free(&newintracomm);
MPI_Comm_free(&intercomm);
MPI_Comm_free(&newcomm);
}
else {
fprintf(stderr,"Proc %d: I'm in no group.\n", me);
}
MPI_Finalize();
}
| Makefile | C-Quelltext |