MPI版本混用问题诊断
MPI作为消息通信工业标准,在高性能计算中被广泛使用。MPI标准定义了库函数语法、语义,开发商根据标准开发实现具体的MPI软件版本,比如常见的MPICH、OpenMPI、Intel MPI、MVAPICH等。
为了满足不同的需求,HPC计算平台一般会安装多个MPI实现版本,如果用户开发环境设置混乱,可能会导致MPI版本混用情况,从而引发意想不到的错误,包括编译时和运行时错误。比如笔者遇到如下情况:依赖库使用一种MPI实现编译,模式使用另一种MPI实现编译链接,在运行时出现很奇怪的错误,这种错误有时候不容易联想到是MPI混用导致的。
下面总结MPI混用引起的编译时和运行时错误。
代码示例
示例项目有两个源代码文件:sum.f90和main.f90,其中主程序main(main.f90)依赖模块mod_sum(sum.f90)。
!sum.f90
module mod_sum
use mpi
implicit none
contains
subroutine sum_global()
implicit none
integer :: id,total,ierr
call mpi_comm_rank(MPI_COMM_WORLD,id,ierr)
call mpi_reduce(id,total,1,MPI_INTEGER,MPI_SUM,0,MPI_COMM_WORLD,ierr)
if(id == 0) print*, 'sum of all is ',total
end subroutine sum_global
end module mod_sum
!main.f90
program main
use mod_sum
implicit none
integer :: nprocs,myid,ierr
call mpi_init(ierr)
call mpi_comm_size(MPI_COMM_WORLD,nprocs,ierr)
call mpi_comm_rank(MPI_COMM_WORLD,myid,ierr)
print*, "rank ",myid," of ",nprocs
call sum_global()
call mpi_finalize(ierr)
end
编译时错误
sum.f90使用IntelMPI mpiifort命令编译,而main.f90使用OpenMPI mpifort命令编译。mod_sum模块使用的mpi模块传播给main主程序,但两者编译时使用不同的MPI版本,查找不同的mpi模块文件,导致编译出错。
$ mpiifort -c sum.f90 # intel mpi
$ mpifort -c main.f90 # openmpi
main.f90(9): error #6405: The same named entity from different modules and/or program units cannot be referenced. [MPI_COMM_WORLD]
call mpi_comm_size(MPI_COMM_WORLD,nprocs,ierr)
---------------------^
运行时错误
如果将sum.f90中use mpi
替换为include "mpif.h"
,以上编译链接成功生成可执行程序。
使用头文件方式能成功编译链接原因在于头文件包含(include)实际上是文本替换操作,只要头文件内容符合fortran语法标准编译不会报错。
$ mpiifort -c sum.f90 # intel mpi
$ mpifort -c main.f90 # openmpi
$ mpifort -o main.exe main.o sum.o # openmpi
生成的main.exe提交到计算节点运行,报以下错误:
[node:227874] *** An error occurred in MPI_Comm_size
[node:227874] *** reported by process [47742942117889,0]
[node:227874] *** on communicator MPI_COMM_WORLD
[node:227874] *** MPI_ERR_COMM: invalid communicator
[node:227874] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
[node:227874] *** and potentially your MPI job)
[node:227869] 31 more processes have sent help message help-mpi-errors.txt / mpi_errors_are_fatal
[cmac0742:227869] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages
[warn] Epoll MOD(1) on fd 49 failed. Old events were 6; read change was 0 (none); write change was 2 (del): Bad file descriptor
[warn] Epoll MOD(4) on fd 49 failed. Old events were 6; read change was 2 (del); write change was 0 (none): Bad file descriptor
关键错误信息:MPI_ERR_COMM: invalid communicator
.因两种MPI定义的常量MPI_COMM_WORLD值是不同的。
! intel mpi mpif.h
INTEGER MPI_COMM_WORLD
PARAMETER (MPI_COMM_WORLD=1140850688)
! openmpi
parameter (MPI_COMM_WORLD=0)
如果反过来,换成Intel MPI最终链接+运行:
$ mpifort -c sum.f90 # openmpi
$ mpiifort -c main.f90 # intel mpi
$ mpiifort -o main.exe main.o sum.o # intel mpi
运行报类似的错误:
Fatal error in PMPI_Comm_size: Invalid communicator, error stack:
PMPI_Comm_size(124): MPI_Comm_size(comm=0x0, size=0x7fffd5a0d2f4) failed
PMPI_Comm_size(78).: Invalid communicator
笔者还遇到过因MPI混用导致以下错误信息:
forrtl: error (78): process killed (SIGTERM)
因某个进程出错,导致其它进程收到信号SIGTERM
,某种 "watchdog"程序杀死了它认为是 "失控 "的程序。
建议
为了避免MPI版本混用问题,建议:
- 使用module软件版本管理方式,其
conflict
功能避免同时加载多个MPI版本 - 弄清楚依赖库使用的MPI版本,确保采用同一套MPI版本
参考资料

