【问题标题】:Group mpi process based on a flag基于标志对 mpi 进程进行分组
【发布时间】:2019-05-09 21:56:01
【问题描述】:

我需要基于更大的 mpi 通信器 (mpi_comm_world) 创建一个子通信器 (mi_comm_world_2)。

尤其是在一个检测循环之后,比如

如果something 存在于过程中proc

我需要在新的通信器 mpi_comm_world_2 中收集与检查相关的所有标记为 true 的过程。

我找不到明确的文档来完成这项工作。

【问题讨论】:

  • 这是MPI_Comm_split()的教科书定义。如果您不需要将 MPI 任务标记为 false 的通信器,请使用 MPI_UNDEFINED 作为颜色

标签: parallel-processing mpi hpc


【解决方案1】:

好问题!

这就是MPI_Comm_split 命令的用处。

定义

int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)

参数

  • comm:处理您想要构建新通信器的通信器

  • color:一个非负整数,指示如何对新通信器中的进程进行分组。相同颜色的进程在同一个新的通信器中

  • key:控制排名分配的整数。排名总是从 0 分配给通信器中的进程数。键决定了进程在新通信器中排名的相对顺序。

  • newcomm:新的沟通者

  • int:函数返回一个整数,表示是否成功。

更长的解释

在整个过程中请记住,您有许多进程在执行看似相同的代码。因此,newcomm 的值可能因进程而异。

color 是一个整数值,用于确定当前进程将落在哪个新的子通信器中。 comm 的所有颜色具有相同数值的进程都将成为同一个新子通信器newcomm 的一部分。

例如,如果您定义了color = rank%4(参见下面的示例 4),那么您将(全局)创建四个新的通信器。请记住,每个进程只会看到它所属的这些新通信器之一。换句话说,颜色决定了您将创建哪些“球队”,例如足球队的球衣颜色。

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();
}

更多信息

  • This page 有一个很好的关于沟通者和群组的教程。
  • 我为示例开发的 SVG 文件可用here

【讨论】:

  • 感谢您的详细解答。这对我帮助很大。谁应该执行拆分?原始通讯器上的每个等级?如果排名在拆分前终止会怎样?
  • @nico 拆分命令必须由要拆分的通信器上的每个进程运行。等级不应该提前终止:它们应该一起终止。
猜你喜欢
  • 1970-01-01
  • 2017-03-09
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多