Python:如何在多个节点上运行简单的MPI代码?

2024-04-28 13:28:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在HPC上使用多个节点运行一个简单的并行MPI python代码

SLURM被设置为HPC的作业计划程序。HPC由3个节点组成,每个节点有36个核心。 openmpi和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中的建议答案,并做了一些小改动。我非常喜欢这段代码,因为我实际上需要重写的用例使用了多处理的pool类

我的默认*.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和--ntask。在本例中,我将节点设置为2,每个节点的ntasks设置为5,因为我需要确保至少保留9个进程。在检查*.err文件时,我得到以下信息:

srun: Warning: can't run 1 processes on 2 nodes, setting nnodes to 1

它忽略设置了--nodes=2,并继续执行perfrom,就好像设置了--nodes=1和--ntasks per nodes=9一样。查看*.out文件时,函数显然只打印hostname1

我读了很多文章,例子和介绍,从各种来源。在大多数情况下,它们使用简单的srun命令,如“srun python myprogram.py”。所以我试着:

srun python -m mpi4py.futures stackExample2.py

这次我的代码在两台主机上都运行,但在hostname1上运行了5次,在hostname 2上运行了5次。这并不是我的初衷,因为我想使用host1和host2的处理器运行一次代码

我尝试了其他各种可能性,包括使用mpirun/mpiexec而不是srun、-host选项等,但仍然无法正确使用。这就提出了一个问题:代码是否缺少某些内容

为了在多个节点上使用流程,是否需要更改代码? 还是我仍然使用错误的srun调用

提前谢谢你


Tags: 代码import节点time进程asmpi4pyhpc
1条回答
网友
1楼 · 发布于 2024-04-28 13:28:57

我找到了解决我问题的办法

首先,您可以在使用来自多个主机的处理器时运行此代码一次

很明显,我对编写用于并行或分布式执行的代码非常陌生。我缺乏经验,这让我走错了路,因为我认为一切都安排得很好

Open MPI实现工作不正常。我最好的猜测是,在设置或编译它时出现了一些错误。这很难实现,因为:

  1. 似乎检测到SLURM在job&;正确地进行资源调度
  2. 可以在单个主机上并行执行代码
  3. 能够在多台主机上同时并行运行代码,彼此独立

我看到了一些使用简单HelloWorld代码(主要是C和Python)的示例,显示了运行分布式代码的一般可能性。但我无法重现这些示例提供的结果。我确保使用相同的代码和mpirun/mpiexec或srun调用,但返回如下内容:

Hello, I'm rank 0 of 3 running on host1
Hello, I'm rank 1 of 3 running on host2
Hello, I'm rank 2 of 3 running on host1
Hello, I'm rank 3 of 3 running on host2

我的结果如下:

Hello, I'm rank 0 of 3 running on host1
Hello, I'm rank 0 of 3 running on host2
Hello, I'm rank 0 of 3 running on host1
Hello, I'm rank 0 of 3 running on host2

这是我意识到我的实现有问题的时候。我真的不能准确地指出确切的问题是什么。我看到一些帖子使用mca标志建立了一条预先定向的通信线路,但实际上没有任何效果。 正如我在第一个问题中提到的,我们有两个MPI实现(OpenMPI v3.1.3(默认加载)、MPICH 3.3),我们可以作为模块加载

我切换到MPICH,并使用mpiexec调用运行完全相同的HelloWorld代码,现在得到了预期的结果。随后,我运行了最初问题中的代码,我能够使用来自多个主机的处理器运行它一次。尽管我找到了一个解决方案,但我会联系HPC管理员,并尝试找出我们的OpenMPI实现的错误

相关问题 更多 >