在 slurm 上使用 python 的多处理
Using python's multiprocessing on slurm
我正在尝试 运行 在 slurm 上编写一些并行代码,其中不同的进程不需要通信。我天真地使用了 python 的 slurm 包。但是,我似乎只在一个节点上使用 cpu。
例如,如果我有 4 个节点,每个节点有 5 个 cpu,我只会同时 运行 5 个进程。我如何在不同的节点上告诉多处理 运行?
python 代码如下所示
import multiprocessing
def hello():
print("Hello World")
pool = multiprocessing.Pool()
jobs = []
for j in range(len(10)):
p = multiprocessing.Process(target = run_rel)
jobs.append(p)
p.start()
问题和类似,但是没有详细解决
您当前的代码将在您启动它的单个节点上,在 5 个处理器上 运行 执行 10 次。它现在与 SLURM 无关。
您必须 SBATCH
SLURM 的脚本。
如果您想 运行 使用 SLURM 在 5 个内核上使用此脚本,请像这样修改脚本:
#!/usr/bin/python3
#SBATCH --output=wherever_you_want_to_store_the_output.log
#SBATCH --partition=whatever_the_name_of_your_SLURM_partition_is
#SBATCH -n 5 # 5 cores
import sys
import os
import multiprocessing
# Necessary to add cwd to path when script run
# by SLURM (since it executes a copy)
sys.path.append(os.getcwd())
def hello():
print("Hello World")
pool = multiprocessing.Pool()
jobs = []
for j in range(len(10)):
p = multiprocessing.Process(target = run_rel)
jobs.append(p)
p.start()
然后用
执行脚本
sbatch my_python_script.py
在其中一个安装了 SLURM 的节点上
然而,这也会将您的作业分配给单个节点,因此速度将与您 运行 在单个节点上的速度完全相同。
我不知道当你只有 5 个进程时,你为什么要 运行 它在不同的节点上。在一个节点上 运行 会更快。如果您在 python 脚本的开头分配超过 5 个核心,则 SLURM 将为您分配更多节点。
提示:
您需要了解 SLURM 中的 core,thread,socket,CPU,node,task,job,jobstep
是什么。
如果你的脚本之间完全没有交互。只需使用 :
srun -n 20 python serial_script.py
SLURM 会自动为您分配资源。
如果你想 运行 4 个节点上的 4 个任务,每个任务使用 5 个核心。您可以使用此命令:
srun -n 4 -c 5 -N 4 -cpu_bind verbose,nodes python parallel_5_core_script.py
它将在 4 个节点 (-N 4
) 上 运行 4 个任务 (-n 4
)。每个任务将拥有 5 个核心的资源 (-c 5
)。 -cpu_bind verbose,nodes
选项表示每个任务会在每个节点上运行(nodes
),实际的cpu_bind会被打印出来(verbose
)。
但是,如果您的 SLURM 配置与我的不同,CPU 绑定可能会出现一些奇怪的行为。有时这很棘手。 python 的 multiprocessing
模块似乎不能很好地与 SLURM 的资源管理一起工作,如您的 link.
中所示
dask 在这些情况下非常有用。它通过 dask-jobqueue 与 SLURM 有一个很好的接口。我强烈推荐它。
我正在尝试 运行 在 slurm 上编写一些并行代码,其中不同的进程不需要通信。我天真地使用了 python 的 slurm 包。但是,我似乎只在一个节点上使用 cpu。
例如,如果我有 4 个节点,每个节点有 5 个 cpu,我只会同时 运行 5 个进程。我如何在不同的节点上告诉多处理 运行?
python 代码如下所示
import multiprocessing
def hello():
print("Hello World")
pool = multiprocessing.Pool()
jobs = []
for j in range(len(10)):
p = multiprocessing.Process(target = run_rel)
jobs.append(p)
p.start()
问题和
您当前的代码将在您启动它的单个节点上,在 5 个处理器上 运行 执行 10 次。它现在与 SLURM 无关。
您必须 SBATCH
SLURM 的脚本。
如果您想 运行 使用 SLURM 在 5 个内核上使用此脚本,请像这样修改脚本:
#!/usr/bin/python3
#SBATCH --output=wherever_you_want_to_store_the_output.log
#SBATCH --partition=whatever_the_name_of_your_SLURM_partition_is
#SBATCH -n 5 # 5 cores
import sys
import os
import multiprocessing
# Necessary to add cwd to path when script run
# by SLURM (since it executes a copy)
sys.path.append(os.getcwd())
def hello():
print("Hello World")
pool = multiprocessing.Pool()
jobs = []
for j in range(len(10)):
p = multiprocessing.Process(target = run_rel)
jobs.append(p)
p.start()
然后用
执行脚本sbatch my_python_script.py
在其中一个安装了 SLURM 的节点上
然而,这也会将您的作业分配给单个节点,因此速度将与您 运行 在单个节点上的速度完全相同。
我不知道当你只有 5 个进程时,你为什么要 运行 它在不同的节点上。在一个节点上 运行 会更快。如果您在 python 脚本的开头分配超过 5 个核心,则 SLURM 将为您分配更多节点。
提示:
您需要了解 SLURM 中的 core,thread,socket,CPU,node,task,job,jobstep
是什么。
如果你的脚本之间完全没有交互。只需使用 :
srun -n 20 python serial_script.py
SLURM 会自动为您分配资源。
如果你想 运行 4 个节点上的 4 个任务,每个任务使用 5 个核心。您可以使用此命令:
srun -n 4 -c 5 -N 4 -cpu_bind verbose,nodes python parallel_5_core_script.py
它将在 4 个节点 (-N 4
) 上 运行 4 个任务 (-n 4
)。每个任务将拥有 5 个核心的资源 (-c 5
)。 -cpu_bind verbose,nodes
选项表示每个任务会在每个节点上运行(nodes
),实际的cpu_bind会被打印出来(verbose
)。
但是,如果您的 SLURM 配置与我的不同,CPU 绑定可能会出现一些奇怪的行为。有时这很棘手。 python 的 multiprocessing
模块似乎不能很好地与 SLURM 的资源管理一起工作,如您的 link.
dask 在这些情况下非常有用。它通过 dask-jobqueue 与 SLURM 有一个很好的接口。我强烈推荐它。