5

我正在尝试使用 MPI 和 Fortran 来实现将位于同一节点上的进程与组分开。MPI 是否有可以识别的例程?

我的想法是通过它们的主机名来分隔这些进程,这在我正在使用的机器的节点上是相同的。但我不知道它是否适用于所有集群。

4

2 回答 2

7

您可能想查看 MPI_COMM_SPLIT_TYPE。它将允许您根据split_type作为参数传入的现有通信器拆分现有通信器:

int MPI_Comm_split_type(MPI_Comm comm, int split_type, int key,
                        MPI_Info info, MPI_Comm *newcomm)

现在,唯一的 split_type 是MPI_COMM_TYPE_SHARED,在标准中定义为:

这种类型将通信器拆分为子通信器,每个子通信器都可以创建一个共享内存区域。

这通常与您所要求的相同,但您必须在您的机器上仔细检查它是否属实。

您需要知道的另一件事是,这是 MPI-3 中的一个新功能,因此它可能不适用于所有 MPI 实现。我知道它可用于MPICH及其衍生产品。AFAIK,它在Open MPI的最新版本中不可用。因此,请确保您拥有真正支持它的 MPI 版本。

于 2013-08-08T16:33:51.083 回答
0

我已经为环境不提供 MPI 3.0 的系统实现了类似的拆分功能,并且它在多个集群上运行良好。它使用MPI_GET_PROCESSOR_NAME并依赖于大多数集群 MPI 实现作为结果返回节点的 FQDN 的事实 - 使用 Open MPI 和 Intel MPI(基于 MPICH,因此其他 MPICH 衍生产品预计会有类似的行为)进行测试。在伪代码中它是这样工作的:

rank := MPI_COMM_RANK(communicator)
prev_rank := rank - 1; IF (prev_rank < 0) prev_rank := MPI_PROC_NULL
next_rank := rank + 1; IF (next_rank >= num_procs) next_rank := MPI_PROC_NULL

proc_name := MPI_GET_PROCESSOR_NAME

list := MPI_RECV(from prev_rank)
IF (list does not contain proc_name) THEN
   list := list + proc_name
END IF

colour := index of proc_name in list
key := rank

MPI_SEND(list to next_rank)

MPI_COMM_SPLIT(communicator, colour, key, newcomm)

这段代码基本上构建了一个唯一的 MPI 处理器名称(主机名)列表,每个进程使用它的 MPI 处理器名称在这个列表中的位置作为通常拆分功能的颜色。在我的算法的 C 实现中,列表只是一个字符串 - 以零字节作为分隔符的所有项目的串联。在 Fortran 中,可以使用主机名中通常不允许使用的任何符号,例如;. MPI_CHAR然后将字符串简单地作为(C) 或MPI_CHARACTER(Fortran)的数组传递。

于 2013-08-11T14:45:11.660 回答