首页 > 解决方案 > Slurm - 如何将所有可用的 CPU 用于独立任务?

问题描述

我的问题类似于这个问题

使用 SLURM 上的所有 CPU

长话短说,我想在尽可能多的节点上使用所有可用的 CPU 内核。

不同之处在于,我的工作不是 MPI 程序的单一工作,而是由 N 个独立任务组成,每个任务有 1 个核心。N 可能大于可用内核的总数,在这种情况下,某些任务只需要等待。

例如,假设我有一个由 32 个核心组成的集群。假设我想运行同一个程序 ( worker_script.sh) 100 次,每次都有不同的输入。每次调用worker_script.sh都是一项任务。我希望前 32 个任务运行,而其余 68 个任务将排队。当核心释放时,后面的任务将运行。最终,当所有任务都运行完成时,我的工作就被认为完成了。

这样做的正确方法是什么?我做了以下脚本,并用sbatch. 但它只是在同一个核心上运行所有东西。所以它最终需要永远。

#!/bin/bash
ctr=0
while [[ $ctr -lt 100 ]]; do 
   srun worker_script.sh $ctr &
   ((ctr++))
done

wait

或者,我可以直接调用上述脚本。这似乎奏效了。例如,它接管了所有 32 个内核,同时将其他所有内容都排入队列。当核心被释放时,它们将被分配给剩余的worker_script.sh. 最终,所有 100 个工作都完成了,当然,所有工作都出现了故障,正如预期的那样。

不同之处在于,不是 100 个任务的 1 个工作,而是每个 1 个任务的 100 个工作。

我不能完成 100 个独立任务有什么原因吗?我从根本上是错误的吗?我应该做 100 个工作而不是 100 个任务吗?

标签: hpcslurm

解决方案


如果您通过 提交该脚本sbatch,它将为该作业分配一个任务。在作业内部,srun命令仅限于作业的资源。这就是为什么您的计算按顺序运行的原因,当您通过sbatch.

如果您只运行脚本,而没有sbatch,则每次调用srun都会创建一个新作业(正如您已经注意到的那样),因此它不限于单个任务。

我不能完成 100 个独立任务有什么原因吗?我从根本上是错误的吗?我应该做 100 个工作而不是 100 个任务吗?

最后,您喜欢哪种方式有点个人喜好。您可以拥有一个包含 100 个任务的作业:

#!/bin/bash
#SBATCH -n 32
ctr=0
while [[ $ctr -lt 100 ]]; do 
   srun -n 1 worker_script.sh $ctr &
   ((ctr++))
done

wait

这将分配 32 个任务,每个 srun 调用将消耗 1 个任务,其余的应该是。缺点:您需要一次等待 32 个任务空闲。这意味着您可能会在队列中等待更长时间。

更好的方法(在我看来)是使用作业数组

#!/bin/bash
#SBATCH -a 0-99%32
worker_script.sh $SLURM_ARRAY_TASK_ID

这将创建一个包含 100 个作业的作业数组。其中32个可以同时运行。如果您不需要/想要后者,您可以从#SBATCH参数中删除 %32 部分。为什么这样更好?如果您的任务是完全独立的,则没有真正需要将它们全部放在一项工作中。这样一来,只要任何地方都有可用的插槽,任务就可以运行。这应该将排队的时间减少到最低限度。

此外,使用作业数组很优雅,并且减少了调度程序的负载。与在 for 循环中提交的大量相同作业相比,您的管理员可能更喜欢拥有大型作业数组。


推荐阅读