乐于分享
好东西不私藏

MPAS 系列教程(一)编译安装

MPAS 系列教程(一)编译安装
TUTORIAL · HPC2026.08

MPAS 编译安装指南

Intel MPI · SMIOL · CMake

MPAS-A 8.4.1

LINUXHPC

本文面向已经安装过 WRF 的读者,使用 Intel oneAPI 2021.4、Intel MPI 和 Intel Classic 编译器,在 Linux 服务器或 HPC 上编译 MPAS-Atmosphere 8.4.1。基础依赖只说明检查方法,ParallelIO 保留完整安装过程;实际编译 MPAS-A 时使用源码自带的 SMIOL。

MPAS 8.4:更新内容概览

MPAS-A 8.4.0 不是只增加了某一个物理方案,而是同时改动了动力框架、初始化、GPU/HPC 支持、化学接口和默认输出。

1

新增初步的 LES 能力:加入三维 Smagorinsky 诊断 TKE 和 1.5 阶预报 TKE 两种亚网格湍流方案。

2

垂直坐标与高层稳定性改进:新增混合垂直坐标控制参数,epssm 可随高度变化,并可用 config_microphysics_top 关闭指定高度以上的微物理倾向项。

3

GPU 和大规模并行支持增强:优化 OpenACC 数据传输,加入 GPU-aware MPI halo 交换,并支持使用 PT-Scotch 在模式启动时在线划分网格。

4

为 CheMPAS-A 提供代码基础:增加化学相关目录和接口,可与 MUSICA-Fortran 连接,为 MICM 和 TUV-x 等化学能力提供基础。

5

物理过程与输出继续修正:包括海冰区积雪初始化、Noah-MP 城市网格高 q2、CAM 短波辐射崩溃等问题;同时从默认输出中移除部分位涡诊断量,历史文件大小可减少约 20%。

6

8.4.1 进一步处理稳定性与构建问题:修正 Kessler 微物理在低气压高层的水汽压、Noah-MP 非默认土壤层的水量守恒、GEN_F90=true 构建路径,以及无 PBL 方案时的近地层数组分配等问题。

如果准备新装 MPAS-A,直接使用 8.4.1 更合适。这篇教程使用的主要路径如下,读者可以把用户名和目录替换成自己的实际路径。

...text

/home/usr/intel/oneapi

/home/usr/package/cmake-3.31.8-linux-x86_64

/home/usr/package/hdf5-1.14.2

/home/usr/package/netcdf

/home/usr/package/pnetcdf-1.12.3

/home/usr/package/CMake_Fortran_utils-master

/home/usr/package/genf90-genf90_200608

/home/usr/package/pio-2.7.0

/home/usr/package/MPAS-Model-8.4.1

PART 01

编译前先理清:哪些依赖必须装?

DEPENDENCIES · 依赖关系

 MPAS-A 的编译依赖

编译器与 MPI → 数据格式库 → 并行 I/O → MPAS-A

其中,GNU Make 和 CMake 负责组织整个构建过程。

编译工具链

Intel 编译器、Intel MPI、GNU Make、CMake

直接加载或按文中检查

数据格式库

zlib、HDF5、NetCDF-C、NetCDF-Fortran、PnetCDF

复用 WRF 编译环境

并行 I/O

ParallelIO 2.7.0、SMIOL

PIO 仅演示安装,实际编译使用 SMIOL

zlib、HDF5、NetCDF和PnetCDF的完整安装过程可以参考WRF 4.8.0 安装教程:从零开始把 WRF 编译跑通,已经成功编译过 WRF 的读者,通常可以直接复用现有依赖环境。本节重点介绍 MPAS-A 编译过程中更容易出问题的 ParallelIO。

ParallelIO 和 SMIOL 怎么选?

MPAS-A 8.4.1 在没有配置 PIO 时,可以使用源码自带的 SMIOL 完成文件读写。因此,ParallelIO 不是生成 MPAS-A 可执行文件的硬性条件。本文仍然保留 ParallelIO 2.7.0 的完整安装过程,方便需要该 I/O 框架的读者参考。我在实际编译 MPAS-A 时没有链接 ParallelIO:带 PIO 的 atmosphere_model 虽然能够编译成功,但在本文测试环境中无法正常运行,因此最终取消 PIO 环境变量,改用 SMIOL。不知道大家有没有遇到过类似的问题。

PART 02

加载 Intel 环境并检查基础库

ENVIRONMENT · 编译环境

先建立一个单独的环境脚本,例如 /home/usr/env_mpas_841.sh。以后编译 ParallelIO 和 MPAS-A 时都加载同一份脚本,避免混入其他 MPI 或编译器。

...bash

source /home/usr/intel/oneapi/setvars.sh

export CC=icc

export CXX=icpc

export FC=ifort

export F90=ifort

export F77=ifort

export I_MPI_CC=icc

export I_MPI_CXX=icpc

export I_MPI_F90=ifort

export PATH=/home/usr/intel/oneapi/mpi/2021.4.0/bin:$PATH

export CMAKE_ROOT=/home/usr/package/cmake-3.31.8-linux-x86_64

export PATH=$CMAKE_ROOT/bin:$PATH

export PHDF5=/home/usr/package/hdf5-1.14.2

export HDF5=$PHDF5

export NETCDF=/home/usr/package/netcdf

export PATH=$NETCDF/bin:$PATH

export NF_INCLUDE=$NETCDF/include

export NF_LIB=$NETCDF/lib

export PNETCDF=/home/usr/package/pnetcdf-1.12.3

export PATH=$PNETCDF/bin:$PATH

export LD_LIBRARY_PATH=$HDF5/lib:$NETCDF/lib:$PNETCDF/lib:${LD_LIBRARY_PATH:-}

本文使用的 ParallelIO 2.7.0 要求 CMake 不低于 3.18。HDF5、NetCDF、PnetCDF、ParallelIO 和 MPAS-A 应尽量由同一套 Intel 编译器与 Intel MPI 构建。

安装 CMake 3.31.8

如果服务器上的 CMake 低于 3.18,或者没有管理员权限,可以直接安装 Kitware 提供的 Linux x86_64 二进制包。CMake 是构建工具,不参与最终的 Fortran/C 库链接,因此不要求使用 Intel 编译器重新编译它。

...bash

export CMAKE_ROOT=/home/usr/package/cmake-3.31.8-linux-x86_64

cd /home/usr/package

wget https://github.com/Kitware/CMake/releases/download/v3.31.8/cmake-3.31.8-linux-x86_64.tar.gz

tar -xzf cmake-3.31.8-linux-x86_64.tar.gz

export PATH=$CMAKE_ROOT/bin:$PATH

which cmake

cmake --version

如果输出中的版本号是 cmake version 3.31.8,说明安装成功。这里下载的是 x86_64 版本,可先用 uname -m 确认服务器架构;若输出不是 x86_64,不要直接使用这个二进制包。

还可以检查 NetCDF-C 是否启用了并行 NetCDF-4:

...bash

nc-config --has-parallel4

nf-config --has-nc4

pnetcdf-config --all

nc-config --has-parallel4 最好返回 yes

PART 03

安装 ParallelIO 2.7.0

PARALLEL I/O · 并行读写

ParallelIO,简称 PIO,是 MPAS 在大量 MPI 进程之间组织并行读写的 I/O 层。本文使用 2026 年发布的 PIO 2.7.0,并关闭 GPTL 计时功能,减少不必要的依赖和链接问题。

下载源码

...bash

cd /home/usr/package

wget https://github.com/NCAR/ParallelIO/archive/refs/tags/pio2_7_0.tar.gz

tar -xzf pio2_7_0.tar.gz

export PIO_SRC=/home/usr/package/ParallelIO-pio2_7_0

export PIO_BUILD=/home/usr/package/build-pio-2.7.0

export PIO=/home/usr/package/pio-2.7.0

准备两个构建辅助工具

PIO 2.7.0 的 Fortran 构建还会使用两个小型辅助仓库。配置阶段需要 CMake_Fortran_utils,生成 Fortran 接口时需要 genf90。PIO 默认会在构建过程中执行 git clone,服务器不能访问 GitHub、设置了 Git 离线镜像,或者构建目录中残留了未下载完整的仓库时,都可能中断。

更稳妥的做法是在配置 PIO 前手动下载。genf90 必须使用 PIO 2.7.0 指定的 genf90_200608 标签。

...bash

cd /home/usr/package

wget https://codeload.github.com/CESM-Development/CMake_Fortran_utils/tar.gz/refs/heads/master -O CMake_Fortran_utils-master.tar.gz

tar -xzf CMake_Fortran_utils-master.tar.gz

wget https://codeload.github.com/PARALLELIO/genf90/tar.gz/refs/tags/genf90_200608 -O genf90_200608.tar.gz

tar -xzf genf90_200608.tar.gz

export CMAKE_FORTRAN_UTILS=/home/usr/package/CMake_Fortran_utils-master

export GENF90_PATH=/home/usr/package/genf90-genf90_200608

test -f "$CMAKE_FORTRAN_UTILS/mpiexec.cmake"

test -x "$GENF90_PATH/genf90.pl"

最后两条 test 命令没有输出就是正常的。后面的 CMake 配置会直接使用这两个本地目录,不再在配置或编译过程中在线克隆仓库。

编译配置

PIO 必须使用 MPI 编译器包装器。虽然环境脚本中的 CC 和 FC 指向串行编译器,但下面在 CMake 命令前显式指定 mpiiccmpiicpc 和 mpiifort,只对这一次配置生效。

...bash

export PKG_CONFIG_PATH=$NETCDF/lib/pkgconfig:$PNETCDF/lib/pkgconfig:${PKG_CONFIG_PATH:-}

CC=mpiicc CXX=mpiicpc FC=mpiifort cmake --fresh \

-S "$PIO_SRC" \

-B "$PIO_BUILD" \

-DCMAKE_INSTALL_PREFIX="$PIO" \

-DUSER_CMAKE_MODULE_PATH="$CMAKE_FORTRAN_UTILS" \

-DGENF90_PATH="$GENF90_PATH" \

-DPIO_ENABLE_TIMING=OFF \

-DPIO_ENABLE_DOC=OFF \

-DPIO_ENABLE_EXAMPLES=OFF \

-DPIO_ENABLE_TESTS=OFF

编译与安装

...bash

cmake --build "$PIO_BUILD" -j8

cmake --install "$PIO_BUILD"

安装完成后检查:

...bash

ls -lh "$PIO/lib"/libpio*

ls -lh "$PIO/include"/pio*.mod

正常情况下可以看到 libpioclibpiof 和 Fortran 模块文件。本文不把 PIO 写入最终的 MPAS-A 编译环境;上面的安装目录保留即可,需要编译 PIO 版本时再临时设置。

PART 04

下载 MPAS-A 8.4.1 源码

SOURCE CODE · 获取源码

从官方标签下载源码:

...bash

cd /home/usr/package

wget https://github.com/MPAS-Dev/MPAS-Model/archive/refs/tags/v8.4.1.tar.gz -O MPAS-Model-8.4.1.tar.gz

tar -xzf MPAS-Model-8.4.1.tar.gz

export MPAS_SRC=/home/usr/package/MPAS-Model-8.4.1

MPAS-A 8.4.1 的源码包还需要在构建时获取 MMM-physics、UGWP 和 WRF 物理过程查找表。

下面的下载过程需要连接 GitHub;服务器可以访问 GitHub 时,建议在正式编译前主动完成这一步:

...bash

cd "$MPAS_SRC/src/core_atmosphere"

./tools/manage_externals/checkout_externals --externals Externals.cfg

cd physics

./checkout_data_files.sh

如果计算集群不能访问 GitHub,可以使用已经包含上述外部源码和查找表的完整安装包,获取方式见文末。

PART 05

编译两个 MPAS-A 可执行文件

BUILD · 编译程序

重新加载统一环境,并明确取消 PIO。只要编译时没有设置这个变量,MPAS-A 就会使用源码自带的 SMIOL:

...bash

source /home/usr/env_mpas_841.sh

unset PIO

export LD_LIBRARY_PATH=$PNETCDF/lib:$NETCDF/lib:$HDF5/lib:${LD_LIBRARY_PATH:-}

which mpiicc mpiicpc mpiifort

echo "${PIO-unset}"

最后一条命令应输出 unset。本文实际测试中,链接 PIO 2.7.0 的 atmosphere_model 在读取初始场时无法正常运行,更换 MPI 后问题仍然存在,因此这里直接使用 SMIOL。

MPAS-A 通常要编译两个核心:

1

init_atmosphere:生成静态场、网格相关文件和气象初始场。

2

atmosphere:执行大气积分。

先编译初始化程序:

...bash

cd "$MPAS_SRC"

make -j8 intel-mpi CORE=init_atmosphere CFLAGS="-O3 -std=gnu99 -DSINGLE_PRECISION"

再编译大气模式:

...bash

make -j8 intel-mpi CORE=atmosphere CFLAGS="-O3 -std=gnu99 -DSINGLE_PRECISION"

生成 Thompson 微物理查找表

编译 atmosphere 时会在 MPAS 源码顶层生成 build_tables,但不会自动执行。如果后续使用 mp_thompson 或 mp_thompson_aerosols 微物理方案,需要执行一次该程序,生成四个 Thompson 二进制查找表。

...bash

cd "$MPAS_SRC"

./build_tables

cp MP_THOMPSON_QRacrQG_DATA.DBL MP_THOMPSON_QRacrQS_DATA.DBL MP_THOMPSON_freezeH2O_DATA.DBL MP_THOMPSON_QIautQS_DATA.DBL src/core_atmosphere/physics/physics_wrf/files/

build_tables 只能串行运行,不要使用 mpiexec。生成过程通常需要 15~20 分钟,看到 Finished building all tables. 表示完成。复制到 physics_wrf/files 目录后,即使以后执行 make clean,这些查找表也能保留下来,并在再次编译 atmosphere 时自动链接到 MPAS 顶层目录。

MPAS-A 8.4.1 的 intel-mpi 构建目标会使用 mpiifortmpiicc 和 mpiicpc。这里显式加入 -std=gnu99,是为了让 Intel Classic C 编译器同时支持 MPAS Registry 使用的 C99 循环声明,以及 ezxml 使用的 GNU/POSIX 接口。-DSINGLE_PRECISION 则保留了原构建目标的单精度定义。

如果编译成功,末尾摘要应包含类似信息:

...text

Parallel version is on.

Using the SMIOL library.

PART 06

常见报错速查

TROUBLESHOOTING · 报错定位

MPAS 编译到物理过程时突然失败

重点检查 src/core_atmosphere/physics/physics_mmmphysics_noaa/UGWP 和 physics_wrf/files 是否完整。很多时候并不是 Fortran 代码有问题,而是构建节点无法访问 GitHub。

联网环境下可以回到 MPAS 源码目录,手动补齐外部源码和物理过程查找表:

...bash

cd "$MPAS_SRC/src/core_atmosphere" && ./tools/manage_externals/checkout_externals --externals Externals.cfg && cd physics && ./checkout_data_files.sh

离线集群则应在联网机器上完成上述下载,再将完整的 MPAS 目录打包到集群上编译。

gen_inc.c 报 expected an expression

使用 Intel Classic C 编译器时,Registry 工具可能会出现下面的错误:

...text

gen_inc.c(2754): error: expected an expression

for (int i = 0; i < *num_keys; i++) {

gen_inc.c(2754): error: identifier "i" is undefined

gen_inc.c 使用了 for (int i = …) 这类 C99 语法,但 intel-mpi 目标默认只给 icc 传入 -O3。不要只加严格的 -std=c99,因为它会继续触发后面的 ezxml.c 问题。直接使用 -std=gnu99 更稳妥。

如果前一次编译已经失败,先清理对应核心:

...bash

make clean CORE=init_atmosphere

然后重新编译:

...bash

make -j8 intel-mpi CORE=init_atmosphere CFLAGS="-O3 -std=gnu99 -DSINGLE_PRECISION"

编译大气积分程序时做法相同,只需把核心名改为 atmosphere

...bash

make -j8 intel-mpi CORE=atmosphere CFLAGS="-O3 -std=gnu99 -DSINGLE_PRECISION"

ezxml.c 报 MADV_SEQUENTIAL 未定义

如果为解决上一个错误而使用了严格的 -std=c99,编译往往会继续停在 ezxml.c

...text

ezxml.c(647): error: identifier "MADV_SEQUENTIAL" is undefined

ezxml.c(649): error: identifier "MADV_NORMAL" is undefined

还可能同时看到 strdup 和 madvise 被隐式声明的警告。原因是严格 C99 模式隐藏了部分 GNU/POSIX 声明和宏。把 -std=c99 改为 -std=gnu99,清理后重新编译即可。不需要修改 ezxml.c 源码。

PART 07

参考资料

REFERENCES · 官方资料

MPAS 8.4.1 官方发布页:https://github.com/MPAS-Dev/MPAS-Model/releases/tag/v8.4.1

CMake 3.31.8 官方发布页:https://github.com/Kitware/CMake/releases/tag/v3.31.8

ParallelIO 2.7.0:https://github.com/NCAR/ParallelIO/releases/tag/pio2_7_0

离线安装包获取

如果服务器不能访问 GitHub,可以使用已包含 MMM-physics、UGWP 和物理过程查找表的完整安装包。

私信回复「MPAS安装」,获取完整安装包和依赖库。

既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。

点赞
在看
转发

THANKS FOR READING