WSL1环境Python主动学习循环subprocess.run第二次调用MPI程序失败求助
问题原因及解决方法
1. MPI调用标准输入异常
很多MPI实现(比如OpenMPI)默认会尝试从标准输入读取配置,第一次运行后标准输入状态发生变化,会导致第二次调用直接退出返回错误码1,无任何输出。
- 解决方法:调用
subprocess.run时添加stdin=subprocess.DEVNULL参数,关闭子进程的标准输入继承:
cp = subprocess.run(["mpirun", "-n", "1", os.path.abspath("../smilei"), particular_namelist_name], stdin=subprocess.DEVNULL, capture_output=True)
2. WSL1进程残留问题
WSL1的进程管理存在缺陷,第一次运行的mpirun或smilei进程可能没有彻底退出,占用了MPI运行槽位或相关资源,导致第二次启动失败。
- 解决方法:每次调用
mpirun前先清理残留进程:
# 清理之前的残留进程,忽略清理失败的报错 subprocess.run(["pkill", "-f", "smilei"], check=False) subprocess.run(["pkill", "-f", "mpirun"], check=False) time.sleep(1) # 等待进程清理完成
3. 相对路径漂移问题
如果top_folder_path是相对路径,一旦happi.Open或其他操作偷偷修改了全局工作目录,第二次调用os.chdir(top_folder_path)时就会进入错误的路径,导致后续调用../smilei找不到可执行文件。
- 解决方法:将
top_folder_path改为绝对路径,初始化时就做转换:
top_folder_path = os.path.abspath(top_folder_path)
4. 日志输出缓冲问题
你当前注释了输出捕获,MPI的输出默认带缓冲,直接捕获可能拿不到实时报错。
- 解决方法:将输出重定向到文件夹内的日志文件,运行失败后直接查看日志获取具体报错:
with open("sim_out.log", "w") as f_out, open("sim_err.log", "w") as f_err: cp = subprocess.run(["mpirun", "-n", "1", os.path.abspath("../smilei"), particular_namelist_name], stdin=subprocess.DEVNULL, stdout=f_out, stderr=f_err)
运行失败后直接到对应a0_xxx文件夹下查看sim_err.log即可拿到具体报错信息。
临时验证方法
你可以先手动复制第二次迭代生成的完整mpirun命令,手动cd到对应文件夹下执行,确认命令本身是否能正常运行,可以快速区分是Python逻辑问题还是程序运行环境问题。
内容的提问来源于stack exchange,提问作者velenos14
相关产品推荐
相关产品推荐

