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
Post a Comment