3
votes

I would like to be able to get a unique id for a certain communicator but this seems an impossible task when you get this communicator by a MPI_Comm_split() call. I know when MPI_Comm_split() is called collectively each of the resulting disjoint communicators has the same context ID yet different group information. I expected by calling MPI_Comm_group(), the group handler associated to a certain communicator would be different for each communicator created by the split, but is the same in all of them!

[CODE]

#include <mpi.h>
#include <stdio.h>

int main() {
    MPI_Init(NULL, NULL);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm split_comm;
    MPI_Comm_split(MPI_COMM_WORLD, rank / 3, rank, &split_comm);
    int split_rank;
    MPI_Group split_group;
    MPI_Comm_group(split_comm, &split_group);
    MPI_Comm_rank(split_comm, &split_rank);
    printf("rank: %d| comm: %u, group: %u\n", split_rank, split_comm, split_group);
}

If one runs the code above with mpirun -np 6 ./exec the result is:

rank: 0| comm: 2214592516, group: 2281701376
rank: 1| comm: 2214592514, group: 2281701376
rank: 2| comm: 2214592514, group: 2281701376
rank: 0| comm: 2214592514, group: 2281701376
rank: 1| comm: 2214592514, group: 2281701376
rank: 2| comm: 2214592514, group: 2281701376

So it makes impossible to identify which of the two communicators a process belongs to.

Is there any way of getting an id which identifies uniquely a communicator?

2
Post your code so we can have a lookMarco Ferrari
I have added a piece of code that hopefully clarifies my question.Eduardo R.
Are you sure the output corresponds to the code and the execution command line? I wouldn't expect split_rank to go from 0 to 5...Gilles
Yes, sorry. I had one line wrong. Now it should be alright but the situation is the same with groups and communicator handles.Eduardo R.
MPI uses opaque objects - they are intentionally hidden from the application. What you have is only a handle, you should not rely on any semantics of that handle except using it in API calls. What do you actually intend to do with that information. How would you define a 'unique communicator' among all ranks in the program?Zulan

2 Answers

1
votes

As noted in the comments, you have no control over the value MPI sets for its COMMs. You can however set the comm name as follows,

#include <mpi.h>
#include <stdio.h>
#include <iostream>

int main() {

    MPI_Init(NULL, NULL);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm split_comm;
    int colour = rank/3;
    MPI_Comm_split(MPI_COMM_WORLD, colour, rank, &split_comm);

    // Define string from split colour and use to set comm name
    std::string name = "Comm-";
    name += std::to_string(colour);
    const char * commname = name.c_str();
    MPI_Comm_set_name(split_comm, commname);

    int split_rank;
    MPI_Group split_group;
    MPI_Comm_group(split_comm, &split_group);
    MPI_Comm_rank(split_comm, &split_rank);

    //Retrieve commname and print
    int rlen;
    char nameout[MPI_MAX_OBJECT_NAME];
    MPI_Comm_get_name(split_comm, nameout, &rlen);
    printf("rank: %d| comm: %u, comm_name: %s, group: %u\n", split_rank, split_comm, nameout, split_group);
}

where the output for your mpirun -np 6 ./exec example is,

rank: 0| comm: 2214592516, comm_name: Comm-0, group: 2281701376
rank: 1| comm: 2214592514, comm_name: Comm-0, group: 2281701376
rank: 2| comm: 2214592514, comm_name: Comm-0, group: 2281701376
rank: 0| comm: 2214592514, comm_name: Comm-1, group: 2281701376
rank: 1| comm: 2214592514, comm_name: Comm-1, group: 2281701376
rank: 2| comm: 2214592514, comm_name: Comm-1, group: 2281701376

This may solve the problem?

0
votes

As mentioned, there is no (portable) way to access the MPI internals. And I woudln't even count on it that there is something exactly like you need.

To handle this generically, you can wrap all mpi communicator management functions using the "PMPI" profiling interface (See MPI Standard 14.2. for Details). Whenever a new communicator is generated, you then store information about it locally in each process and assign it a locally incremented counter value. You can then use PMPI_Comm_group, PMPI_Group_size and PMPI_Group_translate_ranks to get the member processes. Together, the increment counter of the group member with the lowest global rank and the member array uniquely identify the communicator in a global sense. For inter-communicators it is a bit more tricky.