作业脚本中频繁执行mpirun导致slurm请求过于频繁的问题

less than 1 minute read

Published:

记录近日碰到的一个问题。

问题表现

一模一样的程序,一个月前还好好的,最近重新提交作业跑起来就不太对劲,具体两个表现:

  1. 运行速度特别慢,有时候甚至直接空转无输出。
  2. 使用squeue等指令时经常出现request too frequently的提示。

一些测试

  1. 最开始还不知道这两个表现其实是同一个问题。想先解决1,给作业加了一堆计时代码,换节点换编译器测试都没搞明白,一会儿跑的时间正常一会儿又不正常。
  2. 想解决2,客服反馈说账户作业存在高频slurm请求。在管理员那边的后台Log里会显示为很多的“REQUEST HET JOB ALLOC INFO”和“REQUEST JOB STEP CREATE”日志。但问题是我的程序里面完全没写过任何sbatch,squeue等指令,客服也不懂,害我只能分割demo一遍遍测试,测了半天又说同节点有其他作业运行干扰结果。
  3. 最后偶然在一次小demo的测试中发现只运行mpirun也会在日志中出现srun: request too frequently,才让我把一切都想明白。

问题根源

提交的作业脚本中会循环执行mpirun指令,频率太高(大约7秒1次,并且四十多个作业同时跑,会叠加频率),而每次执行mpirun时,均自动会引发srun指令(原因未知,可能是需要和slurm系统申请进程资源)。

srun指令属于slurm指令,高频调用时会触发频率限制,不仅手动执行squeue等会提示request too frequently,作业中运行的程序也会同样受到限制而需要等待重试。因此,运行速度就在这里卡住了,如果一直在等待重试,就会表现出空转的情况。

解决方案

  1. 最简单:降频,我在作业脚本中每次运行mpirun前添加等待两三秒的指令就改善了不少。形象来说就是一大堆车都想快速通过十字路口时就一团混乱谁也过不去,但是加上一些等待时间后就全都可以顺利通过了,虽然对于每个车来说过路口的时间比最理想的状态慢了一点。
  2. 不知道是否可行:在循环调用的mpirun时我用python/shell做的流程控制,以python为例,先写一个run.sh脚本,其中含有单次mpirun,在python脚本中循环调用subprocess.run执行这个脚本。如果在运行python脚本之初就配置好mpi环境,每次调用时只传递这一个环境给run.sh脚本,就不再需要在每个循环中都调mpirun,而只需要在执行python脚本时调用一次即可。
  3. 修改需要mpirun的程序,使得需要的循环可以放在mpi_init里面。这个我干不来,别人写好的巨型程序,我半天都找不到mpi入口。