在 SLURM 中—— nasks 或-n 任务是做什么的?

我使用 SLURM来使用一些计算集群,它有 -ntasks-n。我显然已经阅读了它的文档(http://slurm.schedmd.com/sbatch.html) :

Satch 不启动任务,它请求分配资源 并提交一个批处理脚本。此选项通知 Slurm 控制器 在分配内运行的作业步骤将启动的最大值为 为任务编号并提供足够的资源。默认值为 每个节点一个任务,但请注意—— cpus-per-task 选项将 更改此默认值。

具体的部分我不明白它的意思是:

在分配内运行将启动最多数量的任务,并 提供足够的资源。

我有几个问题:

  1. 我想我的第一个问题是“任务”这个词是什么意思,区别在于 SLURM 上下文中的“工作”这个词。我通常认为作业就是像在 sbatch my_batch_job.sh中一样在 satch 下运行 bash 脚本。不知道任务是什么意思。
  2. 如果我将单词 task 等同于 job,那么我认为它会根据 -n, --ntasks=<number>的参数多次运行相同的 bash 脚本。然而,我显然在集群中测试了它,用 --ntask=9运行了一个 echo hello,并且我期望 satch 将对 stdout 回显 hello 9次(这是在 slurm-job_id.out中收集的,但是令我惊讶的是,我的 echo hello 脚本只执行了一次,那么这个命令到底做了什么呢?看起来它什么也没做,或者至少我看不到它应该做什么。

我确实知道 -a, --array=<indexes>选项适用于多个作业。那是另一个话题。我只是想知道 --ntasks应该做什么,理想情况下应该使用一个示例,这样我就可以在集群中测试它。

41665 次浏览

“—— nasks”选项指定执行命令的实例数。 对于一个常见的集群设置,如果您使用“ srun”启动命令,则这对应于 MPI 等级的数量。

相反,“—— CPUs-per-task”选项指定每个任务可以使用多少 CPU。

您的输出结果也让我感到惊讶。您是在脚本中启动了命令,还是通过 srun 启动了命令? 你的剧本看起来像不像:

#!/bin/bash
#SBATCH --ntasks=8
## more options
echo hello

这应该始终只输出一行,因为脚本只在提交节点上执行,而不是在 worker 上执行。

如果你的剧本看起来像

#!/bin/bash
#SBATCH --ntasks=8
## more options
srun echo hello

Srun 使脚本在 worker 节点上运行命令,因此您应该得到8行 hello。

如果您有要在同一批处理脚本中并行运行的命令,则 --ntasks参数非常有用。 这可以是由一个 &分隔的两个独立命令,也可以是 bash 管道(|)中使用的两个命令。

比如说

使用默认的 nasks = 1

#!/bin/bash


#SBATCH --ntasks=1


srun sleep 10 &
srun sleep 12 &
wait

将抛出警告:

作业步骤创建暂时停用,重试

默认情况下,任务的数量指定为一个,因此在第一个任务完成之前不能启动第二个任务。 这项工作将在22秒左右完成:

sacct -j515058 --format=JobID,Start,End,Elapsed,NCPUS


JobID               Start                 End    Elapsed      NCPUS
------------ ------------------- ------------------- ---------- ----------
515058       2018-12-13T20:51:44 2018-12-13T20:52:06   00:00:22          1
515058.batch 2018-12-13T20:51:44 2018-12-13T20:52:06   00:00:22          1
515058.0     2018-12-13T20:51:44 2018-12-13T20:51:56   00:00:12          1
515058.1     2018-12-13T20:51:56 2018-12-13T20:52:06   00:00:10          1

在这里,任务0开始和完成(12秒) ,然后是任务1(10秒)。使用户的总时间为22秒。

同时运行这两个命令:

#!/bin/bash


#SBATCH --ntasks=2


srun --ntasks=1 sleep 10 &
srun --ntasks=1 sleep 12 &
wait

运行与上面指定的相同的 sacct 命令

    sacct -j 515064 --format=JobID,Start,End,Elapsed,NCPUS
JobID               Start                 End    Elapsed      NCPUS
------------ ------------------- ------------------- ---------- ----------
515064       2018-12-13T21:34:08 2018-12-13T21:34:20   00:00:12          2
515064.batch 2018-12-13T21:34:08 2018-12-13T21:34:20   00:00:12          2
515064.0     2018-12-13T21:34:08 2018-12-13T21:34:20   00:00:12          1
515064.1     2018-12-13T21:34:08 2018-12-13T21:34:18   00:00:10          1

这里总共需要12秒。不存在任务等待资源的风险,因为批处理脚本中已经指定了任务的数量,因此作业具有同时运行这么多命令的资源。

每个任务继承为批处理脚本指定的参数。这就是为什么需要为每个运行任务指定 --ntasks=1,否则每个任务都使用 --ntasks=2,因此第二个命令在第一个任务完成之前不会运行。

继承批处理参数的任务的另一个警告是,如果将 --export=NONE指定为批处理参数。在这种情况下,应该为每个 srun 命令指定 --export=ALL,否则 srun 命令不会继承 sbatch 脚本中设置的环境变量。

附加说明:
在使用 bash 管道时,可能需要指定—— node = 1,以防止管道两侧的命令在单独的节点上运行。
当使用 &同时运行命令时,wait是至关重要的。在这种情况下,如果没有 wait命令,任务0将取消自身,因为任务1已成功完成。

任务是作业在一个或多个节点中并行执行的进程。sbatch为您的作业分配资源,但是即使您为多个任务请求资源,它也只会在单个节点的单个进程中启动作业脚本。srun用于从批处理脚本启动作业步骤。--ntasks=N指示 srun执行作业步骤的 N 个副本。

比如说,

#SBATCH --ntasks=2
#SBATCH --cpus-per-task=2

意味着需要并行运行两个进程,并让每个进程访问两个 CPU。sbatch将为您的作业分配四个 CPU,然后在一个进程中启动批处理脚本。在批处理脚本中,可以使用

srun --ntasks=2 --cpus-per-task=2 step.sh

这将并行运行两个进程,它们都执行 step.sh脚本。从同一个作业,您也可以运行

srun --ntasks=1 --cpus-per-task=4 step.sh

这将启动一个可以访问所有四个 GPU 的进程(尽管它会发出警告)。

值得注意的是,在分配的资源中,您的作业脚本可以自由地做任何事情,并且它不必使用 srun来创建作业步骤(但是您需要 srun来在多个节点中启动作业步骤)。例如,下面的脚本将同时运行这两个步骤:

#!/bin/bash
#SBATCH --ntasks=1
step1.sh &
step2.sh &
wait

如果您想使用 srun启动作业步骤,并且有两个不同的步骤并行运行,那么您的作业需要分配两个任务,并且您的作业步骤只需要请求一个任务。您还需要为 srun提供 --exclusive参数,以便作业步骤使用单独的资源。

#!/bin/bash
#SBATCH --ntasks=2
srun --ntasks=1 --exclusive step1.sh &
srun --ntasks=1 --exclusive step2.sh &
wait