Python h5py、子流程和mpirun之间的奇怪交互
似乎导入h5py会阻止使用子流程运行mpi任务 考虑以下代码:Python h5py、子流程和mpirun之间的奇怪交互,python,python-3.x,subprocess,mpi,h5py,Python,Python 3.x,Subprocess,Mpi,H5py,似乎导入h5py会阻止使用子流程运行mpi任务 考虑以下代码: #!/usr/bin/python3 #import h5py import subprocess result=subprocess.run(['mpirun','-np','2','uptime'],shell=False) print(result.returncode) import h5py import os os.system('env | grep PMIX') 注释第一行后,输出如下所示: 15:44:
#!/usr/bin/python3
#import h5py
import subprocess
result=subprocess.run(['mpirun','-np','2','uptime'],shell=False)
print(result.returncode)
import h5py
import os
os.system('env | grep PMIX')
注释第一行后,输出如下所示:
15:44:04 up 5 days, 6:34, 4 users, load average: 29,16, 29,89, 25,09
15:44:04 up 5 days, 6:34, 4 users, load average: 29,16, 29,89, 25,09
0
1
如果取消对第一行的注释,则输出如下所示:
15:44:04 up 5 days, 6:34, 4 users, load average: 29,16, 29,89, 25,09
15:44:04 up 5 days, 6:34, 4 users, load average: 29,16, 29,89, 25,09
0
1
未执行任何操作,未打印任何错误消息,返回代码为1
一切都在Ubuntu 19.10上进行了测试。
在Ubuntu 18.04上没有这样的问题
可能是因为h5py在18.04中与串行hdf5连接,在19.04中与并行hdf连接
它是一个bug还是一个特性?
在这种情况下,启动mpi任务的正确方法是什么?好的,问题与子流程无关。 与os.system、os.execvp等的行为相同 看起来,简单导入此版本的h5py会初始化进程的MPI环境。 因此,任何子进程都会收到许多与openmpi相关的环境变量 您可以通过以下代码看到其中一些变量:
#!/usr/bin/python3
#import h5py
import subprocess
result=subprocess.run(['mpirun','-np','2','uptime'],shell=False)
print(result.returncode)
import h5py
import os
os.system('env | grep PMIX')
输出可能如下所示:
PMIX_RANK=0
PMIX_NAMESPACE=4066967553
PMIX_GDS_MODULE=ds21,ds12,hash
PMIX_SYSTEM_TMPDIR=/tmp
PMIX_SERVER_URI2=4066967552.0;tcp4://127.0.0.1:39583
PMIX_SERVER_URI3=4066967552.0;tcp4://127.0.0.1:39583
PMIX_BFROP_BUFFER_TYPE=PMIX_BFROP_BUFFER_NON_DESC
...
有了这样的环境变量,MPI将以静默方式运行并退出,错误代码为1
奇怪,但是这些环境变量在os.environ中看不到。
但是,这提供了解决问题的方法:
只需显式地将os.environ传递给子进程。
使用os.execvpe的第三个参数或将env=os.environ传递给subprocess.Popen
因此,问题中更正的程序可能如下所示:
import h5py
import subprocess
import os
result=subprocess.run(['mpirun','-np','2','uptime'], env=os.environ, shell=False)
print(result.returncode)
对我来说,解决方法已经足够。
h5py
取决于mpi4py
,这意味着在mpirun
之前调用MPI\u Init\u thread()。由于内部原因,打开的MPI应用程序无法调用mpirun
。一个选项是重建h5py
,因此它不依赖于mpi4py
,另一个选项是使用MPI\u Comm\u spawn()
而不是子流程。run()