根据标志对 mpi 进程进行分组
Group mpi process based on a flag
我需要基于更大的 mpi 通信器 (mpi_comm_world
) 创建一个子通信器 (mi_comm_world_2
)。
特别是在
这样的检测循环之后
如果 something
存在于过程中 proc
我需要在新的通信器中收集 mpi_comm_world_2 所有在检查方面标记为 true 的进程。
我无法找到明确的文档来完成这项工作。
问得好!
这就是 MPI_Comm_split 命令的用武之地。
定义
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
参数
comm: 通讯器的句柄 从
构建新的通讯器
color:一个非负整数,指示如何对新通信器中的进程进行分组。相同颜色的进程在同一个新的通信器中
key:一个控制rank分配的整数。排名总是从 0 到通信器中的进程数。该键决定了新通信器中进程等级的相对顺序。
newcomm: 新通讯器
int:函数returns一个整数表示是否成功。
更长的解释
在整个过程中请记住,您有许多进程在执行看似相同的代码。因此,newcomm
的值可能因进程而异。
color是一个整数值,决定了当前进程会落在哪个新的子通信器中。 comm
颜色具有相同数值的所有进程将属于同一个新的子通信器 newcomm
。
例如,如果您定义了 color = rank%4
(参见下面的示例 4),那么您将创建(全局)四个新的通信器。请记住,每个进程只会看到它所属的这些新通信器之一。换句话说,颜色决定了您要创建的 "teams",就像足球队的球衣颜色。
key 将确定进程在它们所属的新通信器中的排名方式。如果您设置 key = rank
,则每个新通讯器 newcomm
中的排名顺序(不是排名本身)将遵循原始通讯器 comm
中的排名顺序。如果 key 的两个或多个值具有相同的值,那么在 comm
中排名较低的进程在 newcomm
中排名较低。 (参见下面的示例 2。)
例子
这是我在下面的代码中复制的一些图片示例。示例 #5 回答了您的具体问题。
示例代码
//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();
}
更多信息
我需要基于更大的 mpi 通信器 (mpi_comm_world
) 创建一个子通信器 (mi_comm_world_2
)。
特别是在
这样的检测循环之后如果 something
存在于过程中 proc
我需要在新的通信器中收集 mpi_comm_world_2 所有在检查方面标记为 true 的进程。
我无法找到明确的文档来完成这项工作。
问得好!
这就是 MPI_Comm_split 命令的用武之地。
定义
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
参数
comm: 通讯器的句柄 从
构建新的通讯器
color:一个非负整数,指示如何对新通信器中的进程进行分组。相同颜色的进程在同一个新的通信器中
key:一个控制rank分配的整数。排名总是从 0 到通信器中的进程数。该键决定了新通信器中进程等级的相对顺序。
newcomm: 新通讯器
int:函数returns一个整数表示是否成功。
更长的解释
在整个过程中请记住,您有许多进程在执行看似相同的代码。因此,newcomm
的值可能因进程而异。
color是一个整数值,决定了当前进程会落在哪个新的子通信器中。 comm
颜色具有相同数值的所有进程将属于同一个新的子通信器 newcomm
。
例如,如果您定义了 color = rank%4
(参见下面的示例 4),那么您将创建(全局)四个新的通信器。请记住,每个进程只会看到它所属的这些新通信器之一。换句话说,颜色决定了您要创建的 "teams",就像足球队的球衣颜色。
key 将确定进程在它们所属的新通信器中的排名方式。如果您设置 key = rank
,则每个新通讯器 newcomm
中的排名顺序(不是排名本身)将遵循原始通讯器 comm
中的排名顺序。如果 key 的两个或多个值具有相同的值,那么在 comm
中排名较低的进程在 newcomm
中排名较低。 (参见下面的示例 2。)
例子
这是我在下面的代码中复制的一些图片示例。示例 #5 回答了您的具体问题。
示例代码
//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();
}