一、Slurm作业管理系统
在使用Slurm作业系统之前,需要了解几个基本概念:
- 登陆节点(Login node)
登录节点是整个集群的入口点,集群所有用户共享使用同一个登陆节点,通常仅用于作业提交、文件编辑和编译工作,不应直接运行计算任务 - 计算节点(Compute Nodes)
实际执行计算任务的服务器,包含处理器、显卡、内存、磁盘空间等资源 - 分区(Partition)
分区是将计算节点按照资源类型或者其他逻辑划分的不同分组 - 作业(job)
用户向集群提交的一个计算任务请求,它代表一次完整的资源分配和任务执行过程
2. 常用Slurm命令详解
2.1 sinfo
sinfo命令的作用是查看分区和节点状态
sinfo # 显示所有分区和节点的基本信息
sinfo -l # 详细格式显示
sinfo -N # 以每行一个节点的方式显示
sinfo -p GPU # 查看特定分区(如GPU分区)状态
sinfo --states=idle # 只显示空闲节点
输出示例:
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
GPU* up infinite 31 mix node[34-50,54-67]
GPU* up infinite 19 idle node[51-53,68-83]
CPU up 2-00:00:00 2 alloc node[02-03]
CPU up 2-00:00:00 1 idle node04
PARTITION(分区)
分区是将计算节点按照资源类型或者其他逻辑划分的不同分组
TIMELIMIT(作业时间限制)
格式为天-小时:分钟:秒,infinite代表无作业时间限制
STATE(节点状态)
| idle | 节点空闲,可接收新作业 |
| allocated/alloc | 节点已被分配给作业 |
| down | 节点宕机或不可用 |
| draining/drain | 节点正在排空任务,不再接收新作业 |
| mixed | 节点部分资源已分配,部分空闲 |
2.2 squeue
squeue命令的作用的查看作业状态
squeue # 只看当前用户的作业
\squeue # 显示所有用户的作业
squeue -p GPU # 查看特定分区的作业
默认情况下squeue输出的内容如下,分别是作业号,分区,作业名,用户,作业状态,运行时间,节点数量,运行节点(如果还在排队则显示排队原因)
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
2041 GPU job_name user1 PD 0:00 1 (AssocGrpGRES)
2039 GPU job_name user1 R 14:36:48 1 gpu01
作业状态(ST字段)包括:
| PD(pending) | 排队中 |
| R(running) | 运行中 |
| CG(completing) | 完成中 |
| F(failed) | 失败 |
NODELIST(REASON)字段排队原因包括:
| AssocGrpGRES | 此账户资源用尽 |
| Resources | 当前分区资源不足 |
| Priority | 当前任务优先级比其他任务优先级低 |
| QOS****PerUserLimit | 超过当前QOS用户最大CPU/GPU/任务数量等限制 |
| JobHeldUser | 用户主动挂起的作业 |
| InvalidAccount | 用户的SLURM账号无效或未授权使用该分区 |
2.3 sbatch
sbatch命令的作用是提交批处理作业,将整个计算过程,写到脚本中,通过sbatch指令提交到计算节点上执行
这是slurm作业系统最常用的作业提交方式,提交后立即返回命令行终端,作业在后台运行
假设我们的计算过程为:在计算节点上运行nvidia-smi指令,那么就可以这么编写作业脚本
#!/bin/bash
#SBATCH -o %j.out
#SBATCH -J job_name
#SBATCH -p 2V100
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --gres=gpu:1
nvidia-smi
假设上面作业脚本的文件名为job.sh,通过以下命令提交
sbatch job.sh
成功提交任务后,会得到一个作业号
Submitted batch job 48769
此作业号可以用squeue命令查询到
squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
48769 4P100 job_name user1 R 2:04 1 node107
2.4 scancel
scancel命令的作用是取消队列中已提交的作业
取消作业ID为48769的作业
scancel 48769
取消作业号为48769到48780的一连串作业
scancel [48769-48780]
取消所有正在排队的作业
scancel -t PENDING
#也可以指定其他状态,比如正在运行的(RUNNING)
2.5 scontrol
scontrol命令的作用是系统控制与详细信息查看
scontrol show job 123 # 显示作业号为123的作业的详细信息
scontrol show nodes node01 # 显示节点node01的详细配置
scontrol hold 123 # 挂起/暂停排队中尚未运行的作业号为123的作业,挂起的作业将不会被执行。
scontrol release 123 # 释放被挂起的作业123
2.6 srun
srun命令的作用是交互式提交作业
srun [OPTIONS...] executable [args...]
srun 命令示例:
srun -p CPU -w node01 -n 48 -t 20 A.exe
交互式提交 A.exe 程序,其中,
-p CPU 指定提交作业到CPU队列
-w node01 指定使用node01节点
-n 48 指定总核数为48
-t 20 指定作业运行时间限制为20分钟
2.7 salloc
salloc命令的作用是申请计算节点,然后用户登录到申请到的计算节点上运行任务,salloc 与 sbatch 有几乎相同的参数,不同的是,sbatch在申请到资源后,直接跳转到申请到的计算节点运行脚本中的指令,而salloc只是申请资源,并不会自动跳转到节点执行指令
示例用法
执行salloc命令申请CPU队列的1个节点48核CPU资源
vasp6666@login01:~$ salloc -n 48 -p CPU
salloc: Granted job allocation 5194
salloc: Waiting for resource configuration
salloc: Nodes node01 are ready for job
2、根据屏幕分配的节点(比如是node节点),执行ssh node01登陆到所分配的节点
vasp6666@login01:~$ ssh node01
3、登陆计算节点后可以执行需要的提交命令或程序,比如程序编译安装
vasp6666@node01:~$ source /public/toolkit/oneapi_2023.2/setvar.sh
vasp6666@node01:~$ make DEPS=1 -j 48
4、作业结束后,执行scancel JOBID释放分配模式作业的节点资源
vasp6666@node01:~$ scancel 5194
salloc: Job allocation 5194 has been revoked.
vasp6666@login01:~$
3. Slurm作业脚本编写
3.1 基本脚本结构
Slurm作业脚本是一个shell脚本,包含Slurm指令和要执行的命令。基本结构如下:
#!/bin/bash
#SBATCH 指令部分
# 要执行的命令部分
3.2 常用SBATCH指令详解
#!/bin/bash
# 作业名称(--job-name或-J)
#SBATCH --job-name=my_job
# 指定分区(--partition或-p)
#SBATCH --partition=GPU
# 指定节点数(--nodes或-N,格式:最小节点数或最小节点数-最大节点数)
#SBATCH --nodes=1
#SBATCH --nodes=1-2
# 指定总任务数(--ntasks或-n,一般一个任务需一个CPU核,因此总任务数通常可理解为CPU核心数)
#SBATCH --ntasks=32
# 每个节点上的任务数
#SBATCH --ntasks-per-node=16
# 每个任务需要的CPU数
#SBATCH --cpus-per-task=1
# 内存需求(单位可以是K、M、G)
#SBATCH --mem=16G
# 每个CPU需要的内存
#SBATCH --mem-per-cpu=1G
# 作业最长运行时间(格式:days-hours:minutes:seconds)
#SBATCH --time=2-00:00:00
# 标准输出文件(--output或-o)
#SBATCH --output=job_%j.out
# 标准错误输出文件
#SBATCH --error=job_%j.err
# 需要GPU资源
#SBATCH --gres=gpu:2
3.3 实际应用示例
弦月一号的1V100队列申请一张V100显卡计算VASP任务的脚本
#!/bin/bash 👈Linux 系统中脚本文件开头的特殊注释
#SBATCH -o %j.out 👈标准输出文件,%j是指本次作业的作业号,因此输出文件名称为作业号.out
#SBATCH -J job_name 👈作业名称设置为job_name
#SBATCH -p 1V100 👈指定此次作业提交到1V100分区
#SBATCH --nodes=1 👈指定此次作业需要一个节点
#SBATCH --ntasks=1 👈指定此次作业任务数量为1
#SBATCH --gres=gpu:1 👈指定此次作业申请一个显卡
dos2unix ./POSCAR ./INCAR ./KPOINTS ./POTCAR 👈解决 Windows 和 Unix/Linux 系统间文本文件格式不兼容的问题
source /public/toolkit/oneapi_2023/mkl/latest/env/vars.sh 👈加载intel MKL库
module load /public/toolkit/nvidia/hpc_sdk/modulefiles/nvhpc/25.3 👈加载nvhpc_sdk环境变量
export NO_STOP_MESSAGE=1
export OMP_NUM_THREADS=1
export vasp_path=/public/software/vasp/GPU/vasp/vasp_std 👈指定VASP程序所在路径
mpirun -np $SLURM_NTASKS --bind-to none $vasp_path 👈运行VASP程序
弦月一号的CPU队列申请48核心计算VASP任务的脚本
#!/bin/bash 👈Linux 系统中脚本文件开头的特殊注释
#SBATCH -o %j.out 👈标准输出文件,%j是指本次作业的作业号,因此输出文件名称为作业号.out
#SBATCH -J job_name 👈作业名称设置为job_name
#SBATCH -p CPU 👈指定此次作业提交到CPU分区
#SBATCH --nodes=1 👈指定此次作业需要一个节点
#SBATCH --ntasks=48 👈指定此次作业任务总量为48
ulimit -s unlimited 👈取消进程的栈大小限制,允许程序使用任意大小的栈内存
source /public/toolkit/intel/oneapi/setvars.sh intel64 > /dev/null 👈加载intel_oneapi环境变量
export vasp_path=/public/software/vasp/CPU/vasp.6.4.2/vasp_std 👈指定VASP程序所在路径
mpirun -np $SLURM_NTASKS $vasp_path 👈运行VASP程序
