提交批处理任务

在工作站提交批处理任务需要编写 SLURM 脚本,以便明确申请的资源以及所要运行的程序。

查看可用资源

在提交任务之前,务必检查一下各个节点的状态,例如资源是否充足,当前有多少正在执 行的任务等。

[liuhy@admin playground]$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu*         up 7-00:00:00      1    mix comput2
cpu*         up 7-00:00:00      1  alloc comput1
cpu*         up 7-00:00:00      2   idle comput[3-4]
gpu          up 7-00:00:00      1   idle comput6

如上所示,使用 sinfo 可粗略查看所有分区的节点信息,注意 ‘‘STATE’’ 一栏的输出 若为 ‘‘idle’’ 表示该节点处于闲置状态,若为 ‘‘alloc’’ 表示该节点已经没有多余的 资源了,若为 ‘‘mix’’ 表示该节点有人在占用,但是仍然有剩余资源。

小提示

对于 gpu 分区的节点 comput6,如果显示 ‘‘mix’’ 表示部分资源被占用,可能出现 GPU 卡都被占用但是有空闲 CPU 核心的情况。此时我们需要这个节点更详细的信息。可以使用 scontrol show node <节点名> 命令。

[liuhy@admin playground]$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu*         up 7-00:00:00      4   idle comput[1-4]
gpu          up 7-00:00:00      1    mix comput6
[liuhy@admin playground]$ scontrol show node comput6
NodeName=comput6 Arch=x86_64 CoresPerSocket=14
  CPUAlloc=4 CPUErr=0 CPUTot=56 CPULoad=0.00
  AvailableFeatures=(null)
  ActiveFeatures=(null)
  Gres=gpu:2
  NodeAddr=comput6 NodeHostName=comput6 Version=17.11
  OS=Linux 2.6.32-696.18.7.el6.x86_64 #1 SMP Thu Jan 4 17:31:22 UTC 2018
  RealMemory=128000 AllocMem=8800 FreeMem=105593 Sockets=2 Boards=1
  State=MIXED ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
  Partitions=gpu
  BootTime=2018-01-12T12:55:53 SlurmdStartTime=2018-01-20T16:04:26
  CfgTRES=cpu=56,mem=125G,billing=56,gres/gpu=2
  AllocTRES=cpu=4,mem=8800M,gres/gpu=2
  CapWatts=n/a
  CurrentWatts=0 LowestJoules=0 ConsumedJoules=0
  ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s

如上所示,sinfo 显示 gpu 分区的 comput6 状态是 ‘‘mix’’,但是使用 scontrol 命令查看发现已经占用的资源为 AllocTRES=cpu=4,mem=8800M,gres/gpu=2,即占用 了 4 个 CPU 核心,8800 MB 内存和 2 块 GPU 卡。GPU 卡已经全部占用,这个节点将 无法运行需要 GPU 的任务。但仍然可运行纯 CPU 任务。

此外,管理员还提供了两个有用的命令 snodesjob 用于查看各个节点的状态 与集群所有任务的运行情况。

liuhy@admin ~]$ snode
    NODE       CPU      LOAD         MEM       GPU    JOBID
===========================================================================
 comput1      6/48      6.00     15/128G       0/0    [938 zhanghaix] [937 zhanghaix]
 comput2     48/48     31.83    124/128G       0/0    [946 tsen] [935 zhanghaix]
 comput3     30/48     28.85     78/128G       0/0    [936 zhanghaix]
 comput4      0/48      0.00      0/128G       0/0
 comput6      0/56      0.00      0/128G       0/2
[liuhy@admin ~]$ sjob
             JOBID     USER  ACCOUNT CPUS  GRES NODELIST  TIME_LEFT TIME_LIMIT PRIORITY    STATE REASON
               946     tsen    wenzw   16 (null  comput2    6:43:39   10:00:00      244  RUNNING None
               938 zhanghai  dongbin    4 (null  comput1 6-15:03:17 7-00:00:00      100  RUNNING None
               937 zhanghai  dongbin    2 (null  comput1 6-14:59:11 7-00:00:00      100  RUNNING None
               936 zhanghai  dongbin   30 (null  comput3 6-14:46:27 7-00:00:00      100  RUNNING None
               935 zhanghai  dongbin   32 (null  comput2 6-01:43:56 7-00:00:00      100  RUNNING None

编写 SLURM 脚本

你需要编写一个 SLURM 脚本来完成任务提交的设置。SLURM 脚本可以在本地编写后上传, 也可以直接在工作站服务器上编辑。

一个 SLURM 脚本可设置很多内容,下面的模板列出了常用的选项。

run.slurm
#!/bin/bash
#SBATCH -J test                   # 作业名为 test
#SBATCH -o test.out               # 屏幕上的输出文件重定向到 test.out
#SBATCH -p gpu                    # 作业提交的分区为 cpu
#SBATCH --qos=debug               # 作业使用的 QoS 为 debug
#SBATCH -N 1                      # 作业申请 1 个节点
#SBATCH --ntasks-per-node=1       # 单节点启动的进程数为 1
#SBATCH --cpus-per-task=4         # 单任务使用的 CPU 核心数为 4
#SBATCH -t 1:00:00                # 任务运行的最长时间为 1 小时
#SBATCH --gres=gpu:1              # 单个节点使用 1 块 GPU 卡
#SBATCh -w comput6                # 指定运行作业的节点是 comput6,若不填写系统自动分配节点

# 设置运行环境
module add anaconda/3-5.0.0.1     # 添加 anaconda/3-5.0.0.1 模块

# 输入要执行的命令,例如 ./hello 或 python test.py 等
python test.py                    # 执行命令

其中,第一行是固定的,表示使用 /bin/bash 来执行脚本。其余的说明如下

  • 申请时请写对分区,由于不同的分区硬件配置不同。分区详解>>

  • QoS 的含义是 ‘‘Quality of Service’’,即服务质量。不同的 QoS 对应的优先度和 资源最大值不同。QoS 详解>>

  • 申请的资源不要超过当前分区的最大值,建议使用 scontrol 命令查看分区的剩余 资源数。确定申请 CPU 核心数量之前,请确认你的程序是否真的需要这些计算资源。如果 程序的并行程度不高,申请过多的 CPU 核心数会造成资源的浪费(多数 CPU 占用率会较 低),并且会影响他人使用。

  • 无需显式指定申请的内存数量,申请内存的大小和申请 CPU 核心数成正比。如果运行 程序时遇到内存不够的情况请适量增加 CPU 核心数。使用 GPU 的程序无需指定显存数量。

  • 实际在每个节点上分配的 CPU 数量由 --ntasks-per-node--cpus-per-task 参数共同决定。默认情况下二者都是 1。一般来讲,多进程的程序需要更改 --ntasks-per-node多线程的程序需要更改 --cpus-per-task。各位用户请根据 自己需求进行设置。

  • 任务最长时间的设置格式是 DD-HH:MM:SS,例如一天又 15 小时写作 1-15:00:00。 如果高位为 0 可省略。如果不写任务最长时间,则任务的最长时间默认为对应分区 (Partition) 的默认时间。

以上的所有 #SBATCH 属性均可以不设置,当缺少某属性时,系统将使用默认值。

请在使用时估计自己任务的开销,适量申请计算资源,避免造成资源的浪费。

常见的计算软件/软件库的启动命令

以下列出服务器中常见的软件启动命令,可以作为手动编写 SLURM 脚本的参考,也可以 作为交互式计算的使用参考。

以命令行模式运行 MATLAB

$ matlab -nodesktop -nosplash -nodisplay

使用 MATLAB 运行 m 脚本

$ matlab -nodesktop -nosplash -nodisplay -r "MATLAB 脚本名,不带 m 后缀"

注意:MATLAB 脚本不能像其他语言(如 python,bash)等使用 shebang 来指定解释器, 因此执行一个 M 文件需要使用 MATLAB 内置命令。-r 参数的含义其实并不是“执行 一个脚本”,而是因为在 MATLAB 的命令行中,输入命令可以等效于执行同名的脚本, 因此才使用这种方式。

使用 R 运行 R 脚本

$ Rscript <脚本名>

使用 python 运行 py 脚本

$ python <脚本名>

提交任务

将 SLURM 脚本编写完毕并上传工作站后(或直接在工作站编辑),进入 SLURM 脚本的 目录,使用

$ sbatch <SLURM 脚本文件名>

即可提交任务。

注意,如果参数设置不当 sbatch 命令会提交失败,此时需要检查你的参数并修改成正 确的版本。用户需要使用 squeue 检查作业运行情况,若作业是因为参数不当而没有 运行,则需要修改 SLURM 脚本。

例如,执行 sbatch 后发现如下内容:

[liuhy@admin playground]$ sbatch run.slurm
sbatch: error: Batch job submission failed: Requested node configuration is not available

说明指定的分区内没有所需的资源,检查 SLURM 脚本:

run.slurm
#!/bin/bash
#SBATCH -J test
#SBATCH -p cpu
#SBATCH --cpus-per-task=4
#SBATCH --gres=gpu:2
#SBATCH -N 1
#SBATCH -t 5:00

nvidia-smi
echo $CUDA_VISIBLE_DEVICES
hostname
sleep 60

发现分区写成了 cpu,并同时申请了 GPU 卡。但 CPU 分区是没有 GPU 卡的,因此提交 失败。若提交违反了当前 QoS 的最大限定,任务也会被拒绝。如果违反了目标分区的 最大限定,任务虽然会成功提交但永远不会运行。

有时 sbatch 命令会显示正常提交,但是任务始终无法运行,此时需要使用 squeue 查看任务排队的详细情况。

[liuhy@admin playground]$ sbatch run.slurm
Submitted batch job 55
[liuhy@admin playground]$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                55       cpu     test    liuhy PD       0:00      1 (PartitionTimeLimit)

此时 55 号作业的状态为 PD(Pending),即“被挂起”,最后一列显示了原因是 PartitionTimeLimit,即申请的运行时间已经超过了该分区允许运行的最大时间,任务 永远不会运行。此时需要先使用 scancel 命令(详见下面的说明)取消任务,然后 修改 SLURM 脚本使得参数正确。

快速提交 MATLAB 任务

除了手动编写 SLURM 脚本之外,我们可以使用管理员编写的脚本一键提交 MATLAB 任务。 为此你只需要准备好所有的程序文件,然后运行一次命令即可,非常方便。

$ matslm.rb [-c <使用 CPU 数>][-t <脚本运行时间>][-o <输出文件名>][-p <分区名>][-q <QoS 名>] MATLAB 脚本

此命令的详细用法如下:

  • -h, --help: 显示本命令的帮助。

  • -c, --cpus: 指定使用 CPU 核心数量,默认为 1,允许设置为 1 到 48(或 56, 具体情况视计算资源而定)。

  • -t, --walltime: 指定作业运行的时间,格式为 HH:MM:SS,作业运行时间不得超过 指定 QoS 或分区的最大值。

  • -p, --partition: 指定作业在哪个队列运行,默认为 cpu。

  • -q, --qos: 指定使用哪个 QoS,默认为 normal。

  • -o: 重定向输出文件到某个文件中,此文件中包含输出在 MATLAB 控制台中的所有内容。

  • --tmp-dir: 指定中间文件的存放位置,默认情况下脚本会根据当前时间自动生成一 个目录用于存储所有中间文件。

一个例子(申请 12 个 CPU 核心和 2 小时的运行时间,脚本名为 test.m):

$ matslm.rb -c 12 -t 2:00:00 test.m

程序执行完毕后,产生的标准输出在名为 SLURM_MATLAB_<提交任务时间>_<脚本名(不带.m后缀)> 的文件夹中。

注意:m 脚本文件必须在当前目录中。

查看任务状态

作业提交完毕后,可使用 squeue 命令查看任务状态。

[liuhy@admin playground]$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                55       cpu     test    liuhy PD       0:00      1 (PartitionTimeLimit)
                54       cpu     test    liuhy  R       0:15      1 comput1

如上所示,可显示目前任务号,所在分区,任务状态,已经运行时间,以及运行的节点。 如果任务处于挂起(PD)状态,则显示任务被挂起的原因。用户可以根据这个原因来判断 自己的作业脚本是否写对了。

除此之外,使用 squeue 配合不同参数可以过滤显示的内容,以便能看到你感兴趣的 结果。某些参数可以相互组合。

  • squeue -l: 以长列表显示更多信息。

  • squeue -u username: 仅显示属于用户 username 的任务。

  • squeue -t state: 仅显示处于 state 状态的任务。

删除任务

  • scancel jobid: 删除 jobid 的作业。

  • scancel -u username: 删除 username 的全部作业。

  • scancel -s state: 删除处于 state 状态的作业。

注意:用户只能删除自己的作业,不能删除别人的作业。