超算入门7 slurm
# 1. 什么是slurm ?
Slurm 是一个开源、容错、高可伸缩的集群管理和大型小型 Linux 集群作业调度系统。slurm不需要对操作系统内核进行修改,而是相对独立的。
用户理解:
超算集群不能在登陆节点计算任务,需要提交到计算节点,怎么提交呢?用作业管理系统提交。
slurm
就是其中一种。
下面介绍如何使用slurm。
# 2. slurm使用初级
# 查看可用节点 yhi
查看可用计算节点信息的命令是:
$ yhi
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
debug up 30:00 100 drain cn[1-100]
debug up 30:00 100 alloc cn[101-200]
debug up 30:00 100 idle cn[200-300]
2
3
4
5
上面的代码中,行首为
$
符的行是用户输入的命令,其他行为显示的结果,同下。
说明:
关键词 | 含义 | 备注 |
---|---|---|
PARTITION | 分区名 | -p 分区名来指定分区 |
AVAIL | 可用状态 | up 可用 down 不可用 |
TIMELIMIT | 该分区的作业最大运行时长限制 | 30:00 表示30分钟 2-00:00:00表示2天 infinite表示不限时间 |
NODES | 节点的数量 | -N 数字 来指定节点数量 |
STATE | 节点的状态 | drain: 排空状态,表示该类结点不再分配到其他 idle: 空闲状态 alloc: 被分配状态 |
通过查看系统可用资源情况,我们就知道了要将计算任务提交到那里了,比如例子中的debug计算分区。
# 提交作业
接下来应该就是使用slurm作业管理系统进行作业提交了,常用的提交方式有2种,分别介绍如下:
# yhrun 提交
在命令行终端直接执行yhrun命令进行作业提交计算:
天河系统的相应命令是:
$ yhrun -N 2 -n 24 -p debug executable [args...]
疑问:
-N
与-n
两个参数是什么关系?
解答:-N
是总节点数,-n
是总核数。以TH-1A集群为例,一个节点有12个核。
当N*12 >= n
时,任务可以成功运行,并且占用了节点的全部核数,推荐使用;
当N*12 < n
时,由于无法满足这种节点数和核数的组合,会提示报错如下:yhbatch: error: Batch job submission failed: Requested node configuration is not available
参数说明如下:
关键词 | 含义 | 备注 |
---|---|---|
yhrun | 并行执行程序的命令 | 类似于通用的mpirun 命令 |
-N | 总节点数 | -N 2 表示用2个计算节点 |
-n | 总核数 | -n 24 表示一共用24个cpu核心,注意是总数,而不是每个节点的核数 |
-p | 计算分区 | -p debug 表示用debug计算分区,可以用yhi 命令查询可用分区 |
executable | 可执行程序名称 | 就是你要运行的程序的名字 |
[args...] | 执行参数 | 有的程序需要加参数,就写在后面 |
yhrun
运行的程序,默认会将输出显示到屏幕上,而且当前终端断掉会导致任务退出,因此推荐用下面的yhbatch
命令提交任务。
# yhbatch提交
这种方式是最为推荐的方式,先编写一个脚本(别担心,很简单),然后用提交命令提交这个脚本即可。
1)编写脚本
使用文本编辑器(例如vim等),创建一个用于提交作业的脚本文件,例如名为sub.sh的文件。
$ vim sub.sh
然后写入脚本内容
#!/bin/bash
yhrun -N 2 -n 24 -p debug executable [args...]
2
里面写的内容和yhrun
提交方式的内容完全相同。
2)提交脚本
$ yhbatch -N 2 -n 24 -p debug sub.sh
Submitted batch job 1454916
2
成功提交后,返回Submitted batch job 1454916
,这一串数字就是该任务的JOBID
。
疑问:
yhbatch
和yhrun
都指定了-N -n
参数,哪个会起作用呢?
**解答:**当我们使用yhbatch
提交一个任务时,首先会向作业管理系统申请指定分区指定节点数的计算资源(当核数与节点数不匹配时会报错,yhrun
的部分已经解释过)
当获得了计算资源后,任务脚本会在计算节点执行。
当yhrun运行需要的计算资源
<=
yhbatch申请的计算资源
时,程序可以正常运行;
当yhrun运行需要的计算资源
>
yhbatch申请的计算资源
时,程序就会报错退出,在slurm-jobid.out
文件中显示类似报错;
yhrun: error: Only allocated 1 nodes asked for 2
参数说明如下:
关键词 | 含义 | 备注 |
---|---|---|
yhbatch | 提交批处理脚本的命令 | |
-N | 总节点数 | -N 2 表示用2个计算节点 |
-n | 总核数 | -n 24 表示一共用24个cpu核心 |
-p | 计算分区 | -p debug 表示用debug计算分区 |
sub.sh | 提交脚本名 | 可以依据任务不同编写其他名称的脚本文件 |
优势:使用这种方式提交的任务,会自动生成一个名为
slurm-jobid.out
的文件,其中jobid
是slurm分配给这个任务的具体编号数字。里面会有除了程序特殊指定,或用户重定向以外的所有作业的标准输出和错误信息。当计算任务出现错误的时候,我们也是第一时间查看该文件,寻找原因。
# 查看任务状态
如果我们想查看一下当前用户的作业状态,可以使用如下命令:
$ yhq
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1454916 debug sub.sh zhenggang R 00:05:00 2 cn[5-6]
2
3
参数说明如下:
关键词 | 含义 | 备注 |
---|---|---|
JOBID | 任务编号 | 唯一编号,方便追溯 |
PARTITION | 计算分区名 | 可用yhi 查询 |
NAME | 任务名 | 默认以提交脚本的名称当作任务名 |
USER | 用户名 | 提交该任务的用户名 |
ST | 任务状态 | PD排队 R运行 S挂起 CG正在退出 |
TIME | 任务运行时间 | 例子中为5分钟 |
NODES | 任务作占节点数 | 例子中为1个 |
NODELIST(REASON) | 节点列表(排队原因) | 如果是排队状态的任务,则会给出排队原因 |
备注常见排队原因:
- AssociationResourceLimit:关联的资源限制已满 --- 账户有使用节点数限制,已经用满了
- Resources:当前可用资源不能满足作业需求 --- 系统的可用节点资源不足
- Dependency:作业的依赖关系未满足 --- 作业之间有依赖关系,依赖的作业没完成
- PartitionDown:作业所在的分区处于 down 状态 --- 分区down,所以节点不可用
# 任务完成/取消作业
如果提交作业后,如果正常结束,那么在slurm-jobid.out
文件中并不会有任务的报错信息。
如果任务正在运行,发现需要将它取消,可以这样子:
1)确定任务编号
我们用yhq
命令查看任务编号,比如为
$ yhq
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1454916 debug sub.sh zhenggang R 00:15:00 2 cn[5-6]
2
3
2)取消任务
$ yhcancel 1454916
# 2. slurm使用中级
用户常用的功能,其实大部分是yhrun/yhbatch
的其他参数,举例如下:
# 设置线程数
默认情况下,一个MPI进程开启一个线程,当程序为多线程程序的时候,可以手动设置线程数:
方法一:
$ export OMP_NUM_THREADS=4
通过环境变量参数设置线程数为4。
方法二:
$ yhrun -N 2 -n 8 -c 4 -p debug executable [args...]
通过yhrun -c 4
设置线程数为4。
# 设置工作目录
默认情况下,执行yhbatch
命令的目录就是任务的默认目录。
如果希望修改任务的默认目录,可以使用-D
参数。
$ yhbatch -D /path/to/new/directory -N 2 -n24 -p debug sub.sh
/path/to/new/directory 表示一个新的目录
# 指定节点
我们可以用-w
参数来指定任务使用哪些节点,可以用-x
参数指定任务不使用哪些节点。
通常使用-x
的场景为,当任务在某个节点报错退出后,如果怀疑该节点有问题,可以先用-x
参数过滤掉该节点,重新提交任务。
$ yhbatch -w cn10 -N 2 -n24 -p debug sub.sh
$ yhbatch -x cn11 -N 2 -n24 -p debug sub.sh
2
# 指定任务名
当用户需要提交非常多的相似任务时,通常只会将提交脚本中的参数进行修改,但这样子提交的任务的任务名都相同,不好区分。
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1454916 debug sub.sh zhenggang R 00:15:00 2 cn[5-6]
1454917 debug sub.sh zhenggang R 00:15:00 2 cn[7-8]
1454918 debug sub.sh zhenggang R 00:15:00 2 cn[9-10]
2
3
4
我们可以用-J
参数为每一个任务指定任务名,例如:
$ yhbatch -J job1 -N 2 -n24 -p debug sub.sh
Submitted batch job 1454920
$ yhbatch -J job2 -N 2 -n24 -p debug sub.sh
Submitted batch job 1454921
$ yhbatch -J job3 -N 2 -n24 -p debug sub.sh
Submitted batch job 1454922
$ yhq
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1454920 debug job1 zhenggang R 00:00:05 2 cn[15-16]
1454921 debug job2 zhenggang R 00:00:05 2 cn[17-18]
1454922 debug job3 zhenggang R 00:00:05 2 cn[19-20]
2
3
4
5
6
7
8
9
10
11
# 任务运行时常
默认情况下,任务会一直运行直到任务结束;在超算集群上,通常的计算分区都有设置最大运行时常,当超出时常后任务会自动退出,slurm-jobid.out
文件报错类似:Error: DUE TO TIME LIMIT
用户也可以用-t
参数设置该任务的最大运行时常,时间单位为分钟,如设置为10分钟(即为-t 10
):
$ yhbatch -t 10 -N 2 -n 24 -p debug sub.sh
# 3. slurm使用高级
# yhalloc方式使用
除了yhrun
和yhbatch
,还有一个命令叫做yhalloc
,适用于调试程序。
$ yhballoc -N 2 -n 24 -pdebug
yhalloc: Granted job allocation 1455031
$ yhq
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1455031 debug bash zhenggang R 0:44 2 cn[31-32]
2
3
4
5
6
我们接下来可以:
yhrun -N 2 -n24 -pdebug executable [args...]
任务会在刚刚分配的cn[31-32]节点运行。
我们也可以用ssh
命令切换到计算节点,进行各种操作。
$ ssh cn32
Last login: Tue Dec 18 08:58:40 2018 from ln0
2
注意:用yhalloc申请的节点会在当前终端退出时释放掉,因此仅适用于高阶玩家调试用。
# 设置任务依赖
有时候任务1与任务2有点关系,我们希望等任务1结束后再运行任务2。
如果将任务1和任务2都提交了,它们之间没人关系,会再获得计算资源后都运行,这不是我们想要的。
因此,我们可以正常提交任务1,然后在提交任务2的时候,使用-d jobid
参数设置依赖关系,让任务2等待任务1结束后再运行,即便有计算资源也等着。
$ yhbatch -N 2 -n 24 -p debug sub1.sh
Submitted batch job 1454946
$ yhbatch -d 1454946 -N 2 -n 24 -p debug sub2.sh
Submitted batch job 1454947
$ yhq
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
1454947 debug sub2.sh zhenggang PD 0:00 1 (Dependency)
1454946 debug sub1.sh zhenggang R 0:37 1 cn46
2
3
4
5
6
7
8
我们可以看到先提交的任务1454946
已经在R
,后提交的任务1454947
在PD
,原因是Dependency
,这意味着它将等待1454946
任务结束后才开始运行。
# 附录
# slurm内置环境变量
slurm有很多内置的环境变量,可以在提交脚本中使用,来显示各类信息:
内置变量 | 含义 |
---|---|
SLURM_NODELIST | 分配的节点列表 |
SLURM_NNODES | 分配的任务数 |
SLURM_NPROCS | 要加载的任务数 |
SLURM_JOBID | 作业的 JobID |
SLURM_TASKS_PER_NODE | 每节点要加载的任务数 |
SLURM_JOB_ID | 作业的 JobID |
SLURM_SUBMIT_DIR | 提交作业时的工作目录 |
SLURM_JOB_NODELIST | 作业分配的节点列表 |
SLURM_JOB_CPUS_PER_NODE | 每个节点上分配给作业的 CPU 数 |
SLURM_JOB_NUM_NODES | 作业分配的节点数 |