mpirun运行Python程序触发hwloc警告及PETSc段错误求助
问题现象
- 启动命令:通过如下mpirun命令启动4进程并行Python程序
mpirun -np 4 python test.py
- 程序启动后首先输出4条重复的hwloc警告(每个进程输出1条):
hwloc/linux: Ignoring PCI device with non-16bit domain. Pass --enable-32bits-pci-domain to configure to support such devices (warning: it would break the library ABI, don't enable unless really needed).
- 警告输出完成后,所有4个进程全部触发PETSc段错误,错误类型为信号11 SEGV(内存访问越界),错误栈仅提示问题出在用户自定义函数,未给出具体代码行号,核心错误输出如下:
[*]PETSC ERROR: Caught signal number 11 SEGV: Segmentation Violation, probably memory access out of range [*]PETSC ERROR: likely location of problem given in stack below [*]PETSC ERROR: #1 User provided function() at unknown file:0
现有环境信息
- 操作系统:Ubuntu 22.04
- OpenMPI版本:4.0.7,安装路径为
/home/pavan/packages/openmpi-4.0.7/opt-gfortran - PETSc版本:3.15.5,编译配置命令如下:
./configure --PETSC_ARCH=$PETSC_ARCH --with-scalar-type=real --with-debugging=1 --with-mpi-dir=$MPI_INSTALL_DIR \ --download-metis=yes --download-parmetis=yes --download-superlu_dist=yes \ --with-shared-libraries=yes --with-fortran-bindings=1 --with-cxx-dialect=C++11
- Python版本:3.9.12
- 编译器版本:gcc 9.4.0,gfortran 9.4.0
排查步骤
注:开头的hwloc PCI设备警告是硬件拓扑识别库的常规提示,和本次段错误没有关联,不会导致程序崩溃,可暂时忽略
- 优先排查环境链接/版本不匹配问题(这类问题占Python+PETSc并行段错误的80%以上)
- 核对petsc4py版本:执行
python -c "import petsc4py; print(petsc4py.__version__)"查看安装的petsc4py版本,必须和本地编译的PETSc 3.15.5版本严格一致。如果是通过pip直接安装的petsc4py,默认会绑定系统源的PETSc/MPI库,和你手动编译在用户目录下的PETSc不兼容,需要重新基于本地编译的PETSc路径编译安装petsc4py。 - 排查MPI库冲突:Ubuntu 22.04系统默认预装了OpenMPI运行库,很容易出现运行时加载的MPI库和编译PETSc时链接的自定义版本OpenMPI 4.0.7混用的情况,直接触发内存错误。执行
echo $LD_LIBRARY_PATH确认环境变量,你手动安装的OpenMPI的lib目录必须放在LD_LIBRARY_PATH的最靠前位置,保证运行时优先加载对应版本的库;也可以执行ldd $PETSC_DIR/$PETSC_ARCH/lib/libpetsc.so | grep mpi核对PETSc链接的MPI库路径,和运行时加载的MPI库路径必须完全一致。
- 核对petsc4py版本:执行
- 最小用例隔离问题
先不要运行完整的test.py,写一个最简化的PETSc测试脚本验证基础环境是否正常:
用同样的mpirun命令运行这个最小脚本:from petsc4py import PETSc comm = PETSc.COMM_WORLD rank = comm.Get_rank() print(f"Rank {rank}: PETSc init success, version {PETSc.Sys.getVersion()}") # 测试创建分布式向量 v = PETSc.Vec().create(comm=comm) v.setSizes(100) v.setFromOptions() v.set(1.0) print(f"Rank {rank}: vector norm = {v.norm()}")- 如果最小脚本也崩溃,说明问题完全出在环境配置上,和你写的test.py业务代码无关,回到第一步解决库版本/链接冲突问题即可。
- 如果最小脚本运行正常,说明问题出在test.py的代码逻辑上。
- 代码问题定位
基础环境验证通过后,用以下方法定位具体错误点:- 加调试参数启动:执行
mpirun -np 4 python -m pdb test.py,用Python自带调试器单步执行,找到触发崩溃的具体代码行。 - 开启PETSc详细栈追踪:运行时加参数
-petsc_error_stack_trace,让PETSc输出完整的函数调用栈,替代默认的"未知文件用户函数"提示。 - 重点排查高频代码错误:
- 是否在PETSc完成初始化前调用了任何PETSc相关接口
- 所有分布式Vec、Mat、求解器对象是否绑定了正确的通信子,是否存在跨通信子的对象数据拷贝
- 操作PETSc对象的底层数组指针时,是否存在写入长度超过对象分配内存大小的越界问题
- 是否存在某个进程独有的对象,被其他进程错误访问的情况
- 加调试参数启动:执行
内容的提问来源于stack exchange,提问作者Pavan
相关产品推荐
相关产品推荐

