物理侧 OMP data/transfer 组
输入范围
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\mod_phys_lmdz_omp_data.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\mod_phys_lmdz_omp_transfert.F90
文件定位
mod_phys_lmdz_omp_data.F90 将当前 MPI rank 的 klon_mpi 物理列切分给 OpenMP 线程,并保存线程局部 klon_omp 和起止列。mod_phys_lmdz_omp_transfert.F90 在同一 MPI rank 内用共享缓冲、barrier、master 和 critical 实现 OMP 层 bcast/scatter/gather/reduce。
Mars 运行参与度
条件经过:Mars 或 COMMON 物理侧启用 OpenMP 物理并行时经过;非 OMP 构建退化为单线程分布。
文件和符号
| 文件 | 行数 | 主要符号 | 作用 |
|---|---|---|---|
mod_phys_lmdz_omp_data.F90 |
126 | mod_phys_lmdz_omp_data, Init_phys_lmdz_omp_data, Print_module_data |
保存 OMP rank、线程局部物理列范围和极点标志。 |
mod_phys_lmdz_omp_transfert.F90 |
1119 | mod_phys_lmdz_omp_transfert, bcast_omp, scatter_omp, gather_omp, reduce_sum_omp, omp_barrier |
同一 MPI rank 内的线程间 transfer 包装;主文件页见 mod_phys_lmdz_omp_transfert。 |
OMP data 初始化
Init_phys_lmdz_omp_data(klon_mpi) 的关键步骤:
CPP_OMP下由 master 线程读取omp_size,各线程读取omp_rank;否则设为单线程。- 检查 OpenMP master 是否为 rank 0 线程;异常时调用
abort_physic。 - master 分配
klon_omp_para_nb/begin/end(0:omp_size-1)。 - 将
klon_mpi尽量平均分给线程,余数优先给低编号线程。 - 每个线程设置自己的
klon_omp/klon_omp_begin/klon_omp_end。 - 极点物理标志继承自 MPI data 的
is_north_pole_dyn/is_south_pole_dyn。
OMP transfer 接口族
mod_phys_lmdz_omp_transfert 使用模块级 buffer:
buffer_c,固定最小字符缓冲。buffer_i/buffer_r/buffer_l,按需要通过check_buffer_*扩容。
公开接口:
bcast_omp:master 把值写入 buffer,barrier 后其他线程读取。scatter_omp:master 将klon_mpi数据放入 buffer,各线程按klon_omp_begin取自己的段。gather_omp:各线程把本地段写入 buffer,master 再组装为klon_mpi字段。reduce_sum_omp:先清零输出,线程在 critical 中累加,再由 master 回写。omp_barrier:显式 OpenMP barrier 包装。
复现要点
klon_omp系列变量是THREADPRIVATE,必须在 OpenMP parallel 区内初始化和使用。- OMP transfer 只处理同一 MPI rank 内的线程间搬运;跨 MPI rank 的通信由 MPI transfer 页处理。
- buffer 扩容在 master 区完成,并用 barrier 保护所有线程看到一致缓冲。
- reduce 使用
!$OMP CRITICAL累加,确保结果确定但可能影响性能。
待确认
is_north_pole_phy/is_south_pole_phy对物理参数化分支的直接使用点需后续物理侧页面补充。- OMP transfer 大文件逐泛型过程细节属于 重点页细节页范围。