“use mpi_f08”语句导致 Fortran MPI 程序在 Ubuntu 22.04 上崩溃

Boj*_*eno 3 fortran mpi mpich ubuntu-22.04

我正在使用 Ubuntu 来开发带有 MPI 的 Fortran (2008+) 程序。在早期的 Ubuntu 版本上,一切都已经解决了,但我在 Ubuntu 22.04 上编译和运行 Fortran/MPI 时遇到了一些困难,我最近在一台新 PC 上安装了 Ubuntu 22.04。

我首先安装了 OpenMPI,但它根本不会编译我的程序,抱怨它找不到一些与mpi_f08. (很抱歉,但我不记得确切的消息,并且从那时起我就卸载了 OpenMPI)。

不过我在 MPICH 上的运气更好。它可以编译我的程序,但一旦处理器之间发生第一次通信,它就会在执行过程中崩溃。下面给出了演示该问题的最小示例:

subroutine global_sum_real(phi_old)
use mpi_f08
implicit none
real    :: phi_old
real    :: phi_new
integer :: error
call mpi_allreduce(phi_old,         & ! send buffer
                   phi_new,         & ! recv buffer
                   1,               & ! length
                   mpi_real,        & ! datatype
                   mpi_sum,         & ! operation
                   mpi_comm_world,  & ! communicator
                   error)
phi_old = phi_new
end subroutine

program global_sum_mpi
use mpi_f08
implicit none
real    :: suml
integer :: error
call mpi_init(error)
suml = 1.0
call global_sum_real(suml)
print *, suml
call mpi_finalize(error)
end program
Run Code Online (Sandbox Code Playgroud)

我希望上面发生的事情已经很清楚了。主程序 ( global_sum_mpi) 初始化 MPI 并调用一个子例程 ( global_sum_real),该子例程本质上是MPI_Allreduce. 很简单。

如果我用 mpifort 编译它(它是: mpifort for MPICH version 4.0 ... gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04))并尝试并行运行它,它会崩溃并出现错误:

内部错误:描述符中的类型无效

在调用 的行中MPI_Allreduce。有趣的是,如果我更改用于 MPI 的模块:

use mpi_f08
Run Code Online (Sandbox Code Playgroud)

到平原:

use mpi
Run Code Online (Sandbox Code Playgroud)

一切都按预期进行。这不是我想要采取的路线,因为我相信这mpi_f08与后来的 Fortran 标准更加同步,并且我还需要mpi_f08与外部 PETSc 库更好的兼容性。

关于为什么use mpi_f08在新安装的 Ubuntu 上出现问题有什么想法吗?

亲切的问候

Gil*_*det 5

根本原因是gfortranUbuntu 22.04 (jammy) 提供的一个错误。

这是一个崩溃的示例程序

module mymod
        implicit none
        interface bar
        subroutine bar_f08ts (a) bind(C, name="sync")
        implicit none
        type(*), dimension(..) :: a
        end subroutine
        end interface
end module

module pub
        implicit none

        interface sub
        subroutine pub_f08ts(a)
        implicit none
        type (*), dimension(..) :: a
        end subroutine
        end interface
end module

        subroutine pub_f08ts(a)
        use mymod
        implicit none
        type (*), dimension(..) :: a
        call bar(a)
        end subroutine

subroutine bugsub(a)
        use pub
        implicit none
        real :: a
        call sub(a)
end subroutine

program bug
        implicit none
        real a
        a = 1
        call bugsub(a)
end program
Run Code Online (Sandbox Code Playgroud)
$ gfortran test.f90
$ ./a.out 
Internal Error: Invalid type in descriptor

Error termination. Backtrace:
#0  0x7f27b38c2ad0 in ???
#1  0x7f27b38c3649 in ???
#2  0x7f27b38c3e38 in ???
#3  0x7f27b3b058a4 in ???
#4  0x56281847220b in ???
#5  0x5628184721c4 in ???
#6  0x562818472264 in ???
#7  0x5628184722a0 in ???
#8  0x7f27b36a0d8f in __libc_start_call_main
    at ../sysdeps/nptl/libc_start_call_main.h:58
#9  0x7f27b36a0e3f in __libc_start_main_impl
    at ../csu/libc-start.c:392
#10  0x5628184720c4 in ???
#11  0xffffffffffffffff in ???
Run Code Online (Sandbox Code Playgroud)

我无法在具有各种gfortran版本的 Redhat 机器上重现此问题。

继续前进的正确方法是向 Ubuntu 报告此问题并等待修复。

同时,您可以使用其他发行版,或使用 Open MPI(不使用这些CFI_desc_t内容,因此该gfortran错误不会影响您)。我不明白如何使用 ubuntu 软件包openmpi(提供了一些软件包,但除非我错过了某些内容,否则库和头文件不可用),但您可以从主目录中的源代码构建和安装(不需要 root 访问权限) 。

附加信息

出现此问题的原因是gfortran-11使用libgfortranfrom gfortran-12,然后发生不良交互。

我向 GNU 人员报告了这一点:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108056

  • 根本原因是“libgfortran”不兼容。Ubuntu 的“gfortran-11”使用“gcc-12”中的“libgfortran”。这是有道理的,因为“gcc-11”和“gcc-12”之间的“libgfortran”版本是相同的......除了在这种情况下,它们不兼容。我将首先向 GNU 人员报告,以澄清这是否是一个错误(例如,应该保留兼容性)或“打包”问题(例如,已知兼容性已被破坏,并且库版本应该已被修改)。 (2认同)