mpi4py挂在主从代码中的spawn和hydra_pmi_代理僵尸中

2024-05-23 18:08:21 发布

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

我想知道是否有人看到我在mpi4py中遇到的问题:

这段代码有一个任务列表,它发送给从系统,并生成一个fortran可执行文件,以便在特定配置上运行。不过,fortran在每个任务之间执行的速度非常快。我不确定是什么原因造成的,但如果有人能发现问题,那将是一个很大的帮助。代码还可以在串行模式下运行配置,依次执行这些配置,而不是使用mpi4py,而且在这种模式下没有挂起。在

序列号的时间是:

real    0m12.323s
user    0m45.468s
sys    0m1.490s

对于以下mpi4py版本:

^{pr2}$

我注意到在代码运行时有很多hydra_pmi_proxy zombie在潜伏:

29770 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29772 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29784 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29795 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29796 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29797 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29810 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29815 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29820 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29825 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29830 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29835 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29836 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29837 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29838 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29855 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29860 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29865 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29866 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29878 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29880 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.01 hydra_pmi_proxy                              
29886 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29887 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29888 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29889 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29906 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29911 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29912 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29913 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29926 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29927 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy                              
29928 cor22     20   0       0      0      0 Z   0.0  0.0   0:00.00 hydra_pmi_proxy 

我不知道为什么会这样。在

我原以为这可能是由于fortran代码写入stdout时出现的一些I/o问题,但当我更改代码使其不再有效时,它就不再起作用了。而且,fortran代码似乎已经执行并完成了,而挂起的部分位于python脚本中。代码在一个本地集群的节点上运行得更好,它最终在我的本地机器上完成了它应该做的事情,但是使用mpi4py的想法是为了加快速度,而这已经减慢了它们的速度,所以我相当挠头。。。在

在super中,所有的print语句都会在循环的最后被抛出_硕士.py,而不是随着跑步的进行,这让我很困惑

下面是代码的虚拟版本,它与我运行时遇到的问题相同:

mpirun -np 1 python3 ./super_master.py 

谢谢你的任何见解和抱歉的长帖子!在

超级_硕士.py公司名称:

#! /usr/bin/env python3

import os
from mpi4py import MPI
import sys

comm = MPI.COMM_WORLD


for x in range(0, 3):
   new_comm=comm.Spawn(sys.executable,args=["master.py"],maxprocs=1)
   new_comm.Barrier()
   new_comm.Disconnect()
   print("finnished run ",x)
   os.system('{}'.format('rm */*out*'))

在硕士.py公司名称:

    #! /usr/bin/env python3

from mpi4py import MPI
import numpy as np
import sys
import os
import time


comm = MPI.COMM_WORLD
rank = MPI.COMM_WORLD.Get_rank()
commp = MPI.Comm.Get_parent()

processes=4
tasks=([StopIteration] * (processes))+[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

new_comm=comm.Spawn("/PATH/TO/slave.py", args=[],maxprocs=processes)

status=MPI.Status()


while tasks:
    new_comm.recv(source=MPI.ANY_SOURCE, status=status)
    data=tasks.pop()
    print("on master received source: ",status.Get_source())
    print("On master sending: ",data," to:",status.Get_source())
    new_comm.send(obj=data,dest=status.Get_source())
    print("On master sent: ",data," to:",status.Get_source())

print("Finished All",rank)
new_comm.Barrier()
print("after barrier",rank)
print("rank", rank,"task",tasks)
commp.Barrier()
commp.Disconnect()

在从属.py公司名称:

#! /usr/bin/env python3

from mpi4py import MPI
import numpy as np
import sys
import os
import time

comm = MPI.Comm.Get_parent()
rank = comm.Get_rank()
cwd=os.getcwd()

print("slave", rank," entering loop")

for task in iter(lambda: comm.sendrecv(data,dest=0), StopIteration):
    print("slave ", rank," recvd data", task)
    print("slave ", rank," going to sleep")
    directory=os.path.join(cwd,str(task))
    os.chdir(directory)
    info = MPI.Info.Create()
    info.update({"wdir": directory})
    print("before spawn in slave:", rank)
    new_comm=MPI.COMM_SELF.Spawn("/PATH/TO/FORTRAN_EXECUTABLE",
                  args=[],maxprocs=4,info=info)
    print("after spawn in slave:", rank)

    new_comm.Barrier()
    new_comm.Disconnect()
    info.Free()
    os.system('{}'.format('sleep '+str(task*1.5)))
    os.chdir(cwd)


comm.Barrier()
comm.Disconnect()

编辑:

嗨,伙计们

fortran进程似乎在我的机器上运行,而python似乎在休眠状态下运行:

17530 cor22     20   0  190044  25868  10056 S   0.0  0.0   0:01.83 python3                                      
17531 cor22     20   0  189924  25832  10020 S   0.0  0.0   0:01.33 python3                                      
17532 cor22     20   0  189920  25844  10040 S   0.0  0.0   0:01.24 python3                                      
17533 cor22     20   0  190036  25832  10024 S   0.0  0.0   0:01.82 python3                                      
17534 cor22     20   0  190040  25832  10024 S   0.0  0.0   0:01.32 python3

这在集群上似乎没有发生。看来这正是事情放缓的原因。如果有人对如何防止这种行为有任何想法,我会非常乐意听到的!在

在集群上,如果任务列表很大,我可以获得与串行版本相比相当好的加速。如果任务列表很小(<;20左右),则没有太多的加速,当它第一次启动时,它似乎有点卡住了,但是当它在任务列表中移动时,如果列表足够大,它就会回到正轨上。我也不知道为什么会这样,但如果有人有什么建议,我想听听。在

16 cpu群集上运行4个派生进程的计时,每个进程都有一个从进程,在4个进程上运行fortran代码:

Tasks    mpi4py       serial
10       0m28.109s    0m30.472s
20       0m47.166s    1m6.380s
30       0m48.586s    1m38.161s
40       0m56.258s    2m10.056s
50       1m5.508s     2m10.056s
100      1m31.854s    5m22.126s
200      2m18.955s    9m4.022s

Tags: 代码importnewgetosmpi4pypython3hydra