Kranthi Kumar
Kranthi Kumar

Reputation: 1264

How to know the all the ranks of the processor that are part of a communicator in MPI?

Is there anyway through which I can know all the processes that are part of communicator? Suppose there are totally 16 MPI processes and MPI_Comm comm has 4 processes as a group. Given just the communicator comm can we know all the ranks of the processes that are part of the communicator?

Thank You

Upvotes: 1

Views: 2011

Answers (1)

Hristo Iliev
Hristo Iliev

Reputation: 74475

Each communicator has an associated process group, obtainable by calling MPI_COMM_GROUP (MPI_Comm_group in the C bindings). Once the process group for comm was obtained, one can use MPI_GROUP_TRANSLATE_RANKS to translate the list of ranks in the group of comm to the corresponding ranks in the group of MPI_COMM_WORLD. One has to go through the translation process, because inside the group of comm, participating processes has ranks ranging from 0 to MPI_COMM_SIZE(comm)-1.

Here is a sample implementation:

void print_comm_ranks(MPI_Comm comm)
{
   MPI_Group grp, world_grp;

   MPI_Comm_group(MPI_COMM_WORLD, &world_grp);
   MPI_Comm_group(comm, &grp);

   int grp_size;

   MPI_Group_size(grp, &grp_size);

   int *ranks = malloc(grp_size * sizeof(int));
   int *world_ranks = malloc(grp_size * sizeof(int));

   for (int i = 0; i < grp_size; i++)
      ranks[i] = i;

   MPI_Group_translate_ranks(grp, grp_size, ranks, world_grp, world_ranks);

   for (int i = 0; i < grp_size; i++)
      printf("comm[%d] has world rank %d\n", i, world_ranks[i]);

   free(ranks); free(world_ranks);

   MPI_Group_free(&grp);
   MPI_Group_free(&world_grp);
}

Here is a sample usage:

int rank;
MPI_Comm comm;

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_split(MPI_COMM_WORLD, rank % 2, rank, &comm);

if (rank == 0)
{
   printf("Rank 0 view:\n");
   print_comm_ranks(comm);
}
else if (rank == 1)
{
   printf("Rank 1 view:\n");
   print_comm_ranks(comm);
}

and the corresponding output with 7 processes:

Rank 0 view:
comm[0] has world rank 0
comm[1] has world rank 2
comm[2] has world rank 4
comm[3] has world rank 6
Rank 1 view:
comm[0] has world rank 1
comm[1] has world rank 3
comm[2] has world rank 5

(ranks 0 and 1 end up in different communicators after the split)

Note that you can only enumerate the contents of a communicator that the current process knows about, because communicators are referred by their handles and those are local values to each process.

Upvotes: 5

Related Questions