我正在尝试使用 MPI 和 Fortran 来实现将位于同一节点上的进程与组分开。MPI 是否有可以识别的例程?
我的想法是通过它们的主机名来分隔这些进程,这在我正在使用的机器的节点上是相同的。但我不知道它是否适用于所有集群。
我正在尝试使用 MPI 和 Fortran 来实现将位于同一节点上的进程与组分开。MPI 是否有可以识别的例程?
我的想法是通过它们的主机名来分隔这些进程,这在我正在使用的机器的节点上是相同的。但我不知道它是否适用于所有集群。
您可能想查看 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 版本。
我已经为环境不提供 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)的数组传递。