运行作业

我们将提交一个单节点作业和一个多节点 MPI 作业,以验证整个集群栈是否正常工作 —— 包括计算、网络、存储和用户身份。

单节点作业

从一个简单的作业开始,验证基本功能。在登录节点上,切换到 user1\:

sudo su - user1

创建并提交一个作业脚本\:

cat > /fsx/single-job.sh << 'EOF'
#!/bin/bash
#SBATCH -J single-test
#SBATCH -o /fsx/single-test.%j.out
#SBATCH -e /fsx/single-test.%j.err
#SBATCH -p x86
#SBATCH --nodes=1
#SBATCH --ntasks=1

echo "Job ${SLURM_JOB_NAME} [${SLURM_JOB_ID}] running on ${SLURMD_NODENAME}"
echo "Submitted by user: $(whoami)"
echo "Home directory: $HOME"
echo "Hostname: $(hostname)"
echo "Date: $(date)"
echo "Job complete"
EOF

sbatch /fsx/single-job.sh

这将以 user1 的身份向 x86 分区提交一个作业。输出会写入到 /fsx(Lustre),因此任何节点都可以访问它。

这是集群上的第一个作业。由于 minInstanceCount=0,PCS 需要从头启动一个 hpc7a 实例。这需要 3-5 分钟。如果实例仍在运行,后续作业会更快。

监控作业

检查作业队列\:

squeue

在 PCS 启动实例时,我们应该会看到作业处于 CF(正在配置)状态,一旦启动后则变为 R(正在运行)\:

image-20260803192624484

观察节点状态:

sinfo

image-20260803192641183

我们会看到节点经历以下状态转换\:

  • idle~ —— 已关机(没有实例运行)
  • alloc# —— 实例正在启动、配置中
  • alloc —— 实例正在运行,作业正在执行
  • idle —— 实例正在运行,没有作业(在空闲超时后将关机)
  • idle~ —— 在空闲超时后再次关机

等待作业完成(squeue 返回为空)\:

watch -n 5 squeue

当队列为空时,按 Ctrl+C

检查输出

cat /fsx/single-test.*.out

我们应该会看到类似这样的输出:

image-20260803192739611

这确认了:

  • 作业运行在一个 hpc7a 计算节点上
  • 它以 user1(LDAP 用户)身份运行
  • 主目录是 /home/user1(EFS)
  • 输出被写入到 /fsx(Lustre)

多节点 MPI 作业

现在用一个 hello world 程序测试 MPI。仍以 user1 身份,创建源代码\:

cat > /fsx/hello.c << 'EOF'
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv) {
  MPI_Init(NULL, NULL);

  int world_size;
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);

  int world_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int name_len;
  MPI_Get_processor_name(processor_name, &name_len);

  printf("Hello from processor %s, rank %d out of %d\n",
         processor_name, world_rank, world_size);

  MPI_Finalize();
}
EOF

加载 OpenMPI 5 模块并编译:

module load openmpi5
mpicc -o /fsx/hello /fsx/hello.c

创建并提交 MPI 作业:

cat > /fsx/mpi-job.sh << 'EOF'
#!/bin/bash
#SBATCH -J mpi-hello
#SBATCH -o /fsx/mpi-hello.%j.out
#SBATCH -e /fsx/mpi-hello.%j.err
#SBATCH -p x86
#SBATCH --nodes=1
#SBATCH --ntasks=4

module load openmpi5
srun /fsx/hello
EOF

sbatch /fsx/mpi-job.sh

此作业在单个 hpc7a 节点上运行 4 个 MPI rank。PCS 将启动 1 个 hpc7a 实例(如果尚未运行)。

监控并检查结果

watch -n 5 squeue

等待作业完成,然后检查输出\:

cat /fsx/mpi-hello.*.out

我们应该会看到来自同一节点上 4 个 rank 的输出:

image-20260803192956542

所有 rank 都运行在同一个 hpc7a 实例上。这确认了 MPI、EFA 以及 Slurm 集成都正常工作。

附:MPI(Message Passing Interface)

HPC 作业(CFD 仿真、天气预报、分子动力学)一台机器算不动,要拆到几百上千个节点上并行跑。这些分布在不同机器上的进程需要频繁交换数据(比如网格边界值),MPI 就是干这个的标准接口:

• 点对点通信:MPI_Send / MPI_Recv,进程 A 发数据给进程 B

• 集合通信:MPI_Bcast(广播)、MPI_Reduce(归约求和)、MPI_Allgather(全收集)等

• 进程管理:程序启动时拉起 N 个进程,每个有自己的 rank(编号),按 rank 分工

写法示意:科学家写一份 C/Fortran 代码,用 mpirun -np 1024 ./my_sim 启动 1024 个进程,代码里用 MPI 调用互相传数据。

OpenMPI 是 MPI 标准的一个开源实现

关系类似"SQL 标准 vs MySQL/PostgreSQL”:

• MPI = 规范(由 MPI Forum 制定,现在到 MPI-4.x)

• OpenMPI = 最流行的开源实现之一

• 其他实现:MPICH(另一个老牌开源实现)、Intel MPI、AWS 上还有针对 EFA 优化的路径

因为大家都遵循同一标准,同一份源代码理论上换个 MPI 实现重新编译就能跑——实现之间比拼的是性能和网络支持(谁的集合通信更快、对 InfiniBand/EFA 支持更好)。