openmpi mpirun v1.8 中 --map-by 选项的语法

Syntax of the --map-by option in openmpi mpirun v1.8

查看以下摘自 openmpi manual

--map-by <foo>
    Map to the specified object, defaults to socket. Supported options
    include slot, hwthread, core, L1cache, L2cache, L3cache, socket, 
    numa, board, node, sequential, distance, and ppr. Any object can 
    include modifiers by adding a : and any combination of PE=n (bind n
    processing elements to each proc), SPAN (load balance the processes 
    across the allocation), OVERSUBSCRIBE (allow more processes on a node
    than processing elements), and NOOVERSUBSCRIBE. This includes PPR,
    where the pattern would be terminated by another colon to separate 
    it from the modifiers.

我对语法有不同的疑问,并对它们有一些评论:

尤其是ppr让我很困惑。它的缩写是什么?

当然,我可以通过查看报告的 --report-bindings 绑定来查看前一个选项的结果(只有 4 个进程映射到一个套接字上,默认情况下绑定到一个套接字的 4 个核心),但我无法理解语法。在手册的另一行,它说这个新选项取代了 --npersocket:

的弃用用法
-npersocket, --npersocket <#persocket>
    On each node, launch this many processes times the number of processor
    sockets on the node. The -npersocket option also turns on the -bind-
    to-socket option. (deprecated in favor of --map-by ppr:n:socket) 

ppr 表示每个资源 个进程 。它的语法是ppr:N:resource,意思是"assign N processes to each resource of type resource available on the host"。例如,在具有 6 核 CPUs 的 4 插槽系统上具有 --map-by ppr:4:socket 结果如下过程图:

 socket   ---- 0 ----    ---- 1 ----    ---- 2 ----    ---- 3 ----
 core     0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5
 process  A B C D        E F G H        I J K L        M N O P

(在此示例中,进程编号从 A 运行到 Z

手册的意思是整个ppr:N:resource被视为一个单一的说明符,可以在其后添加选项,以:分隔,例如ppr:2:socket:pe=2。这应该读作 "start two processes per each socket and bind each of them to two processing elements" 并且在给定相同的四插槽系统的情况下应该产生以下映射:

 socket   ---- 0 ----    ---- 1 ----    ---- 2 ----    ---- 3 ----
 core     0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5
 process  A A B B        C C D D        E E F F        G G H H

sequential 映射器逐行读取主​​机文件,并为在那里找到的每个主机启动一个进程。如果给定,它会忽略插槽计数。

dist 映射器根据 NUMA 节点与给定 PCI 资源的距离映射进程。它只在 NUMA 系统上有意义。同样,让我们​​使用玩具四路系统,但这次扩展表示以显示 NUMA 拓扑:

 Socket 0 ------------- Socket 1
    |                      |
    |                      |
    |                      |
    |                      |
    |                      |
 Socket 2 ------------- Socket 3
    |
   ib0

插座之间的线条代表 CPU links。那些是,例如Intel CPUs 的 QPI links 和 AMD CPUs 的 HT links。 ib0 是用于与其他计算节点通信的 InfiniBand HCA。现在,在该系统中,Socket 2 直接与 InfiniBand HCA 对话。 Socket 0 和 Socket 3 必须跨越一个 CPU link 才能与 ib0 通信,而 Socket 1 必须跨越 2 CPU link。这意味着,Socket 2 上的进程 运行 将具有尽可能低的延迟,而 Socket 1 上发送和接收消息的进程将具有尽可能高的延迟。

它是如何工作的?如果您的主机文件指定例如该主机上的 16 个插槽和映射选项是 --map-by dist:ib0,它可能会导致以下映射:

 socket   ---- 0 ----    ---- 1 ----    ---- 2 ----    ---- 3 ----
 core     0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5
 process  G H I J K L                   A B C D E F    M N O P

6 个进程映射到最靠近 InfiniBand HCA 的 Socket 2,然后再映射 6 个进程到第二近的 Socket 0,再映射 4 个进程到 Socket 3。也可以分散进程而不是线性填充处理元素。 --map-by dist:ib0:span 结果:

 socket   ---- 0 ----    ---- 1 ----    ---- 2 ----    ---- 3 ----
 core     0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5    0 1 2 3 4 5
 process  E F G H        M N O P        A B C D        I J K L

实际的NUMA拓扑是使用hwloc库获得的,它读取BIOS提供的距离信息。 hwloc 包括一个名为 hwloc-ls(也称为 lstopo)的命令行工具,可用于显示系统的拓扑结构。通常它仅在其输出中包括处理元素的拓扑结构和 NUMA 域,但如果您为其提供 -v 选项,它还包括 PCI 设备。