mpi - Need help understanding MPI_Comm_create -


regarding mpi_comm_create, mpi standard says

mpi_comm_create(comm, group, newcomm)

... function collective , must called processes in group of comm.

i took mean that, instance, if comm argument mpi_comm_world, all processes must call mpi_comm_world.

however, wrote variation on code available on internet demonstrating use of mpi_comm_create. below. can see there 2 spots mpi_comm_create called, , not processes. , yet code runs fine.

did lucky? did stumble onto implementation-dependent feature? misunderstanding mpi standard? idea 2 calls result in calling mpi_comm_create "at end of day" it's ok? thanks. here's code:

#include <stdio.h> #include <stdlib.h> #include "mpi.h"   int main(int argc, char **argv) {     mpi_comm even_comm, odd_comm;    mpi_group even_group, odd_group, world_group;    int id, even_id, odd_id;    int *even_ranks, *odd_ranks;    int num_ranks, num_even_ranks, num_odd_ranks;    int err_mpi, i, j;    int even_sum, odd_sum;      err_mpi = mpi_init(&argc, &argv);    mpi_comm_size(mpi_comm_world, &num_ranks);    mpi_comm_rank(mpi_comm_world, &id);     mpi_comm_group(mpi_comm_world, &world_group);     num_even_ranks = (num_ranks+1)/2;    even_ranks = (int *)malloc(num_even_ranks*sizeof(int));    j=0;    (i=0; i<num_ranks; i++){       if (i%2 == 0) {          even_ranks[j] = i;          j++;       }    }      num_odd_ranks = num_ranks/2;    odd_ranks = (int *)malloc(num_odd_ranks*sizeof(int));    j=0;    (i=0; i<num_ranks; i++){       if (i%2 == 1) {          odd_ranks[j] = i;          j++;       }    }      if (id%2 == 0){       mpi_group_incl(world_group, num_even_ranks, even_ranks, &even_group);       // right here, procs not calling!       mpi_comm_create(mpi_comm_world, even_group, &even_comm);       mpi_comm_rank(even_comm, &even_id);       odd_id = -1;    } else {       mpi_group_incl(world_group, num_odd_ranks, odd_ranks, &odd_group);       // right here, procs not calling!       mpi_comm_create(mpi_comm_world, odd_group, &odd_comm);       mpi_comm_rank(odd_comm, &odd_id);       even_id = -1;    }     // have do, we'll ranks of    // various procs in each communicator.           if (even_id != -1) mpi_reduce(&id, &even_sum, 1, mpi_int, mpi_sum, 0, even_comm);    if (odd_id != -1) mpi_reduce(&id, &odd_sum, 1, mpi_int, mpi_sum, 0, odd_comm);     if (odd_id == 0) printf("odd sum: %d\n", odd_sum);    if (even_id == 0) printf("even sum: %d\n", even_sum);     mpi_finalize();  } 

although comm_create called 2 different lines of code, important point processes in comm_world calling comm_create @ same time. fact not same line of code not relevant - in fact, mpi library doesn't know comm_create being called from.

a simpler example calling barrier 2 branches; regardless of line executed, processes executing same barrier code work expected.

you rewrite code called same line: have variables called "num_ranks", "mycomm", "mygroup" , "myid" , array called "ranks" , set them equal or odd variables depending on rank. processes call:

mpi_group_incl(world_group, num_ranks, ranks, &mygroup); mpi_comm_create(mpi_comm_world, mygroup, &mycomm); mpi_comm_rank(mycomm, &myid); 

and if wanted reassign these afterwards, e.g.

if (id%2 == 0) even_comm = mycomm; 

Comments