17

比如说,我使用 MPI 运行一个并行程序。执行命令

mpirun -n 8 -npernode 2 <prg>

共启动 8 个进程。即每个节点 2 个进程,总共 4 个节点。(OpenMPI 1.5)。其中一个节点包含 1 个 CPU(双核)并且节点之间的网络互连是 InfiniBand。

现在,可以通过以下方式确定等级编号(或进程编号)

int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

这将返回一个介于 0 和 7 之间的数字。

但是,如何确定节点号(在本例中为 0 到 3 之间的数字)和节点内的进程号(0 到 1 之间的数字)?

4

4 回答 4

18

我相信您可以通过 MPI-3 以这种方式实现这一目标:

MPI_Comm shmcomm;
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0,
                    MPI_INFO_NULL, &shmcomm);
int shmrank;
MPI_Comm_rank(shmcomm, &shmrank);
于 2016-10-19T05:15:49.177 回答
11

这取决于 MPI 的实现——对于这个特定的问题没有标准。

Open MPI 有一些环境变量可以提供帮助。OMPI_COMM_WORLD_LOCAL_RANK 将为您提供节点内的本地排名 - 即。这是您要查找的进程号。因此,调用 getenv 将回答您的问题 - 但这不能移植到其他 MPI 实现

有关OpenMPI 中变量的(短)列表,请参阅此内容。

我不知道相应的“节点号”。

于 2012-01-29T10:24:51.483 回答
3

这个确切的问题在 Markus Wittmann 的博客MPI Node-Local Rank 确定中进行了讨论。

在那里,提出了三种策略:

  1. 一个简单的、可移植的解决方案使用 MPI_Get_processor_name 或 gethostname 为节点创建唯一标识符并在其上执行 MPI_Alltoall。[...]
  2. [方法2]依赖于MPI_Comm_split,它提供了一种将通信器拆分为子组(子通信器)的简单方法。[...]
  3. 如果可用,可以使用共享内存。[...]

对于一些工作代码(大概是 LGPL 许可?),Wittmann 链接到来自APSM 库的MpiNodeRank.cpp

于 2015-08-03T16:40:58.537 回答
0

或者,您可以使用

int MPI_Get_processor_name( char *name, int *resultlen )

检索节点名称,然后将其用作颜色

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

这并不像 一样简单MPI_Comm_split_type,但是它提供了更多的自由来按照您想要的方式拆分您的通信器。

于 2018-05-25T09:12:37.010 回答