如何在MPI程序内调用另一MPI程序,解决Open MPI递归调用mpirun报错问题
你遇到的报错是OpenMPI的默认限制:不允许在已经通过mpirun启动的MPI进程内部,再次调用mpirun启动新的MPI程序,也就是禁止嵌套mpirun调用。以下是三个不同复杂度的解决方案,可根据你的实际需求选择:
方案1:仅修改run2脚本(零代码修改,最快生效)
不需要修改任何Fortran代码,只需调整run2脚本里的mpirun参数,打开OpenMPI的嵌套调用支持即可。修改后run2的内容如下:
mpirun -np 2 --mca plm isolated --mca orte_parent_uri none ./hallo.exe
修改后直接按你原来的命令mpirun -np 2 ./F1.exe运行即可,大部分场景下都可以直接跑通。
方案2:启动逻辑外移(彻底避免嵌套,兼容性最好)
如果你的主程序F1在调用hallo前后没有需要保持的跨进程状态,只是单纯的顺序执行三段逻辑:「F1前置计算」→「运行hallo程序」→「F1后置计算」,可以把F1拆成两个独立的可执行文件F1_pre.exe和F1_post.exe,然后写一个总运行脚本一次性按顺序跑:
#!/bin/bash # 运行主程序前置逻辑 mpirun -np 2 ./F1_pre.exe # 运行被调用的hallo程序 mpirun -np 2 ./hallo.exe # 运行主程序后置逻辑 mpirun -np 2 ./F1_post.exe
这个方案完全没有嵌套调用,兼容所有MPI版本,不会出现版本兼容问题。
方案3:使用MPI原生进程启动接口(合规通用,适合复杂场景)
如果你需要主程序和hallo程序之间有数据交互,或者不想拆分原有的F1代码,可以用MPI标准自带的MPI_Comm_spawn接口启动子MPI程序,不需要自己调用system跑mpirun,自然不会触发嵌套报错。
只需把F1.f90中原来调用system的部分:
if(mpirank .eq. 0) then print*,'Going in hallo' call system ('./run2') endif
替换为如下代码即可:
integer inter_comm if(mpirank .eq. 0) then print*,'Going in hallo' ! 直接启动2个hallo.exe进程,不需要调用mpirun call MPI_Comm_spawn('./hallo.exe', MPI_ARGV_NULL, 2, MPI_INFO_NULL, 0, MPI_COMM_SELF, inter_comm, MPI_ERRCODES_IGNORE, ierr) ! 等待所有hallo进程运行结束 call MPI_Comm_disconnect(inter_comm, ierr) endif
修改后可以直接删除run2脚本,按原命令启动主程序即可,这个方法符合MPI标准,所有MPI实现都支持。
内容的提问来源于stack exchange,提问作者BideshSengupta
相关产品推荐
相关产品推荐

