Slurm环境下OpenMPI跨多节点运行MPI程序报错问题咨询
OpenMPI搭配Slurm运行MPI并行程序报错排查
问题背景
基于OpenMPI + Slurm调度系统运行MPI Hello World并行程序,通过#SBATCH作业脚本提交任务,环境配置如下:
.bashrc中配置PATH与LD_LIBRARY_PATH环境变量,包含路径/shared/centos7/openmpi/3.1.2/bin- 通过module工具加载openmpi与cuda/9.2环境
测试现象
- 作业脚本中使用
srun ~/hello-mpi.x运行:输出符合预期,共分配c0625、c0626两个计算节点,启动32个进程,与脚本配置的2节点、每节点16任务参数完全匹配,进程输出内容正常。 - 作业脚本中改用
mpirun ~/hello-mpi.x运行:触发ORTE守护进程通信失败报错,报错内容如下:
An ORTE daemon has unexpectedly failed after launch and before
communicating back to mpirun. This could be caused by a number
of factors, including an inability to create a connection back
to mpirun due to a lack of common network interfaces and/or no
route found between them. Please check network connectivity
(including firewalls and network routing requirements).
- 作业脚本中使用
srun mpirun ~/hello-mpi.x运行:触发报错slurmstepd: error: execve(): mpirun: No such file or directory。 - 交互命令行补充测试:未通过salloc申请多节点资源时,直接在登录节点命令行运行mpirun或srun,仅能在单节点运行输出结果,共启动4个进程;若直接运行
srun mpirun ~/hello-mpi.x,同样触发上述mpirun找不到的报错。
相关配置与代码
1. SBATCH作业脚本
#!/bin/bash #SBATCH --verbose #SBATCH --export=ALL #SBATCH --nodes=2 #SBATCH --ntasks-per-node=16 #SBATCH --cpus-per-task=1 #SBATCH --time=00:10:00 #SBATCH --job-name=JonsJob #SBATCH --mem=100G #SBATCH --partition=short srun ~/hello-mpi.x
2. MPI Hello World程序代码
/* The Parallel Hello World Program */ #include <stdio.h> #include <mpi.h> int main(int argc, char *argv[]) { int rank, size, namelen; char processor_name[MPI_MAX_PROCESSOR_NAME]; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Get_processor_name(processor_name, &namelen); printf("Hello World from process %d from the Node %s. There are a total of %d processes.\n", rank, processor_name, size); MPI_Finalize(); return 0; }
3. .bashrc配置内容
# .bashrc # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi module load openmpi module load cuda/9.2
根本原因分析
mpirun: No such file or directory报错原因:Slurm通过srun向计算节点派发任务时,默认不启动交互式登录shell流程,.bashrc内写的module加载逻辑仅在用户交互式登录节点时生效,计算节点执行srun下发的任务时不会自动加载openmpi相关环境变量,因此系统无法找到mpirun可执行文件。- 直接在作业脚本运行mpirun触发ORTE守护进程失败的原因:当前环境安装的OpenMPI 3.1.2未正确编译Slurm PMI/PMIx支持组件,mpirun无法对接Slurm的调度接口完成跨节点进程拉起、通信地址交换,只能尝试通过原生TCP自主建立跨节点连接;而集群计算节点间通常会限制非调度系统触发的跨节点业务端口通信,或mpirun无法识别节点间的高速互联网卡,最终导致ORTE守护进程无法和主mpirun进程建立通信,触发报错。
- 登录节点直接运行mpirun/srun仅启动4个进程为预期行为:未通过salloc/sbatch申请Slurm多节点资源时,srun和mpirun都只能识别当前登录节点的本地资源,无法跨节点调度进程。
可行解决方案
- 首选方案:直接使用
srun运行MPI程序。这是Slurm环境下兼容性、稳定性最高的运行方式,当前测试中srun ~/hello-mpi.x已经可以严格按照作业申请的2节点、每节点16核配置拉起32个跨节点进程,输出完全正常,不需要额外嵌套调用mpirun。需要调整MPI运行参数时,直接把参数加在srun命令后即可。 - 若因业务需求必须使用
mpirun启动,按以下步骤调整:- 不要依赖
.bashrc自动加载环境,在作业脚本的执行命令前,显式加载所需环境,避免计算节点环境缺失:# 在所有SBATCH参数后、执行启动命令前追加以下内容 source /etc/profile module load openmpi module load cuda/9.2 # 兜底显式写路径,避免module加载异常 export PATH=/shared/centos7/openmpi/3.1.2/bin:$PATH export LD_LIBRARY_PATH=/shared/centos7/openmpi/3.1.2/lib:$LD_LIBRARY_PATH - 启动mpirun时追加Slurm适配参数,强制对接Slurm调度能力,命令示例:
其中mpirun --mca plm slurm --mca btl_tcp_if_include <集群计算节点内部通信网卡网段> ~/hello-mpi.x--mca plm slurm指定mpirun使用Slurm进程管理模块拉起跨节点进程,不需要自己通过ssh到计算节点启动守护进程;--mca btl_tcp_if_include后面替换为集群计算节点内部通信的网卡对应网段(比如10.0.0.0/16),避免mpirun错误选到登录管理网卡导致通信失败。如果集群使用InfiniBand网络,可以去掉TCP相关参数,追加--mca btl openib,self,vader指定使用IB传输层。 - 禁止使用
srun mpirun的嵌套启动写法:这种写法会让Slurm在每个分配到的CPU槽位先启动一个mpirun进程,每个mpirun再独立拉起子进程,会导致进程数翻倍、调度冲突、通信死锁等问题,完全不符合Slurm的资源调度逻辑。
- 不要依赖
内容的提问来源于stack exchange,提问作者Jonathan Sullivan
相关产品推荐
相关产品推荐

