HPC SLURM 和批量调用 Master-Worker 系统中支持 MPI 的应用程序

HPC SLURM and batch calls to MPI-enabled application in Master-Worker system

我正在尝试使用资源管理器 SLURM 在 HPC 中实现某种主从系统,我正在寻找有关如何实现此类系统的建议。

我必须使用一些 python 代码来扮演 Master 的角色,在每批计算之间 Master 将 运行 2 秒自己的计算,然后发送一个新一批工作交给工人。每个 Worker 必须 运行 在 HPC 的单个节点上有一个外部可执行文件。外部可执行文件 (Gromacs) 本身是启用 MPI 的。将有 ~25 个 Worker 和许多批次的计算。

我对 atm 的想法(另见下文进一步编辑):

我目前正在尝试的:

  1. 在我通过 sbatch run.sh
  2. 调用的 bash 脚本中,通过 SLURM 分配尽可能多的 MPI 任务
#!/bin/bash -l
#SBATCH --nodes=4
#SBATCH --ntasks=4
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=12

module load required_env_module_for_external_executable

srun python my_python_code.py
  1. 在 python my_python_code.py 当前 MPI rank 内捕获,并使用 rank/node 0 到 运行 Master python code
from mpi4py import MPI

name = MPI.Get_processor_name()
rank = MPI.COMM_WORLD.Get_rank()
size = MPI.COMM_WORLD.Get_size()

if rank == 0:  # Master
    run_initialization_and_distribute_work_to_Workers()

else:  # Workers
    start_Worker_waiting_for_work()
  1. 在 Worker 的 python 代码中,使用 MPI.COMM_SELF.Spawn()
  2. 启动外部(启用 MPI)应用程序
def start_Worker_waiting_for_work():

    # here we are on a single node

    executable = 'gmx_mpi'
    exec_args = 'mdrun -deffnm calculation_n'

    # create some relationship between current MPI rank
    # and the one the executable should use ?

    mpi_info = MPI.Info.Create()
    mpi_info.Set('host',  MPI.Get_processor_name())
    commspawn = MPI.COMM_SELF.Spawn(executable, args=exec_args,
                                    maxprocs=1, info=mpi_info)

    commspawn.Barrier()
    commspawn.Disconnect()

    res_analysis = do_some_analysis()  # check what the executable produced

    return res_analysis

我想解释一下:

  1. 有人可以确认此方法似乎对实现所需系统有效吗?或者很明显这没有机会工作?如果是,请问为什么?

  2. 我不确定 MPI.COMM_SELF.Spawn() 是否会使可执行文件继承 SLURM 资源分配。如果没有,如何解决这个问题?我认为 MPI.COMM_SELF.Spawn() 是我要找的,但我不确定。

  3. 外部可执行文件需要加载一些 environment modules。如果它们在 sbatch run.sh 加载,当我从 MPI.COMM_SELF.Spawn()my_python_code.py 调用时它们是否仍然加载?

  4. 作为一种稍微不同的方法,是否可以有类似pre-allocations/reservations的东西来为工人预订资源,然后使用MPI.COMM_WORLD.Spawn()和pre-allocations/reservations ?目标也是避免在每个新批次进入 SLURM 队列,因为这可能会浪费大量时钟时间(因此会在一开始就预订所有需要的资源)。

  5. 因为 python Master 必须始终保持活动状态,所以 SLURM 作业依赖项在这里没有用,是吗?

非常感谢您提供的任何帮助!

编辑:简化工作流程

为了让我的问题简单化,我首先忽略了我实际上让 Workers 进行一些分析的事实。但正如 Gilles Gouillardet 所建议的那样,这项工作可以使用 OpenMP 多处理在 Master 上完成。它执行得足够快。

那么工人确实是必要的,因为每个任务在单个 Worker/Node.

上大约需要 20-25 分钟

我还添加了一些关于维护我自己的任务队列以发送到 SLURM 队列并最终发送到 Workers 的内容,以防任务数量 t 会超过几个 tens/hundreds 职位。这也应该在将来为不同的应用程序重新使用此代码时提供一些灵活性。

大概这样就好了。我会尝试这样做并更新这些行。编辑:它工作正常。

乍一看,这对我来说太复杂了:

  • 从站和 GROMACS 之间没有通信
  • 有一些 master/slave 通信,但 MPI 真的有必要吗?
  • 奴隶真的有必要吗? (例如主进程是否可以简单地序列化计算然后直接启动GROMACS?)

一种更简单的架构是在您的前端有一个进程,这样就可以:

  1. 准备 GROMACS 输入
  2. sbatch gromacs(连续开始几个工作)
  3. 等待 GROMACS 作业完成
  4. 分析 GROMACS 输出
  5. 重新迭代或退出

如果从服务器正在执行一些您不想在主服务器上序列化的工作,您可以使用共享文件系统上的文件来替换 MPI 通信吗?在这种情况下,您可以在执行 GROMACS 之前和之后在 GROMACS 作业中的计算节点上进行计算。如果没有,也许基于 TCP/IP 的通信可以解决问题。