Fortran 77->;Fortran 90+;:公共块,MPI_Bcast

Fortran 77->;Fortran 90+;:公共块,MPI_Bcast,fortran,fortran-common-block,Fortran,Fortran Common Block,我正在将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 ...

我正在将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
是手动计算的,并且容易出错。若公共块定义丢失,调试将花费很长时间,因为即使valgrind也不会注意到OOB。 另一方面,为每个变量分别调用MPI_BCAST将对性能产生负面影响


我将非常感谢您关于如何重构此文件的建议。

您可以在2个
MPI\u 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)

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

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