10.1. 快速入门:启动MPI应用程序
尽管本节省略了许多细节,但它提供的示例很可能适用于多种环境。
警告
请注意,本节为“快速入门”——其目的并非详尽无遗,也不涵盖如何在所有支持的环境中构建Open MPI。因此,以下示例在您的实际环境中可能无法完全按所示方式运行。
如有必要,请查阅本章其他部分以获取更多详细信息。
10.1.1. 使用 mpirun 启动应用程序
Open MPI 同时支持 mpirun(1) 和 mpiexec(1)(两者完全等效)来 启动 MPI 应用程序。例如:
shell$ mpirun -n 2 mpi-hello-world
# or
shell$ mpiexec -n 2 mpi-hello-world
# or
shell$ mpiexec -n 1 mpi-hello-world : -n 1 mpi-hello-world
都是等效的。为简洁起见,本文档后续内容将统一使用mpirun。
10.1.1.1. 其他 mpirun 选项
mpirun 支持 --help 选项,该选项会显示使用说明及其支持选项的摘要。这应被视为提供选项的权威列表。
几个值得注意的选项包括:
--hostfile: 为需要指定启动并行应用程序的主机的启动器(如rsh启动器)指定主机文件。注意,为了与其他MPI实现兼容,–machinefile是--hostfile的同义词。--host: 指定运行的主机或主机列表(详情请参阅此FAQ条目)。-n: 指定要启动的进程数量。--mca: 设置MCA参数(详见如何设置MCA参数获取更多详情)。--wdir DIRECTORY: 设置启动应用程序的工作目录。如果未指定,则默认使用当前工作目录(如果当前工作目录在所有节点上不存在,则使用$HOME)。-x ENV_VARIABLE_NAME: 要导出到并行应用程序的环境变量名称。-x选项可以多次指定,以向并行应用程序导出多个环境变量。
10.1.2. 单机启动
在单台笔记本电脑或工作站上开发MPI应用是很常见的。在这种简单的"单程序多数据(SPMD)"场景中,使用mpirun(1)并通过-n选项指定要启动的MPI进程数量:
shell$ mpirun -n 6 mpi-hello-world
Hello world, I am 0 of 6 (running on my-laptop))
Hello world, I am 1 of 6 (running on my-laptop)
...
Hello world, I am 5 of 6 (running on my-laptop)
这将启动一个六进程并行应用程序,运行六个名为mpi-hello-world的可执行文件副本。
如果不指定-n选项,mpirun(1)默认会启动与机器处理器核心数(不包括超线程)相同的MPI进程。
10.1.3. 在非调度环境中启动(通过ssh)
通常,Open MPI需要满足以下条件才能启动和运行MPI应用程序:
您必须能够以非交互方式登录远程节点(例如,无需输入密码或口令)。
Open MPI的可执行文件必须能被找到(例如,在您的
PATH环境变量中)。必须能够找到Open MPI的库文件(例如,在您的
LD_LIBRARY_PATH环境变量中)。
mpirun(1) 接受一个 --hostfile 选项(及其同义词 --machinefile 选项),用于指定一个每行包含一个主机名的hostfile:
shell$ cat my-hostfile.txt
node1.example.com
node2.example.com
node3.example.com slots=2
node4.example.com slots=10
可选的slots属性告知Open MPI该节点可分配的最大进程数。如果未提供slots参数,Open MPI默认会使用该节点上的处理器核心数(不包括超线程)。
假设my-hostfile.txt中的4个节点每个都有16个核心:
shell$ mpirun --hostfile my-hostfile.txt mpi-hello-world
Hello world, I am 0 of 44 (running on node1.example.com)
Hello world, I am 1 of 44 (running on node1.example.com)
...
Hello world, I am 15 of 44 (running on node1.example.com)
Hello world, I am 16 of 44 (running on node2.example.com)
Hello world, I am 17 of 44 (running on node2.example.com)
...
Hello world, I am 31 of 44 (running on node2.example.com)
Hello world, I am 32 of 44 (running on node3.example.com)
Hello world, I am 33 of 44 (running on node3.example.com)
Hello world, I am 34 of 44 (running on node4.example.com)
...
Hello world, I am 43 of 44 (running on node4.example.com)
您可以查看Open MPI在每个节点上启动的进程数量明细:
节点1:16,因为未指定
slots节点2:16,因为未指定
slots参数节点3:2,因为指定了
slots=2节点2:10,因为指定了
slots=10
但请注意,并非所有环境都需要主机文件。例如,Open MPI在批处理/调度环境(如Slurm、PBS/Torque、SGE、LoadLeveler)中运行时能自动检测,并会使用这些系统提供的主机信息。
还需注意的是,如果使用需要主机文件(hostfile)的启动器但未指定主机文件,则所有进程都将在本地主机上启动。
10.1.4. 在调度环境中启动
在调度环境中(例如Slurm作业、PBS/Pro、LSF或其他任何调度系统),用户会告知调度器需要启动多少个MPI进程,而调度器则决定使用哪些主机。随后,调度器会将这两部分信息(进程数量和要使用的主机)传递给Open MPI。
在调度环境中启动有两种方式。从名义上看,它们都能实现相同的目标:启动MPI进程。这两种方法对用户而言的主要区别在于,mpirun(1)比调度器直接启动器提供了更多功能特性。
10.1.4.1. 使用Open MPI的mpirun(1)
注意
从技术上讲,Open MPI的mpirun(1)是PRRTE prun的一个薄封装层。因此,这里描述的大部分功能实际上都是关于prun的。不过为了简单起见,本文档将统一使用mpirun的术语来描述所有内容。
在计划任务环境中使用功能齐全的mpirun(1)时,无需指定主机文件或要启动的MPI进程数量。mpirun(1)将直接从调度器获取这些信息。因此,如果您想启动一个完全"填满"计划分配的MPI作业(即计划分配中的每个槽位对应一个MPI进程),您只需:
# Write a script that runs your MPI application
shell$ cat my-slurm-script.sh
#!/bin/sh
# There is no need to specify -n or --hostfile because that
# information will automatically be provided by Slurm.
mpirun mpi-hello-world
然后你将my-slurm-script.sh脚本提交给Slurm执行:
# Use -n to indicate how many MPI processes you want to run.
# Slurm will pick the specific hosts which will be used.
shell$ sbatch -n 40 my-slurm-script.sh
Submitted batch job 1234
shell$
Slurm作业1234完成后,您可以查看输出文件了解执行情况:
shell$ cat slurm-1234.out
Hello world, I am 0 of 40 (running on node37.example.com)
Hello world, I am 1 of 40 (running on node37.example.com)
Hello world, I am 2 of 40 (running on node37.example.com)
...
Hello world, I am 39 of 40 (running on node19.example.com)
请注意,Slurm调度器选择了运行进程的主机。
上述示例表明,仅调用mpirun
mpi-hello-world——不添加其他命令行选项——即可从调度器获取要运行的进程数量和使用的主机信息。
mpirun(1) 拥有许多本快速入门章节未提及的功能。例如,虽然在调度环境中不常见,但您可以使用 -n 和/或 --hostfile 在整个调度分配的子集中启动。更多详情请参阅 mpirun(1) 手册页。
10.1.4.2. 使用调度器进行"直接启动"(无需mpirun(1))
某些调度器(如Slurm)具备"直接启动"MPI进程的能力,无需使用Open MPI的mpirun(1)。例如:
shell$ srun -n 40 mpi-hello-world
Hello world, I am 0 of 40 (running on node14.example.com)
Hello world, I am 1 of 40 (running on node14.example.com)
Hello world, I am 2 of 40 (running on node14.example.com)
...
Hello world, I am 39 of 40 (running on node203.example.com)
shell$
与前面的例子类似,这个例子启动了40份mpi-hello-world,但它是通过Slurm的srun命令完成的,而没有使用mpirun(1)。