Reputation: 85
I need to create a sub-communicator (mi_comm_world_2
) based on a bigger mpi communicator (mpi_comm_world
).
In particular, after a detection loop such as
if something
exists inside the proc proc
I need to collect in the new communicator mpi_comm_world_2 all the process flagged as true in respect of the check.
I am not able to find a clear documentation in order to do this job.
Upvotes: 3
Views: 765
Reputation: 61289
Good question!
This is what the MPI_Comm_split command is good for.
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
comm: Handle to the communicator you want to want build the new communicator from
color: A nonnegative integer indicating how to group the processes in the new communicators. Processes with the same color are in the same new communicator
key: An integer that controls rank assignment. Ranks are always assigned from 0 to the number of processes in the communicator. The key determines the relative ordering of the processes' ranks in the new communicator.
newcomm: The new communicator
int: The function returns an integer indicating whether it was successful or not.
Throughout this bear in mind that you have many processes executing what appears to be the same code. As such, the value of newcomm
can differ between processes.
color is an integer value that determines in which of the new sub-communicators the current process will fall. All processes of comm
for which color has the same numerical value will be part of the same new sub-communicator newcomm
.
For example, if you defined color = rank%4
(see Example 4, below), then you would create (globally) four new communicators. Keep in mind that each process will only be seeing the one of these new communicators which it is part of. Put another way, color determines which the "teams" you will create, like the jersey color of football teams.
key will determines how processes are ranked within the new communicators they are part of. If you set key = rank
, then the order of ranking (not the ranking itself) in each new communicator newcomm
will follow the order of ranking in the original communicator comm
. If two or more values of key have the same value, then the process that had the lower rank in comm
has the lower rank in newcomm
. (See Example 2, below.)
Here are a few pictorial examples which I duplicate in code below. Example #5 answers your specific question.
//Compile with mpic++ main.cpp
#include <mpi.h>
int main(int argc, char **argv){
int world_size, world_rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &world_size); //Get the number of processes
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); //Get the rank of the process
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Comm newcomm1, newcomm2, newcomm3, newcomm4, newcomm5;
//Example 1: Duplicate the existing communicator. The command `MPI_Comm_dup()`
// does exactly this.
MPI_Comm_split(comm, 0, world_rank, &newcomm1);
//Example 2: Duplicate the existing communicator, but reverse the
// rankings
MPI_Comm_split(comm, 0, world_size-world_rank, &newcomm2);
int rank2; //Get the rank of the process
MPI_Comm_rank(newcomm2, &rank2); //in the new communicator
//Example 3: Split each process into its own communicator. This is the
// equivalent of using `MPI_COMM_SELF` for each process.
MPI_Comm_split(comm, world_rank, world_rank, &newcomm3);
//Example 4: Split processes into communicators based on their colouring. Use
// their rank in the existing communicator to determine their
// relative rank order in the new communicator.
int color = world_rank / 4;
MPI_Comm_split(comm, color, world_rank, &newcomm4);
int rank4; //Get the rank of the process
MPI_Comm_rank(newcomm2, &rank4); //in the new communicator
//Example 5: Group only some of the processes into a new communicator based on
//a flag.
int flag = world_rank%2==0; //An example flag
MPI_Comm_split(comm, flag?0:MPI_UNDEFINED, world_rank, &newcomm5);
MPI_Finalize();
}
Upvotes: 3