在 Slurm 中使用 Python 多处理,以及我需要哪种 ntasks 或 ncpus 组合

Using Python multiprocessing in Slurm, and which combination of ntasks or ncpus I need

我正尝试在 slurm 集群上 运行 一个 python 脚本,我正在使用 python 的内置 multiprocessing 模块。

我使用的设置非常简单,出于测试目的,示例是:

len(arg_list)
Out[2]: 5

threads = multiprocessing.Pool(5)
output = threads.map(func, arg_list)

所以 funcarg_list 中的 5 个参数上并行应用了 5 次。我想知道的是如何在 slurm 中分配正确数量的 cpu's/tasks 以使其按预期工作。这就是我的 slurm 批处理脚本的相关部分:

#!/bin/bash

# Runtime and memory
#SBATCH --time=90:00:00
#SBATCH --mem-per-cpu=2G

# For parallel jobs
#SBATCH --cpus-per-task=10
##SBATCH --nodes=2
#SBATCH --ntasks=1
##SBATCH --ntasks-per-node=4  

#### Your shell commands below this line ####

srun ./script_wrapper.py 'test'

如您所见,目前我有 ntasks=1cpus-per-task=10。请注意,主要的 func 包含一个 scipy 例程,它倾向于在两个内核上 运行 (即使用 200% cpu 用法,这就是为什么我想要 10 cpus而不是 5)。

这是为我的目的分配资源的正确方法吗,因为目前作业花费的时间比预期的要长很多(更像是在单个线程中 运行ning)。

我需要改为设置 ntasks=5 吗?因为我从在线文档中得到的印象是 ntasks=5 反而会调用 srun ./script_wrapper.py 'test' 五次,这不是我想要的。我的假设是否正确?

此外,有没有一种方法可以轻松检查 CPU 使用情况以及 multiprocessing.Pool 调用的 python 任务的所有进程 ID?目前我正在尝试使用 sacct -u <user> --format=JobID,JobName,MaxRSS,Elapsed,AveCPU,但是 AveCPUMaxRSS 字段由于某种原因总是空着(?),当我将第一个脚本视为一个过程时,我看不到应该由多处理调用的其他 5 个。示例:

       JobID    JobName     MaxRSS    Elapsed     AveCPU 
------------ ---------- ---------- ---------- ---------- 
16260892             GP              00:13:07            
16260892.0   script_wr+              00:13:07            

我认为您的 Slurm 任务分配是正确的。 Python 的多处理只会在一台机器上 运行,在我看来你在一个节点上正确分配了 10 个 CPU。可能导致此问题的原因是多处理的 Pool.map 默认情况下对输入列表的 "chunks" 起作用,而不是一次对一个元素起作用。它这样做是为了在任务较短时最小化开销。要强制多处理一次处理列表的一个元素,请将 map 的 chunksize 参数设置为 1,例如

threads.map(func, arglist, 1)

有关详细信息,请参阅 multiprocessing documentation

因为您说您使用的是 SciPy 的多线程版本,您可能还想检查底层库的相关线程级别。例如,如果您的 SciPy 是针对英特尔数学核心函数库构建的,请尝试设置 OMP_NUM_THREADSMKL_NUM_THREADS environment variables 以确保每个进程使用不超过 2 个线程并充分利用(而不是过度使用)分配给您的 SLURM 资源。

编辑:sacct 只会为 s运行 直接启动的任何进程提供 运行ning 时间,而不会为任何子进程提供。因此,在您的情况下,您只能从单个 s运行 命令中获得一个进程。要监控子流程,您可能需要查看在系统级别运行的监控工具,而不是通过 Slurm。