#include #include #include #include int main( int argc, char *argv[] ) { int np = 1; int errcodes[2]; int world_rank, world_size; MPI_Comm parent_comm, spawn_comm; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); MPI_Comm_get_parent( &parent_comm ); if (MPI_COMM_NULL == parent_comm && world_size != 2) { fprintf(stderr, "Must run with two processes\n"); MPI_Abort(MPI_COMM_WORLD, 1); } if (parent_comm == MPI_COMM_NULL) MPI_Comm_spawn((char*)"./a.out", MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_SELF, &spawn_comm, errcodes); else spawn_comm = parent_comm; if(spawn_comm != MPI_COMM_NULL) { int high, intra_rank, intra_size, leader; MPI_Comm intra_comm, inter_comm, univ_comm; if(parent_comm == MPI_COMM_NULL) high = 0; else high = 1; /* Merge each intercomm between the spawned groups into an intracomm: */ MPI_Intercomm_merge(spawn_comm, high, &intra_comm); MPI_Comm_rank(intra_comm, &intra_rank); MPI_Comm_size(intra_comm, &intra_size); /* Determine the leader (rank 0 & 1 of the origin world): */ if (parent_comm == MPI_COMM_NULL) { leader = (world_rank+1) % 2; MPI_Send(&leader, 1, MPI_INT, 1, 0, intra_comm); } else MPI_Recv(&leader, 1, MPI_INT, 1, 0, intra_comm, MPI_STATUS_IGNORE); /* Create an intercomm between the two merged intracomms (and use the origin world as bridge/peer communicator): */ MPI_Intercomm_create(intra_comm, 0, MPI_COMM_WORLD, leader, 123, &inter_comm); /* Try a Barrier on this intercomm: */ MPI_Barrier(inter_comm); /* Merge this intercomm into a 'universe' intracomm that covers all procs: */ MPI_Intercomm_merge(inter_comm, 0, &univ_comm); /* Try a Barrier on this intracomm: */ MPI_Barrier(univ_comm); MPI_Comm_free(&univ_comm); MPI_Comm_free(&inter_comm); MPI_Comm_free(&intra_comm); MPI_Comm_free(&spawn_comm); } MPI_Finalize(); return 0; }