dyn1d/mod_const_mpi.F90

路径

LMDZ.MARS\libf\phymars\dyn1d\mod_const_mpi.F90

文件定位

dyn1d/mod_const_mpi.F90 在当前源码树中不是独立实现,而是一行相对路径:

../../../../LMDZ.COMMON/libf/dyn3dpar/mod_const_mpi.F90

它把 1D testphys1d 构建路径中的 mod_const_mpi 解析到公共并行动力版本。目标模块保存 LMDZ 动力侧 MPI communicator 和实数 MPI datatype,并提供 MPI/XIOS/OASIS 初始化入口。当前 dyn1d 初始化直接读取 COMM_LMDZ,用于有 XIOS 时初始化物理分布。

定义的符号

符号 类型 目标行号 作用
mod_const_mpi.F90 path stub dyn1d line 1 指向 LMDZ.COMMON/libf/dyn3dpar/mod_const_mpi.F90
mod_const_mpi module common line 4 保存 MPI communicator/datatype 并提供初始化例程。
COMM_LMDZ integer, save common line 6 LMDZ 动力侧 communicator;MPI 分支常设为 MPI_COMM_WORLD 或 XIOS/OASIS 返回的 communicator。
MPI_REAL_LMDZ integer, save common line 7 LMDZ real 数据的 MPI datatype;MPI 分支设为 MPI_REAL8
Init_const_mpi subroutine common line 12 读取 type_ocean,按耦合/非耦合路径初始化 communicator。
Init_mpi subroutine common line 60 非耦合路径 MPI 初始化入口,必要时也初始化 XIOS。

初始化逻辑

Init_const_mpi

  1. 通过 getin('type_ocean', type_ocean) 读取海洋耦合类型,默认字符串为 force
  2. type_ocean=='couple'
    • CPP_COUPLE 下进入耦合初始化。
    • CPP_XIOS 时调用 wxios_init("LMDZ", outcom=COMM_LMDZ, type_ocean=type_ocean)
    • 否则调用 OASIS/PRISM 的 prism_init_comp_protoprism_get_localcomm_proto(COMM_LMDZ,ierr)
    • CPP_MPI 下设置 MPI_REAL_LMDZ=MPI_REAL8
  3. 否则调用 Init_mpi

Init_mpi

  1. CPP_MPI 下调用 MPI_INIT_THREAD,要求 MPI_THREAD_SERIALIZED
  2. 若 MPI 线程支持级别不足,打印 warning。
  3. 设置 COMM_LMDZ=MPI_COMM_WORLDMPI_REAL_LMDZ=MPI_REAL8
  4. 若同时启用 CPP_XIOS,调用 wxios_init("LMDZ", outcom=COMM_LMDZ)
  5. 若未启用 CPP_MPI 但启用 CPP_XIOS,只调用 wxios_init("LMDZ"),源码中不设置 COMM_LMDZ

dyn1d 使用路径

当前 dyn1d 目录中直接使用 mod_const_mpi 的源码位置是 init_testphys1d_mod

use mod_const_mpi, only: COMM_LMDZ

在初始化 physics distribution 时:

#ifdef CPP_XIOS
call init_physics_distribution(regular_lonlat,4,1,1,1,nlayer,COMM_LMDZ)
#else
call init_physics_distribution(regular_lonlat,4,1,1,1,nlayer,1)
#endif

因此 COMM_LMDZ 在 1D 路径中的直接作用是:当 CPP_XIOS 打开时,把动力侧 communicator 传给 physics distribution 初始化;没有 XIOS 时使用整数 1 作为串行/占位 communicator。

使用方和相关公共路径

文件 使用符号 说明
init_testphys1d_mod COMM_LMDZ XIOS 分支初始化 1D physics distribution。
parallel_lmdz.F90 COMM_LMDZ, using_mpi 公共并行运行时初始化 rank/size、barrier、broadcast、gather。
dynphy_lonlat/calfis_p.F COMM_LMDZ 并行动力-物理接口中做 MPI 非阻塞通信。
dyn3dpar/mod_hallo.F90 COMM_LMDZ, MPI_REAL_LMDZ halo 通信使用 communicator 和 real datatype。
dyn3dpar/times.F90 MPI_REAL_LMDZ, COMM_LMDZ 并行计时统计 gather。

与串行版本的差异

公共源码还存在 LMDZ.COMMON/libf/dyn3d/mod_const_mpi.F90,它同名但更小,只声明 COMM_LMDZ/MPI_REAL_LMDZ 和一个把两者置 0 的 Init_const_mpi。本 dyn1d stub 指向的是 dyn3dpar 版本,所以页面按并行版本记录;不要把串行 dyn3d 版本的“置 0”行为套到当前 dyn1d 路径。

编译条件和外部依赖

宏/依赖 影响
CPP_MPI 引入 mpif.h,调用 MPI_INIT_THREAD,设置 COMM_LMDZ=MPI_COMM_WORLDMPI_REAL_LMDZ=MPI_REAL8
CPP_XIOS 使用 wxios_init 初始化 XIOS,并可返回 COMM_LMDZ
CPP_OMCT, CPP_COUPLE 使用 OASIS/PRISM coupling 路径初始化本地 communicator。
CPP_IOIPSL 从 IOIPSL 使用 getin;否则使用本地 ioipsl_getincom::getin
type_ocean 配置键;默认 force ,为 couple 时走耦合 communicator 初始化。

复现要点

  1. COMM_LMDZ 是否已初始化取决于程序入口是否调用过 Init_const_mpiInit_mpi。单看 init_testphys1d_mod 只能看到读取 COMM_LMDZ,不能证明初始化发生在该例程内部。
  2. 未启用 CPP_XIOS 的 1D 初始化不会使用 COMM_LMDZ,而是把 1 传给 init_physics_distribution
  3. 启用 CPP_XIOS 时,如果 COMM_LMDZ 未被正确初始化,physics distribution 初始化可能拿到未定义 communicator。
  4. 当前文件是公共并行 stub,不是 Mars 物理层 MPI 数据模块;物理层 communicator 另见 mod_phys_lmdz_mpi_data.F90COMM_LMDZ_PHY

待确认

相关页面