【问题标题】:Fortran 77 -> Fortran 90+: COMMON blocks, MPI_BcastFortran 77 -> Fortran 90+:常见块,MPI_Bcast
【发布时间】:2026-01-11 23:40:01
【问题描述】:

我正在将 F77 程序重构为更新的 Fortran 标准(90 甚至更高)。

我有一个模块,其中定义了一些变量。这些变量目前被放入公共块中,因为在外部子程序中,所有这些变量仅使用一个 MPI_BCAST 调用并利用该公共块中变量的连续存储来广播。

module foo
  implicit none
  integer :: a,b,c,d
  real*8 :: r,t,p
  common/com/ a,b,c,d,r,t,p
end module foo

subroutine bar
  ...
  com_length = 4*4 + 3*8 ! 4 integers + 3 real(8)

  ! bcasting 'com' common block, i.e. all variables at once
  call mpi_bcast(a,com_length,mpi_byte,root,comm,ierr)
  ...
end subroutine bar

问题是公共块com_length的长度是手动计算的,容易出错。如果缺少 COMMON 块定义,调试将需要很长时间,因为即使 valgrind 也不会注意到 OOB。 另一方面,为每个变量单独调用 MPI_BCAST 会对性能产生负面影响。

感谢您对如何重构它的建议。

【问题讨论】:

    标签: fortran fortran-common-block


    【解决方案1】:

    您可以在 2 个 MPI_BCAST 电话中完成。

      CALL MPI_BCAST([a, b, c, d], 4, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
      CALL MPI_BCAST([t, r, p], 3, MPI_DOUBLE_PRECISION, root, MPI_COMM_WORLD, ierr)
    

    43 可能不完全正确,但想法仍然相同:将您的类似变量分组为一个数组并广播它们。

    【讨论】:

    • 请注意,数组构造函数的方括号是 Fortran 2003 的一项功能,给定的编译器可能不支持(尽管我使用的每个编译器都支持)。您可能必须改用(/ /)
    • 谢谢!很简单。我正在考虑更复杂的解决方案,例如使用 SEQUENCE 存储将所有内容放入派生类型...您的解决方案非常优雅。
    • @Yossarian 是的,我知道这一点,但这个想法是可以理解的。
    • @kyle-kanos 想了一会儿,这个解决方案是行不通的:a,b,c,d, ... root rank 会广播它们,但是它们是如何在所有其他处理器上设置的?
    • @robusta:你是什么意思?如果您声明INTEGER :: a, b, c, dREAL(8) :: r, t, p,那么所有进程都会知道这些变量。如果root 进程是定义它们的进程,那么当MPI_BCAST 被调用时,所有处理器都会设置变量。