节点如何在 OpenMPI 中通信

How nodes communicate in OpenMPI

我能够在 ssh 下的多个节点中 运行 OpenMPI 作业。一切看起来都很好,但我发现我对真正发生的事情知之甚少。那么,节点如何在 OpenMPI 中通信?它在多个节点中,因此不能共享内存。它似乎也不是 TCP 或 UDP,因为我没有配置任何端口。谁能描述在 2 个节点中的 2 个进程之间发送和接收消息时发生了什么?谢谢!

Open MPI 建立在称为模块化组件架构 (MCA) 的框架之上。有针对不同活动的框架,例如 point-to-point 通信、集体通信、并行 I/O、远程进程启动等。每个框架都实现为一组组件,这些组件提供相同 [=90] 的不同实现=] 接口.

每当第一次请求特定框架的服务时,例如字节传输层 (BTL) 或匹配传输层 (MTL) 的服务,这两者都在队列之间传输消息,MCA 枚举通过能够满足要求的各种组件并尝试实例化它们。一些组件有自己的特定要求,例如,需要特定的硬件存在,如果不满足则无法实例化。所有成功实例化的组件都会被打分,得分最高的组件将被选中来执行请求和其他类似的请求。因此,Open MPI 能够适应不同的环境,用户端的配置非常少。

对于不同级别之间的通信,BTL 和 MTL 框架提供了多种实现,并且该集合在很大程度上取决于 Open MPI 版本及其构建方式。 ompi_info 工具可用于查询库配置。这是我的一台机器的例子:

$ ompi_info | grep 'MCA [mb]tl'
                 MCA btl: openib (MCA v2.1.0, API v3.0.0, Component v2.1.1)
                 MCA btl: sm (MCA v2.1.0, API v3.0.0, Component v2.1.1)
                 MCA btl: tcp (MCA v2.1.0, API v3.0.0, Component v2.1.1)
                 MCA btl: vader (MCA v2.1.0, API v3.0.0, Component v2.1.1)
                 MCA btl: self (MCA v2.1.0, API v3.0.0, Component v2.1.1)
                 MCA mtl: psm (MCA v2.1.0, API v2.0.0, Component v2.1.1)
                 MCA mtl: ofi (MCA v2.1.0, API v2.0.0, Component v2.1.1)

此处列出的不同组件是:

  • openib -- 使用 InfiniBand 动词通过 InfiniBand 网络进行通信,这是当今最广泛的 high-performance 集群通信结构之一,以及其他 RDMA-capable 网络,例如 iWARP或 RoCE
  • sm -- 使用共享内存在同一个节点上通信
  • tcp -- 使用 TCP/IP 通过任何提供套接字接口的网络进行通信
  • vader -- 与sm类似,在同一节点上提供共享内存通信
  • self -- 提供高效的self-communication
  • psm -- 使用 PSM 库通过源自 PathScale 的 InfiniBand 变体的网络进行通信,例如 Intel Omni-Path (r.i.p.)
  • ofi -- 使用 OpenFabrics 接口 (OFI) 而不是动词的替代 InfiniBand 传输

hostA 上的等级 A 第一次想与 hostB 上的等级 B 交谈时,Open MPI 将检查模块列表。 self 只提供 self-communication 将被排除。 smvader 将被排除在外,因为它们仅在同一节点上提供通信。如果您的集群没有配备 high-performance 网络,最有可能保留的候选者是 tcp,因为实际上没有集群节点没有某种以太网连接。

tcp 组件探测所有启动的网络接口并记下它们的网络地址。它在所有端口上打开侦听 TCP 端口,并将此信息发布到中央存储库(通常由用于启动 MPI 程序的 mpiexec 进程管理)。当等级 A 中的 MPI_Send 调用请求 tcp 的服务以向等级 B 发送消息时,该组件查找等级 B 发布的信息和 select 的所有 IP 地址在 hostA 所属的任何网络中。然后它会尝试创建一个或多个 TCP 连接,成功后消息开始流动。

在大多数情况下,您不需要配置任何东西,tcp 组件 Just Works™。有时虽然它可能需要一些额外的配置。例如,默认的 TCP 端口范围可能被防火墙阻止,您可能需要告诉它使用不同的端口范围。或者它可能 select 网络接口具有相同的网络范围,但不提供物理连接 - 典型情况是各种管理程序或容器服务使用的虚拟接口。在这种情况下,您必须告诉 tcp 排除这些接口。

配置各种 MCA 组件是通过使用 mpiexec--mca param_name param_value command-line 参数传入 MCA 参数来完成的。您可以使用 ompi_info --param framework component 查询给定 MCA 组件具有的列表或参数及其默认值。例如:

$ ompi_info --param btl tcp
                 MCA btl: tcp (MCA v2.1.0, API v3.0.0, Component v2.1.1)
             MCA btl tcp: ---------------------------------------------------
             MCA btl tcp: parameter "btl_tcp_if_include" (current value: "",
                          data source: default, level: 1 user/basic, type:
                          string)
                          Comma-delimited list of devices and/or CIDR
                          notation of networks to use for MPI communication
                          (e.g., "eth0,192.168.0.0/16").  Mutually exclusive
                          with btl_tcp_if_exclude.
             MCA btl tcp: parameter "btl_tcp_if_exclude" (current value:
                          "127.0.0.1/8,sppp", data source: default, level: 1
                          user/basic, type: string)
                          Comma-delimited list of devices and/or CIDR
                          notation of networks to NOT use for MPI
                          communication -- all devices not matching these
                          specifications will be used (e.g.,
                          "eth0,192.168.0.0/16").  If set to a non-default
                          value, it is mutually exclusive with
                          btl_tcp_if_include.
             MCA btl tcp: parameter "btl_tcp_progress_thread" (current value:
                          "0", data source: default, level: 1 user/basic,
                          type: int)

参数有不同的级别,默认情况下ompi_info只显示级别1的参数(user/basic参数)。这可以使用 --level N 参数更改,以显示最高级别 N 的参数。级别一直到 9,只有在非常高级的情况下才需要更高级别的级别,例如 fine-tuning 库或调试问题。例如btl_tcp_port_min_v4btl_tcp_port_range_v4,串联使用指定TCP连接的端口范围,是2级参数(user/detail)。