Python 在使用mpi4py的并行环境中,在for循环中使用Popen的系统调用在第一次迭代后失败

Python 在使用mpi4py的并行环境中,在for循环中使用Popen的系统调用在第一次迭代后失败,python,python-2.7,subprocess,mpi,hpc,Python,Python 2.7,Subprocess,Mpi,Hpc,下面的一个简单脚本将显示,Popen在循环中发送“ECHO”的最简单情况下仅在第一次迭代中有效(在带有RHEL 5的IBM iDataplex x86系统上运行)。在第一次迭代中,它可以对Popen进行尽可能多的调用,而不会出现任何问题,但在此之后,只有4个进程可以访问Popen。因此,如果有一个调用需要将信息传递给所有进程(例如allgather,因此需要一个屏障),则不会传递任何信息,因为除了4个进程外,所有进程的stdo=''(空字符串)。如果使用while循环,那么它将永远不会退出,因为

下面的一个简单脚本将显示,Popen在循环中发送“ECHO”的最简单情况下仅在第一次迭代中有效(在带有RHEL 5的IBM iDataplex x86系统上运行)。在第一次迭代中,它可以对Popen进行尽可能多的调用,而不会出现任何问题,但在此之后,只有4个进程可以访问Popen。因此,如果有一个调用需要将信息传递给所有进程(例如allgather,因此需要一个屏障),则不会传递任何信息,因为除了4个进程外,所有进程的stdo=''(空字符串)。如果使用while循环,那么它将永远不会退出,因为除了4个进程外,其他所有进程都会被捕获在循环中。这是专门针对这个系统的吗?这里的任何人都知道这是怎么回事吗

如果在4个进程或更少的进程上运行,它可以完全正常工作

from mpi4py import MPI
from subprocess import Popen, PIPE

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
num_proc = comm.Get_size()
if rank == 0:
    start_time = MPI.Wtime()
for i in range(10):
    stdo = ''
    cmd = ['echo','HELLO']
    # while stdo == '':
    a = Popen(cmd, shell=False, stdout=PIPE, stdin=PIPE)
    stdo, stder = a.communicate("Input")
    a.wait()
    if stdo != "HELLO\n":
        print "Rank", rank, "ITER: ", i, "OUT: ", stdo
    # comm.barrier()
    # r = comm.allgather(stdo) #Causes infinite loop because any number above 4 processors after the first iteration will never exit the while loop
#if any collective operation or barrier is removed, it will work properly
if rank == 0:
    print "Num Proc is", num_proc, "Time is",  MPI.Wtime() - start_time
Popen的第一个参数(传递给bash的内容)必须是字符串。我也总是做shell=True。如果您是编写脚本的人,那么您知道代码应该做什么,因此可以安全地运行

cmd = 'echo HELLO'
a = Popen(cmd, shell=True, stdout=PIPE, stdin=PIPE)
Popen的第一个参数(传递给bash的内容)必须是字符串。我也总是做shell=True。如果您是编写脚本的人,那么您知道代码应该做什么,因此可以安全地运行

cmd = 'echo HELLO'
a = Popen(cmd, shell=True, stdout=PIPE, stdin=PIPE)

我不认为这是问题所在,但是…
communicate
隐式调用
wait
,因此没有理由自己调用它。有许多
ulimit
设置可能会导致这种情况。最明显的是
-u
,它限制了普通用户可用的进程数量,但任何其他因素都可能导致它。你在任何地方检查
a.returncode
吗?我认为这不是问题所在,但是…
communicate
隐式调用
wait
,因此没有理由自己调用它。有许多
ulimit
设置可能导致此问题。最明显的是
-u
,它限制了普通用户可用的进程数量,但任何其他因素都可能导致它。您是否在任何地方检查
a.returncode