如果存在对MPI_Initialized的调用,则Fortran程序将冻结

问题描述

以下Fortran程序在调用print_test时冻结。

program test_prg
  implicit none
  integer :: mpi_enabled,ierr

  call MPI_Initialized(mpi_enabled,ierr)
  print *,print_test()

contains

  function print_test() result(res)
    real :: res 
    res = 0 
    print *,'HELLO'
  end function
end program

print_test调用甚至可以在对MPI_Initialized调用之前,并且只要程序中某处存在对MPI_Initializedprint *,print_test()调用,它仍然会冻结。如果将MPI_Initialized替换为MPI_Init,也可以重现相同的问题,但是如果我将其删除,则不会出现相同的问题。如果我删除print *,'HELLO',那么它将起作用。如果我在单独的行上调用print_test,然后打印结果,那么它将起作用。使用gfortran 9.3.0(通过mpifort编译时,会观察到该问题。使用ifort进行编译时,同一程序可以正常工作。 MPICH版本是3.3.2。

这是一个gfortran错误吗?有人知道如何解决此问题吗?

解决方法

有人向我指出,这个问题与递归IO有关,这显然是标准所不允许的。简而言之,如果一个函数打印到一个单元,则不能在与同一单元关联的打印语句的IO列表中调用它。必须将函数的返回值分配给变量,然后打印该变量,或打印到另一单元。不幸的是,不遵守此规则会导致运行时冻结,没有解释,而不是编译时错误。已经提出并回答了完全相同的问题,例如:

Function call stopping/hanging when containing a write-statement,but only when linking with certain libraries during compilation

Print to standard output from a function defined in an Fortran module