guide 串并行差异

源码范围:

LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\guide_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\guide_p_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\leapfrog.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\leapfrog_p.F

Mars 运行参与度:接口兼容 + 条件边界。leapfrogleapfrog_pguide_main 的活动调用受 CPP_IOIPSL + planet_type=="earth" 条件包围;Mars phymars/nogcm.F90 中的 ok_guide 分支加载 relax.nc 给独立 relaxetat0 路径,不经过本页两个 COMMON guide 模块。

对照结论

串行 guide_mod 和并行 guide_p_mod 的数值职责相同:读取 nudging 输入场、插值到 LMDZ 动力层、把 U/V/T/P/Q forcing 叠加到动力状态,并可选写 guide_ins.nc。差异集中在三点:

  1. 并行版的 NetCDF 输入阶段仍由每个进程读完整场,真正的域分解从 guide_interpguide_main 的局部切片开始。
  2. 并行版用 ijb_u/ije_uijb_v/ije_v 分开写 U/scalar 与 V 网格,并在 pole_sud 时缩短 V 网格尾部范围。
  3. 并行版 guide_out 在写文件前调用 gather_field,非 root 直接返回;串行版直接写完整全局数组。

模块和配置差异

项目 串行 guide_mod 并行 guide_p_mod 影响
调用方 leapfrog 使用 guide_mod leapfrog_p 使用 guide_p_mod 串/并行可执行文件走不同模块。
并行依赖 parallel_lmdzmod_halloBands 分布、halo 和 root I/O 是并行版新增约束。
垂直坐标开关 guide_modele 布尔 guide_plevs=0/1/2,并兼容 guide_modele 并行版可读逐格点 P.nc
逐格点压力 pnat pnat1/pnat2(iip1,jjp1,nlevnc) guide_plevs=2 仅并行版支持。
局部范围 全域 ijb_u/ije_u/jjb_u/jje_uijb_v/ije_v/jjb_v/jje_v U/scalar 与 V 网格要分开查。
输出 直接 NetCDF 写 gather_fieldmpi_rank==0 输出错误先查 gather/root。

串行版和并行版都分配全局维度的 guide 工作数组,例如 ugui(ip1jmp1,llm)vgui(ip1jm,llm)psgui(ip1jmp1)。并行版没有把这些数组声明成局部尺寸,而是在读入后只更新或使用本 rank 负责的连续片段。

输入读取不是并行 I/O

guide_readguide_read2D 的串并行读法基本一致:每个进程打开同名 NetCDF 文件,读完整 (iip1,jjp1,nlevnc)(iip1,jjm,nlevnc) 输入场,然后按需要执行 invert_lat。这意味着:

真正的分布式计算在 guide_interp 发生:T/Q/U 使用 jjb_u:jje_u,V 使用 jjb_v:jje_v。U/scalar 目标场写 ijb_u:ije_u,V 目标场写 ijb_v:ije_v

guide_interp 局部分布

串行版构造完整模型层压力、U/V staggered 压力,然后对全局场调用 pres2lev

pression -> exner -> pls
pext = pls * aire
massbar(pext) -> plunc/plvnc
pres2lev(full field)

并行版把同一流程拆成本地行:

local pls on jjb_u:jje_u
pext local fill
Register_SwapFieldHallo(pext)
massbar_p(pext) -> local plunc/plvnc
pres2lev(field(:,jjb:jje,:), ...)

当并行版需要 V 网格上相邻纬向行时,会额外对 psnat1/2pnat1/2 做 halo:guide_plevs=1psnat halo,guide_plevs=2pnat halo。串行版没有这一步,因为所有纬向行本地可见。

guide_main 写回范围

串行版在每个变量分支中直接对完整数组赋值:

变量 串行写回 并行写回
U ucov = ucov + f_add ucov(ijb_u:ije_u,:) += f_add(ijb_u:ije_u,:)
T teta = teta + f_add teta(ijb_u:ije_u,:) += f_add(ijb_u:ije_u,:)
Ps ps = ps + f_add(:,1) ps(ijb_u:ije_u) += f_add(ijb_u:ije_u,1)
Q q = q + f_add q(ijb_u:ije_u,:) += f_add(ijb_u:ije_u,:)
V vcov = vcov + f_add(1:ip1jm,:) vcov(ijb_v:ije_v,:) += f_add(ijb_v:ije_v,:)

guide_addfield 同样体现这个边界:串行版对 field(:,l) 全域乘 alpha*alpha_pcor;并行版用 hsize==ip1jm 判断 V 网格,否则按 U/scalar 网格,只处理本 rank 片段。

纬向平均差异

guide_zonave 在串行版中扫描 j=1:hsize 的全纬向行。并行版只在本地纬向范围内做平均和填回:

后一个分支在极点或南极缩减分布上可能带来边界差异,和 guide forcing 叠加到动力状态 中记录的运行验证点一致。

输出和 factt

factt = dtvr * iperiod / daysec 是一个动力步组对应的天数分数。它有两类用途:

  1. 首次进入 guide_main 时传给 tau2alpha,把天数单位的 tau_min/tau_max 转成每步松弛系数。
  2. 输出诊断时,调用方先把 forcing 增量写成 f_add/factt,表示按天分数归一化后的 forcing。

串行 guide_out(varname,hsize,vsize,field) 不接收 factt,所有归一化都在调用点完成。并行 guide_out(varname,hsize,vsize,field,factt) 多了一个 factt 实参,但 当前源码体内没有使用该参数;实际缩放仍来自调用点的 f_add/factt。因此排查并行 guide_ins.nc 中的 ucov/teta/ps/q/vcov forcing 量时,应先看调用点是否传入了已除以 factt 的 field,而不是期待 guide_out 内部缩放。

输出还有一个重要串并行差异:

并行版 guide_out 对所有传入 field 先执行:

gather_field(field, iip1*hsize, vsize, 0)
if (mpi_rank /= 0) return

所以只有 root 创建和写 guide_ins.nc。源码中 ps 变量被定义为 3D (lon,lat,time),但写入分支和 SP 共用 count=(iip1,jjp1,llm,1);这与 ps 定义维度不完全一致,属于需要运行验证的诊断输出风险。本页只记录源码行为,不修改 COMMON 源码。

Mars 条件经过

COMMON guide_mod/guide_p_mod 的直接入口是 guide_main(itau,ucov,vcov,teta,q,masse,ps)。串行和并行 leapfrog* 只有在 CPP_IOIPSLplanet_type=="earth"logic_mod:ok_guide=.TRUE. 时才调用它。进入后还要受以下开关控制:

开关 作用
guide_u/guide_v/guide_T/guide_P/guide_Q 决定变量分支是否读取、插值、叠加和输出。
guide_2D 选择 guide_read2D 而不是 3D guide_read
iguide_read/iguide_int 控制新输入时间片读取和垂直插值频率。
guide_sav/iguide_sav 控制 guide_ins.nc 诊断输出。
guide_add 决定输入场是外部增量还是目标状态。
guide_zon 在叠加前做纬向平均。
guide_plevs 仅并行版,选择输入压力层解释。

Mars generic 的 phymars/nogcm.F90 中也检查 ok_guide,但那里调用的是 relaxetat0("relax.nc")。因此不要把 relax.nc 简单松弛路径和本页的 COMMON NetCDF u/v/T/hur/ps/P/apbp guide 路径混为一谈。

排错顺序

  1. 先确认当前可执行文件走 guide_mod 还是 guide_p_mod
  2. 若是并行版,记录 ij_begin/ij_end/jj_begin/jj_endpole_sudguide_plevs
  3. 输入场问题先查每个 rank 是否能读到完整 NetCDF 文件;并行版没有 root 代读。
  4. U/T/Q/Ps 差异查 ijb_u:ije_u,V 差异查 ijb_v:ije_v
  5. 插值差异查 pext/psnat/pnat halo,特别是 V 网格和 guide_plevs=1/2
  6. 输出文件缺失先查 guide_sav 和 root rank;输出量级问题先查调用点的 f_add/factt
  7. SPps 输出维度异常,优先按并行 guide_outSP/ps 分支确认运行时 NetCDF 行为。

相关页面