作业提交


http://slurm.schedmd.com/

1. 结点状态查看命令 sinfo 
       
用户查看其节点的状态:

        其中,PARTITION 表示分区,NODES 表示结点数,NODELIST 为结点列表,STATE 表示结点运行状态。其中,idle 表示结点处于空闲状态,alloc 表示结点已经分配了一个或多个作业。

 

2. 作业状态信息查看命令 squeue

        查看作业运行情况。

        其中,JOBID 表示任务 ID,Name 表示任务名称,USER 为用户,TIME 为已运行时间,NODES 表示占用结点数,NODELIST 为任务运行的结点列表。


3. 交互式作业提交命令 srun

        交互式提交作业:在 shell 窗口中执行 srun 命令,主要命令格式如下:
                srun [options] program


        srun 常用选项:srun 包括多个选项,其中最常用的选项主要有以下几个:
                 -n, –ntasks=number
        指定要运行的任务数。请求为 number 个任务分配资源,默认为每个任务一个处理器核。


                 -c, –cpus-per-task=ncpus
        告知资源管理系统控制进程,作业的每个任务需要 ncpus 个处理器核。若未指定此选项,则控制进程默认为每个任务分配一个处理器核。


                -N, –nodes=minnodes[-maxnodes]
        请求为作业至少分配 minnodes 个结点。调度器可能觉得在多于 minnodes 个结点上运行作业。可以通过 maxnodes 限制最多分配的结点数目(例如“-N 2-4”或“–nodes=2-4”)。最少和最多结点数目可以相同以指定特定的结点数目(例如, “-N 2”或“–nodes=2-2” 将请求两个且仅两个结点)。分区的结点数目限制将覆盖作业的请求。如果作业的结点限制超出了分区中配置的结点数目,作业将被拒绝。 如果没有指定-N,缺省行为是分配足够多的结点以满足-n 和-c 参数的需求。在允许的限制范围内以及不延迟作业开始运行的前提下,作业将被分配尽可能多的结点。


                -p, –partition=partition name
        在指定分区中分配资源。请使用 -p [hpxg|hpib|debug] 指定所使用的分区。


                -w, –nodelist=node name list
        请求指定的结点名字列表。作业分配资源中将至少包含这些结点。列表可以用逗号分隔的结点名或结点范围(如 n[0001-0005,0007,…])指定,或者用文件名指定。如果参数中包含 “/” 字符,则会被当作文件名。如果指定了最大结点数如-N 1-2,但是文件中有多余 2 个结点,则请求列表中只使用前 2 个结点。


                -x, –exclude=node name list
        不要将指定的结点分配给作业。如果包含 “/” 字符,参数将被当作文件名。srun 将把作业请求提交到控制进程,然后在远程结点上启动所有进程。如果资源请求不能立即被满足,srun 将阻塞等待,直到资源可用以运行作业。如果指 定了–immediate 选项,则 srun 将在资源不是立即可用时终止。


                -h, –help
        若需使用 srun 更多选项,可通过 “srun –h” 或 “srun –help” 查看。
        

        使用示例:在分区 hpxg 上运行 5 个任务 hostname:
                $srun –p hpxg –n hostname


4. 批处理作业提交命令 sbatch

        批处理作业是指用户编写作业脚本,指定资源需求约束,提交后台执行作业。提交批处理作业的命令为 sbatch,用户提交命令即返回命令行窗口,但此时作业在进入调度状态,在资源满足要求时,分配完计算结点之后,系统将在所分配的第一个计算结点(而不是登录结点)上加载执行用户的作业脚本。
        批处理作业的脚本为一个文本文件,脚本第一行以 “#!” 字符开头,并制定脚本文件的解释程序,如 sh,bash。由于计算节点为精简环境,只提供 sh 和 bash 的默认支持。


        使用示例:例如用户的脚本名为 mybash.sh,内容如下:
                #!/bin/bash
                hostname

        根据该脚本用户提交批处理作业,需要明确申请的资源为 hpxg 分区的 4 个结点。
        注意:需给该文本文件设置 mybash.sh 可执行权限,利用命令:
                chmod +x mybash.sh
       
用户 sbatch 批处理命令如下:
                sbatch –N 4 –p hpxg ./mybash.sh
       
计算开始后,工作目录中会生成以 slurm 开头的.out 文件为输出文件。更多选项,用户可以通过 sbatch –help 命令查看。


5. 作业取消命令 scancel

        用户使用 scancel 命令取消自己的作业。命令格式如下:
                scancel jobid
        jobid 可通过 squeue获得。对于排队作业,取消作业将简单地把作业标记为 CANCELLED 状态而结束作业。对于运行中或挂起的作业,取消作业将终止作业的所有作业步,包括批处理作业脚本,将作业标记为 CANCELLED 状态,并回收分配给作业的结点。一般地,批处理作业将会马上终止;交互作业的 srun 进程将会感知到任务的退出而终止;抢占结点资源的 salloc 进程不会自动退出,除非作业所执行的用户命令因作业或任务的结束而终止。但是在作业被取消时,控制进程都会发送通知消息给分配资源的 srun 或 salloc 进程。用户可以选择通过 salloc 的 "–kill-command" 选项设置在收到通知时向所执行的命令发送信号将其终止。


6. 作业提交示例

        通过对简单示例HelloWorld程序的提交,大家可以了解作业提交的基本步骤,体会使用 srun 和 sbatch 命令提交作业的区别。

         在命令提示符下输入:vim HelloWorld.c
[simon@n0255 ~]$vim HelloWorld.c
        说明:
        vim 为Linux下常用的编辑器,HelloWorld.c为文件名,如果当前目录下不存在该文件,则新建并编辑,如果存在,打开并编辑。
        按下 i 键进入插入模式:

        输入以下内容:
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return(0);
}

        输入完成后按下 Esc 键 退出插入模式,然后输入 :wq 写入并退出。此时,输入ls,应该能看到刚刚建立的文件:[simon@n0255 ~]$ ls
data HelloWorld.c

        接下来,我们要调用系统的编译器来将我们刚才建立的HelloWorld.c源程序编译成可执行文件:[simon@n0255 ~]$ gcc HelloWorld.c
[simon@n0255 ~]$ ls
a.out data HelloWorld.c

        说明:
        gcc 即为系统的C编译器(也可以使用Intel的 icc编译器),后面接你的源程序。
        使用 ls 列出当前目录内容 可以看到生成了名为a.out的程序。接下来,我们执行 a.out 查看下结果:
[simon@n0255 ~]$ ./a.out
Hello world!
[simon@n0255 ~]$

        说明:
        ./a.out 中. 代表当前目录。Hello world! 即为程序的输出了。
        注意:目前你运行的这个程序是在你当前登录的这个节点,也就是n0255上运行的,这个节点也就一个普通的服务器,拥有16个CPU核,如果是运行很多个像我们这样的HelloWorld的程序还是没有啥问题的,但是如果你的一个程序运行需要很长的运行时间,那么16核的CPU就不够用了。特别是这个登录节点同时还有其他用户登录同时使用的,所以 登录节点是禁止运行大量的、长时间占用CPU时间的程序的 。此时我们就需要使用调度系统(SLURM),将我们的程序投放到其它的节点上来运行。
[simon@n0255 ~]$ srun -p hpxg ./a.out
Hello world!
[simon@n0255 ~]$

        srun为我们提交程序,用于把我们程序提交到整个集群系统的节点上去运行的。-p 用于指定分区,hpxg为分区名,我们的集群根据底层网络连接类型分成了hpxg(万兆网络互连,目前已经升级为Infiniband网络互连)、hpib(Infiniband网络互连)、debug(调试用途分区)分区。使用sinfo命令,我们查看各个分区的情况:

 

        我从之前运行的情况来看,输出 Hello World!好像直接在n0255登录节点输出没啥两样,现在我们将程序稍微修改下,就可以看出运行的不同了:

[simon@n0255 ~]$vim HelloWorld.c


        按 i 进入插入模式,输入:

#include <stdio.h>
#include <stdlib.h>
int main()
{
char hostname[1024];
gethostname(hostname,1024);
printf("%s:",hostname);
printf("Hello world!\n");
return(0);
}


        说明:上述程序改动的作用就是在输出Hello World!之前获取主机名并输出。按 Esc 退出插入模式,然后按 :wq 保存并退出。

[simon@n0255 ~]$ gcc HelloWorld.c
[simon@n0255 ~]$ ./a.out
n0255:Hello world!


        可以看出,直接运行的程序前面有了 n0255 的主机名了。接下来,我们使用 srun来进行提交看看:

[simon@n0255 ~]$ srun -p hpxg ./a.out
n0242:Hello world!
[simon@n0255 ~]$


        由此可以看出,我们这个Hello World!应该是在节点n0242上运行了。
        接下来,我们继续修改一下源程序,用来模拟长一点时间(100s)的程序:

#include <stdio.h>
#include <stdlib.h>
int main()
{
char hostname[1024];
sleep(100);
gethostname(hostname,1024);
printf("%s:",hostname);
printf("Hello world!\n");
return(0);
}

 

        上面程序先sleep了100s,然后才有输出。vim HelloWorld.c,然后 gcc 编译,重新生成 a.out,并运行:

        可以看出,程序运行没有返回到命令行,处于等待输入或输出的状态。所以以 srun 提交的程序处于处于交互模式下。
一般只有在程序运行后需要用户人工判断进行输入时才使用交互模式。处于交互模式下运行的程序被人工退出(如Ctrl+c、终端关闭等)或因登录节点故障退出时,程序运行节点的程序也会退出。
        当我们进程不需要人工干预时,我们可以使用sbatch命令来进行任务的提交,这样无论是终端退出或登录节点故障都不会影响到我们实际运行的程序。
        要使用sbatch提交程序,我们只需要写一个很简单的脚本:
[simon@n0255 ~]$ vim a.sbatch
        新建一个a.sbatch(名字或后缀可以随便取)输入以下内容:

#!/bin/bash
./a.out

        保存退出,然后给这个脚本加上可执行的权限:[simon@n0255 ~]$ chmod +x a.sbatch
        接着使用 sbatch 提交:[simon@n0255 ~]$ sbatch -p hpxg a.sbatch
Submitted batch job 2653283
[simon@n0255 ~]$

        可以看到,提交会返回了一个job的ID(2653283),之后便又回到了命令提示符的状态。接下来,我们便可以使用 squeue 来查看我们已经提交了的作业的信息:

        squeue的输出我们可以看出我们提交的任务的ID(JOBID),运行所在的分区(PARTITION),任务的名称(NAME),运行的用户(USER),任务状态(ST,R表示正在运行),运行了的时间(TIME),使用了多个节点(NODES)以及使用了的节点的列表(NODELIST)。
        任务运行完之后,如果需要查看我们程序的输出情况,默认会在提交任务的目录产生 slurm-jobid.out的文件,所有任务运行的错误已经标准输出会重定向至此文件中。

        squeue 只能查看正在运行的任务。如果想查看已经结束的任务历史,可以使用 sacct命令: