在 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)
- 这是绕过 1000 个任务限制的明智方法吗?
- 是否有更好的方法来合并结果?我现在有 50 个文件必须手动连接。有没有一些comm_world可以存在于不同的工作之间?
这看起来是 job arrays 的完美候选者。数组中的每个作业都相同,但 $SLURM_ARRAY_TASK_ID 环境变量除外。您可以像使用命令行变量一样使用它。
(您需要检查您的系统管理员是否将 MaxArraySize 设置得足够高。检查 scontrol show config | grep MaxArraySize
的输出)
我认为您需要让您的应用程序将工作分配给 1000 个任务(MPI 等级),然后使用 MPI 集体调用(即 MPI_Reduce
或 MPI_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 个任务是什么意思?
- 你是说一个 MPI 作业有 50000 个 MPI 任务吗?
- 或者你的意思是 50000 个独立的串行程序?
- 或者您指的是(MPI 作业数)*(每个作业的任务数)= 5000
的任意组合
if 1), 那么,请咨询您的系统管理员。当然,您可以在多个 SLURM 作业中分配 50000 个插槽,手动等待它们同时全部 运行,然后 mpirun
您的应用 在 SLURM 之外 。这既丑陋又低效,如果这被视为试图规避系统限制,您可能会遇到麻烦。
如果 2) 或 3),那么作业数组是一个不错的选择。如果我对您的应用的理解正确,您将需要一个额外的 post 处理步骤,以便 concatenate/merge 您的所有输出都在一个文件中。
如果你选择 3),你将需要找到最佳点
(一般来说,50000 个串行程序比 50 个 1000 个任务的 MPI 作业或一个 50000 个任务的 MPI 程序更有效但是合并 50000 个文件的效率低于合并 50 个文件(或根本不合并任何文件) )
如果您不能在前端节点上进行 post 处理,那么您可以使用作业依赖性来启动它在所有计算完成后
我刚开始使用 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)
- 这是绕过 1000 个任务限制的明智方法吗?
- 是否有更好的方法来合并结果?我现在有 50 个文件必须手动连接。有没有一些comm_world可以存在于不同的工作之间?
这看起来是 job arrays 的完美候选者。数组中的每个作业都相同,但 $SLURM_ARRAY_TASK_ID 环境变量除外。您可以像使用命令行变量一样使用它。
(您需要检查您的系统管理员是否将 MaxArraySize 设置得足够高。检查 scontrol show config | grep MaxArraySize
的输出)
我认为您需要让您的应用程序将工作分配给 1000 个任务(MPI 等级),然后使用 MPI 集体调用(即 MPI_Reduce
或 MPI_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 个任务是什么意思?
- 你是说一个 MPI 作业有 50000 个 MPI 任务吗?
- 或者你的意思是 50000 个独立的串行程序?
- 或者您指的是(MPI 作业数)*(每个作业的任务数)= 5000 的任意组合
if 1), 那么,请咨询您的系统管理员。当然,您可以在多个 SLURM 作业中分配 50000 个插槽,手动等待它们同时全部 运行,然后 mpirun
您的应用 在 SLURM 之外 。这既丑陋又低效,如果这被视为试图规避系统限制,您可能会遇到麻烦。
如果 2) 或 3),那么作业数组是一个不错的选择。如果我对您的应用的理解正确,您将需要一个额外的 post 处理步骤,以便 concatenate/merge 您的所有输出都在一个文件中。
如果你选择 3),你将需要找到最佳点 (一般来说,50000 个串行程序比 50 个 1000 个任务的 MPI 作业或一个 50000 个任务的 MPI 程序更有效但是合并 50000 个文件的效率低于合并 50 个文件(或根本不合并任何文件) )
如果您不能在前端节点上进行 post 处理,那么您可以使用作业依赖性来启动它在所有计算完成后