我的问题与这个问题类似
长话短说,我想在尽可能多的节点上使用所有可用的 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 个作业,而是 100 个作业,每个作业 1 个任务。
我无法完成 100 项独立任务有什么原因吗?我一开始就从根本上错了吗?我应该做 100 份工作而不是 100 项任务吗?
最佳答案
如果您通过 sbatch
提交该脚本,它将为该作业分配一个任务。在作业内部,srun
命令仅限于作业的资源。这就是为什么当您通过 sbatch
提交计算时,您的计算会按顺序运行。
如果您只是运行脚本,没有 sbatch
,则对 srun
的调用每次都会创建一个新作业(正如您已经注意到的),因此它不限于单个任务。
Is there a reason I can't do 100 independent tasks? Am I fundamentally wrong to begin with? Should I be doing 100 jobs instead of 100 tasks?
最后,您喜欢哪种方式有点个人喜好。您可以拥有一个包含 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个任务同时空闲。这意味着您可能会在队列中等待更长时间。
(在我看来)更好的方法是使用 job array :
#!/bin/bash
#SBATCH -a 0-99%32
worker_script.sh $SLURM_ARRAY_TASK_ID
这将创建一个包含 100 个作业的作业数组。其中 32 个可以同时运行。如果您不需要/不想要后者,只需从 #SBATCH
参数中删除 %32 部分即可。
为什么这样更好?如果您的任务是完全独立的,那么就没有必要将它们全部放在一项工作中。这样,只要任何地方有空闲槽,任务就可以立即运行。这应该可以将排队时间减少到最低限度。
此外,使用作业数组非常优雅,并且可以减少调度程序的负载。您的管理员可能更喜欢拥有大型作业数组,而不是在 for 循环中提交的大量相同作业。
关于hpc - Slurm - 如何使用所有可用的 CPU 来执行独立任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63526390/