如何从拆分通信器中获取原始 mpi 等级

how to get the original mpi rank from split communicators

我把世界排名分给不同的传播者

    MPI_Comm_split(world_comm, color_, key_worker,
                   &color_comm_worker);
    MPI_Comm_split(world_comm, color_master, key_master, &color_comm_master);
  
    int color_worker_size, color_master_size;
    MPI_Comm_size(color_comm_worker, &color_worker_size);
    MPI_Comm_size(color_comm_master, &color_master_size);
  
    int color_worker_rank, color_master_rank;
    MPI_Comm_rank(color_comm_worker, &color_worker_rank);
    MPI_Comm_rank(color_comm_master, &color_master_rank);      

例如,对于 5 个等级,我会:

  world_rank : 1 color_worker : 1 color_master: 0 key_master: 1
  world_rank : 2 color_worker : 1 color_master: 1 key_master: 1
  world_rank : 3 color_worker : 1 color_master: 2 key_master: 1
  world_rank : 4 color_worker : 2 color_master: 0 key_master: 2
  world_rank : 0 color_worker : 0 color_master: 0 key_master: 0

如您所见,color_comm_master 有自己的排名编号,从 0 开始。 此通讯器中的排名 1 在世界通讯器中排名 2。如何通过知道split communicator的id来确定split rank在world communicator中的rank id?

让我们从包含等级 0 1 2 3 4 5 的通信器 A 开始

您已经知道 'color' 决定了哪些进程在哪个通信器中结束,因此如果我们为前三个进程提供一种颜色,为后三个进程提供不同的颜色,我们最终会得到两个通信器:

key 告诉 MPI 实现将进程放在新通信器中的什么位置。例如:

MPI_Comm_split(A, rank < (nprocs/2), nprocs-rank, &newcomm);

您最终会得到两个通信器:一些进程将在等级为 0 1 2 的通信器中,其他进程将在等级为 3 4 5 的通信器中

在这些新的通信器中,进程是如何分配等级的?按 'key' 排序。在这种情况下,我构建了一个键来将排名倒序排列。 Rank 0 的密钥为“6”,因此它现在在新的通信器中为 Rank 2。等级 5 的密钥为 0,因此在新的通信器中它现在为等级 0。

下面是一些您可以用来澄清的代码:

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

int main(int argc, char **argv) {
    int rank, new_rank, nprocs, new_nprocs;
    MPI_Comm newcomm;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    MPI_Comm_split(MPI_COMM_WORLD, rank < (nprocs/2), nprocs-rank, &newcomm);

    MPI_Comm_rank(newcomm, &new_rank);
    MPI_Comm_size(newcomm, &new_nprocs);

    printf("Hello from rank %d of %d (was rank %d of %d)\n",
            new_rank, new_nprocs, rank, nprocs);

    MPI_Comm_free(&newcomm);
    MPI_Finalize();
}