【发布时间】:2021-07-10 17:06:06
【问题描述】:
我想在使用多个节点的 HPC 上运行一个简单的并行化 MPI python 代码。
SLURM 被设置为 HPC 的作业调度程序。 HPC 由 3 个节点组成,每个节点有 36 个内核。 Open MPI 和 MPICH 都可以作为 MPI 实现。
我要运行的代码如下:
import sys
import numpy as np
import socket
import time
from mpi4py.futures import MPIPoolExecutor
# Define simple function
def myFun(x):
time.sleep(5)
print('Process is running on host: %s' % (socket.gethostname()))
return x+2
if __name__ == '__main__':
timestamp1 = time.perf_counter()
# Create small set of random input data
dat = [np.random.rand(3, 2) for x in range(8)]
# Using mpi4py for multiprocessing
with MPIPoolExecutor(max_workers=8) as pool:
# Run function with myFun and dat as map operation
result = pool.map(myFun, dat)
timestamp2 = time.perf_counter()
delta_t = timestamp2 - timestamp1
print('Runtime of code: ', delta_t)
此代码非常简单,仅用于了解如何使其工作。该代码基于 Hristo 'away' Iliev 在此线程 Python: how to parallelizing a simple loop with MPI 中的建议答案,并进行了一些细微的更改。我真的很喜欢这段代码,因为我实际上需要重写的用例使用了多处理的池类。
我的默认 *.sbatch 文件基本上设置如下:
#!/bin/bash
# SLURM Setup -------------------------------------------------
#SBATCH --job-name=Test_MPI
#SBATCH --output=job.%j.out
#SBATCH --error=job.%j.err
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=9
#SBATCH --mem=1G
module load ...
eval "$(conda shell.bash hook)"
conda activate ...
srun -n 1 python -m mpi4py.futures stackExample2.py
在这种情况下,我保留 9 个处理器,因为我使用 1 个主进程和 8 个工作进程(使用 MPIPoolExecutor(max_workers=8) 定义)。当只是并行化它时,这工作正常。
当我想将此代码用于>36 个进程时,我需要能够在多个节点上运行它。但到目前为止,我还做不好。首先我只调整#SBATCH --nodes 和 --ntasks-per-node。在这种情况下,我设置节点 = 2 和 ntasks-per-node=5,因为我需要确保至少保留 9 个进程。检查 *.err 文件时,我得到了这个:
srun: Warning: can't run 1 processes on 2 nodes, setting nnodes to 1
它忽略了 --nodes =2 的设置,并继续执行,就像设置了 --nodes=1 和 --ntasks-per-node=9 一样。查看 *.out 文件时,该函数显然只打印了 hostname1。
我从各种来源阅读了很多帖子、示例和介绍。在大多数情况下,它们使用简单的 srun 命令,例如“srun python myprogram.py”。所以我尝试了:
srun python -m mpi4py.futures stackExample2.py
这次我的代码在两台主机上运行,但它在主机名 1 上运行了 5 次,在主机名 2 上运行了 5 次。这不是我想要的,因为我想使用主机 1 和主机 2 的处理器运行一次代码。
我尝试了各种其他可能性,包括使用 mpirun/mpiexec 代替 srun、-host 选项等,但仍然无法正确使用。这就提出了代码是否缺少某些东西的问题。
我是否需要更改代码才能在多个节点上使用进程? 还是我仍然使用错误的 srun 调用?
提前谢谢你!
【问题讨论】:
-
此功能在内部依赖于
MPI_Comm_spawn(),因此不太可能与srun一起使用,您应该改用mpirun。 -
@GillesGouaillardet 我尝试使用 mpirun。到目前为止,我能够在多个节点(在本例中为 2 个节点)上并行运行代码多次。但是我试图在使用位于两个节点上的进程时并行运行一次代码。
-
您需要
mpirun -np 1 ...才能开始一项任务。然后,假设mpi4py在后台使用的 MPI 库正确支持和检测 SLURM,MPI_Comm_spawn()应该在两个节点上生成任务。
标签: python parallel-processing mpi openmpi slurm