跳转至

MPI 集成现状与实测报告(OpenMPI 4.1.5 × Slurm 26.05.2)

测试日期:2026-09-12|测试方式:真实集群提交 MPI 作业(非推演) 测试节点:k8s-node-01(16 核)|提交用户:rain01(非 root) 触发背景:为配置 MpiDefault 而核实现有 MPI 与 Slurm 的集成方式


一、模块系统勘察(module av)

本集群用 Lmod 管理环境(/etc/profile.d/lmod.sh),modulefiles 路径 /mnt/nfs/slurm/modules。

$ module av
--------------------------- /mnt/nfs/slurm/modules ----------------------------
   Cadence/IC617        gcc/7.5.0                   openmpi/4.1.5
   Keysight/Ads/2025    gcc/12.1.0           (D)    python/pyenv
   bio/vina/1.1.2       global_env/slurm_env        spectre/151
  Where:
   D:  Default Module

MPI 实现唯一一个:openmpi/4.1.5

项 值
模块名 openmpi/4.1.5
安装路径 /mnt/nfs/slurm/opt/openmpi-4.1.5
依赖 gcc/12.1.0(modulefile 内 load("gcc/12.1.0") 自动加载)
编译器 mpicc / mpicxx / mpif90 齐备
PMIx 内置 pmix3x(不依赖外部 PMIx 库)
modulefile 位置 /mnt/nfs/slurm/modules/openmpi/4.1.5.lua(另有 .lua.bak.20260813 旧版)

注意:该目录下曾并存两个版本的 modulefile 内容,生效的是 4.1.5.lua(新版)。 新版明确写明:"不使用 OMPI_MCA_pmix=pmix(无效值);不设置时 OMPI 自动选择 pmix3x 组件", 而旧版(.bak.20260813)恰恰设置了 OMPI_MCA_pmix=pmix。 若误用旧版会触发模块组件查找失败,排查时需先确认生效版本:module show openmpi/4.1.5。


二、Slurm 侧支持能力(决定性证据)

$ srun --mpi=list
MPI plugin types are...
        none
        cray_shasta
        pmi2
$ ls /usr/local/slurm/lib/slurm/ | grep ^mpi_
mpi_cray_shasta.so
mpi_pmi2.so

结论:本集群 Slurm 仅编译了 none / cray_shasta / pmi2 三种 MPI 插件,未编译 pmix。 MpiDefault 的合法取值因此只能是这三者之一(对 OpenMPI 场景即 pmi2)。


三、四组对照实测(核心)

测试程序(MPI 3.1,打印 rank/size/host):

#include <stdio.h>
#include <unistd.h>
#include <mpi.h>
int main(int argc, char **argv) {
    int rank, size; char host[256];
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    gethostname(host, sizeof(host));
    printf("MPI_OK rank=%d/%d host=%s\n", rank, size, host);
    fflush(stdout);
    MPI_Finalize();
    return 0;
}

编译(mpicc -o mpi_hello mpi_hello.c)通过。提交 sbatch -p compile -N1 -n4 后四种启动方式对照:

# 启动方式 结果 判定
1 srun -n 4 ./mpi_hello ❌ OPAL ERROR: Unreachable in file pmix3x_client.c at line 112
The application appears to have been direct launched using "srun", but OMPI was not built with SLURM's PMI support and therefore cannot execute.
不可用
2 srun --mpi=pmi2 -n 4 ./mpi_hello ❌ 同上(同样报未编译 Slurm PMI 支持) 不可用
3 mpirun -np 4 ./mpi_hello(非 root) ✅ MPI_OK rank=0..3/4 host=k8s-node-01 正确方式
4 srun -n 4 mpirun -np 4 ./mpi_hello ⚠️ 能跑,但输出 16 行(4 个 srun 任务各自又启动了 4 个 MPI 进程) 误用(进程重复)

补充:以 root 提交时,方式 3/4 会额外被 OpenMPI 拒绝:

mpirun has detected an attempt to run as root.
...
You can override this protection by adding the --allow-run-as-root option

即 root 提交必须加 --allow-run-as-root(不推荐,OpenMPI 官方强烈不建议 root 跑 mpirun); 业务用户(如 rain01)提交则无此限制。


四、根因分析

┌──────────────────────────┐        ┌──────────────────────────┐
│ Slurm 26.05.2            │        │ OpenMPI 4.1.5            │
│ 已编译 MPI 插件:         │        │ PMIx 组件:              │
│   none / cray_shasta /   │  ✗     │   pmix3x(内置)          │
│   pmi2                   │◀──────▶│   isolated / flux        │
│ (无 mpi_pmix)           │ 不匹配 │ 未编译 Slurm PMI 支持     │
└──────────────────────────┘        └──────────────────────────┘
  • Slurm 侧:MpiDefault=pmi2 的作用是让 srun 为任务准备 PMI2 通信环境(PMI_FD / PMI_RANK / PMI_SIZE 等)
  • OpenMPI 侧:pmix3x_client.c 报错说明它作为 PMIx 客户端找不到 PMIx server; 而 Slurm 未编译 mpi_pmix 插件,不会提供 PMIx server
  • 同时 OpenMPI 编译时未启用 --with-pmi=slurm,因此也无法退回读 PMI2 环境变量
  • ⇒ 两端协议不匹配,srun 直启路径不通,瓶颈在 OpenMPI 侧而非 Slurm 配置

重要推论:仅设置 MpiDefault=pmi2 并不能让 srun -n N ./prog 工作。 本次仍按用户决策配置了 MpiDefault=pmi2(Slurm 侧语义正确、无副作用、且为将来重编译铺路), 但必须清楚:当前实际可用路径是 mpirun 模式。


五、当前正确用法(用户指引)

5.1 单节点 MPI(推荐写法)

#!/bin/bash
#SBATCH -p compile
#SBATCH -N1
#SBATCH -n4
#SBATCH -J mpi_demo
source /etc/profile.d/lmod.sh
module load openmpi/4.1.5

mpirun -np 4 ./my_mpi_program      # ← 分配已在 sbatch 中声明,mpirun 不再申请资源

5.2 多节点 MPI

#!/bin/bash
#SBATCH -p compile
#SBATCH -N3                 # 三个节点
#SBATCH -n48                # 48 个进程(3 × 16 核)
source /etc/profile.d/lmod.sh
module load openmpi/4.1.5

mpirun -np 48 ./my_mpi_program

mpirun 会读取 Slurm 注入的 SLURM_JOB_NODELIST / SLURM_NTASKS 等变量自行完成进程布局分发, 无需在 mpirun 里重复写 hostfile。

5.3 明确不要这样写(实测会产生进程重复)

srun -n 4 mpirun -np 4 ./prog     # ❌ srun 起 4 个任务,每个又起 4 个 MPI 进程 = 16 个
srun -n 4 ./prog                  # ❌ 当前 OpenMPI 未编译 Slurm PMI,必然失败

六、结论与建议

6.1 结论

项 结论
MpiDefault=pmi2 是否已配置 ✅ 已配置并生效(scontrol show config 可见)
该配置当前是否有实际效果 ❌ 暂无——OpenMPI 未编译 Slurm PMI 支持,srun 直启仍失败
当前唯一可用 MPI 运行方式 ✅ mpirun -np N ./prog(在 sbatch 分配内直接调用)
是否需要紧急处置 否。MPI 作业用 mpirun 模式可正常工作

6.2 根治建议(需单独立项)

若要启用 srun -n N ./prog 直启(HPC 主流用法,可省去 mpirun 层),需重编译 OpenMPI:

# 重新编译 OpenMPI,启用 Slurm PMI 支持
./configure --prefix=/mnt/nfs/slurm/opt/openmpi-4.1.5 \
            --with-slurm \                # 或 --with-pmi=slurm
            --with-pmix=internal \
            --with-hwloc=internal
make -j"$(nproc)" && make install

重编译后需验证:

$ srun --mpi=pmi2 -n 4 ./mpi_hello     # 期望:MPI_OK rank=0..3/4

风险:会替换共享路径下的 MPI 环境,影响所有 MPI 用户; 必须先在非生产路径编译验证,再原子切换(符号链接),并保留旧版本回退通道。

6.3 配套建议

项 建议
统一用户提交模板 在 /mnt/nfs/slurm/modules/global_env/slurm_env 或作业模板中固化 mpirun 用法,避免误用 srun -n N mpirun
修正 modulefile 清理 4.1.5.lua.bak.20260813(含错误的 OMPI_MCA_pmix=pmix),避免误加载
root 提交限制 保持 OpenMPI 的 root 保护(不加 --allow-run-as-root),强制业务用普通用户提交
文档同步 阶段 1 架构文档中"MPI 无默认实现需显式指定"一条应更新为 MpiDefault=pmi2 + mpirun 模式说明

七、测试环境清理

已删除:/mnt/nfs/slurm/tmp_mpi_probe(含 mpi_hello.c / mpicc 产物 / 测试脚本 / 输出日志)
相关测试作业:436、437(均 COMPLETED,无需清理)
提交用户工作目录未留残留

来源:/home/rain/Documents/slurm/slurm_study/slurm_study_plan/运维变更_日志分离与MPI默认/MPI与OpenMPI集成实测报告.md | 最后更新:2026-09-12 12:29(由 build/sync.py 同步,请勿在站点侧修改)