在 Slurm 上使用 MPI,有没有办法在不同的作业之间发送消息?

Using MPI on Slurm, is there a way to send messages between separate jobs?

我刚开始使用 MPI (mpi4py) 和 Slurm。我需要 运行 大约 50000 个任务,因此为了遵守管理员设置的大约 1000 个任务的限制,我一直 运行 像这样设置它们:

sbrunner.sh:

#!/bin/bash
for i in {1..50}
do
   sbatch m2slurm.sh $i
   sleep 0.1
done

m2slurm.sh:

#!/bin/bash
#SBATCH --job-name=mpi
#SBATCH --output=mpi_50000.out
#SBATCH --time=0:10:00
#SBATCH --ntasks=1000

srun --mpi=pmi2 --output=mpi_50k.out python par.py data_50000.pkl  > py.out 2> .err

par.py(省略无关内容):

offset = (int(sys.argv[2])-1)*1000
comm = MPI.COMM_WORLD
k = comm.Get_rank()
d = data[k+offset]

# ... do something with d ...

allresults = comm.gather(result, root=0)
comm.Barrier()
if k == 0:
    print(allresults)
  1. 这是绕过 1000 个任务限制的明智方法吗?
  2. 是否有更好的方法来合并结果?我现在有 50 个文件必须手动连接。有没有一些comm_world可以存在于不同的工作之间?

这看起来是 job arrays 的完美候选者。数组中的每个作业都相同,但 $SLURM_ARRAY_TASK_ID 环境变量除外。您可以像使用命令行变量一样使用它。

(您需要检查您的系统管理员是否将 MaxArraySize 设置得足够高。检查 scontrol show config | grep MaxArraySize 的输出)

我认为您需要让您的应用程序将工作分配给 1000 个任务(MPI 等级),然后使用 MPI 集体调用(即 MPI_ReduceMPI_AllReduce 调用合并结果。

尝试绕过限制对您没有帮助,因为您开始的作业将一个接一个地排队。

Jobs 数组将提供与您在提供的批处理文件中所做的类似的行为。因此,您的应用程序仍然必须能够处理仅给定 N 个任务(MPI 等级)的所有数据项。

无需合并以确保所有其他作业都已完成查看 slurm 作业依赖参数 https://hpc.nih.gov/docs/job_dependencies.html

编辑:

您可以使用作业依赖创建一个新作业,该作业将 运行 在所有其他作业完成后进行,此作业将收集结果并将它们合并到一个大文件中。我仍然相信你过度思考了明显的解决方案 make rank 0 (master collect all results and save them to the disk)

50000 个任务是什么意思?

  1. 你是说一个 MPI 作业有 50000 个 MPI 任务吗?
  2. 或者你的意思是 50000 个独立的串行程序?
  3. 或者您指的是(MPI 作业数)*(每个作业的任务数)= 5000
  4. 的任意组合

if 1), 那么,请咨询您的系统管理员。当然,您可以在多个 SLURM 作业中分配 50000 个插槽,手动等待它们同时全部 运行,然后 mpirun 您的应用 在 SLURM 之外 。这既丑陋又低效,如果这被视为试图规避系统限制,您可能会遇到麻烦。

如果 2) 或 3),那么作业数组是一个不错的选择。如果我对您的应用的理解正确,您将需要一个额外的 post 处理步骤,以便 concatenate/merge 您的所有输出都在一个文件中。

如果你选择 3),你将需要找到最佳点 (一般来说,50000 个串行程序比 50 个 1000 个任务的 MPI 作业或一个 50000 个任务的 MPI 程序更有效但是合并 50000 个文件的效率低于合并 50 个文件(或根本不合并任何文件) )

如果您不能在前端节点上进行 post 处理,那么您可以使用作业依赖性来启动它所有计算完成后