链接地球系统模型的 PnetCDF、NetCDF-C 和 NetCDF-Fortran 库

Linking PnetCDF, NetCDF-C and NetCDF-Fortran libraries for an earth system model

提问人:Aatreyee 提问时间:11/10/2023 最后编辑:Dima ChubarovAatreyee 更新时间:11/13/2023 访问量:74

问:

我正在尝试研究地球系统模型,但我是新手。 目前,我只尝试运行一个计算密集度较低的测试用例。

我的系统是Ubuntu 20.04。我按以下顺序构建了所需的库 - mpich、pnetcdf、zlib、hdf5、netcdf-c、netcdf-fortran、lapack 和 blas。版本如下(我的 GCC 和 gfortran 版本是 9.4.0):mpich-3.3.1、pnetcdf-1.12.3、zlib-1.2.13hdf5-1.10.5、netcdf-c-4.9.0、netcdf-fortran-4.6.0LAPACKBLAS 3.11。 对于具有并行 I/O 支持的构建,我在安装时遵循了 Pnetcdf 的顺序,然后是 hdf5,然后是 Netcdf-c,最后是 Netcdf-fortran。所有库和包都正确安装,没有任何错误,并且使用与我用于模型相同的编译器。

我现在遇到的问题与库的链接(pnetcdf、netcdf-c 和 netcdf-fortran)有关,更具体地说是顺序,正如专门用于该模型的论坛所指出的那样。 在模型的构建结束时,当它尝试创建单个可执行文件时,它会失败(collect2:错误:ld 返回 1 退出状态)。以下是显示错误的命令

mpif90 -o /home/ubuntuvm/projects/cesm/scratch/testrun11/bld/cesm.exe \
cime_comp_mod.o cime_driver.o component_mod.o component_type_mod.o \
cplcomp_exchange_mod.o map_glc2lnd_mod.o map_lnd2glc_mod.o \
map_lnd2rof_irrig_mod.o mrg_mod.o prep_aoflux_mod.o prep_atm_mod.o \
prep_glc_mod.o prep_ice_mod.o prep_lnd_mod.o prep_ocn_mod.o \
prep_rof_mod.o prep_wav_mod.o seq_diag_mct.o seq_domain_mct.o \
seq_flux_mct.o seq_frac_mct.o seq_hist_mod.o seq_io_mod.o \
seq_map_mod.o seq_map_type_mod.o seq_rest_mod.o t_driver_timers_mod.o \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -latm \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -lice \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -llnd \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -locn \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -lrof \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -lglc \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -lwav \
-L/home/ubuntuvm/projects/cesm/scratch/testrun11/bld/lib/ -lesp \
-L../../gnu/mpich/nodebug/nothreads/mct/noesmf/c1a1l1i1o1r1g1w1e1/lib \
-lcsm_share -L../../gnu/mpich/nodebug/nothreads/lib -lpio -lgptl \
-lmct -lmpeu  -L/home/ubuntuvm/CESM/lib -lnetcdff \
-Wl,-rpath=/home/ubuntuvm/CESM/lib -lnetcdf -lm -lnetcdf -lhdf5_hl \
-lhdf5 -lpnetcdf -ldl -lm -lz -Wl,-rpath=/home/ubuntuvm/CESM/lib \
-lpnetcdf -L/usr/local/lib -llapack -L/usr/local/lib -lblas \
-L/home/ubuntuvm/CESM/lib -lpnetcdf  -L/home/ubuntuvm/CESM/lib

以下是部分错误,其中 libpio.a 是在上述命令之前构建的组件库

/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_copy_att':
nf_mod.F90:(.text+0x31): undefined reference to `nfmpi_copy_att'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_def_var_md':
nf_mod.F90:(.text+0x3b5): undefined reference to `nfmpi_def_var'
/usr/bin/ld: nf_mod.F90:(.text+0x4fe): undefined reference to `nfmpi_def_var'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_def_dim':
nf_mod.F90:(.text+0xab9): undefined reference to `nfmpi_def_dim'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_redef':
nf_mod.F90:(.text+0xeb9): undefined reference to `nfmpi_redef'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_enddef':
nf_mod.F90:(.text+0xff0): undefined reference to `nfmpi_enddef'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_inq_dimlen':
nf_mod.F90:(.text+0x115c): undefined reference to `nfmpi_inq_dimlen'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_inq_dimname':
nf_mod.F90:(.text+0x14c2): undefined reference to `nfmpi_inq_dimname'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_pio_inq_dimid':
nf_mod.F90:(.text+0x1821): undefined reference to `nfmpi_inq_dimid'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_inq_varnatts_vid':
nf_mod.F90:(.text+0x1c24): undefined reference to `nfmpi_inq_varnatts'
/usr/bin/ld: ../../gnu/mpich/nodebug/nothreads/lib/libpio.a(nf_mod.F90.o): in function `__nf_mod_MOD_inq_vardimid_vid':
nf_mod.F90:(.text+0x1fcc): undefined reference to `nfmpi_inq_vardimid'

这些库的链接如下

-L/home/ubuntuvm/CESM_Library/lib -lnetcdff -lnetcdf \
-Wl,-rpath=/home/ubuntuvm/CESM_Library/lib -lnetcdf -lm -lnetcdf -lhdf5_hl \
-lhdf5 -lpnetcdf -ldl -lm -lz -Wl,-rpath=/home/ubuntuvm/CESM_Library/lib -lpnetcdf

我在这里做错了什么?我将不胜感激有关图书馆顺序的任何建议,并很乐意提供可能需要的任何其他细节。

linker-errors netcdf mpich cime

评论

0赞 Dima Chubarov 11/10/2023
欢迎来到 Stack Overflow!您的问题中缺少的是编译器错误消息的详细信息。如何运行编译命令?你用吗?make
1赞 Aatreyee 11/10/2023
实际上,我的模型是CESM2.1.3。它由 CIME 驱动,有助于配置、编译和执行地球系统模型。CIME 由我必须使用的 python 脚本组成。工作流调用以下脚本: 1.“create_newcase”创建案例, 2.'case.setup',用于创建 Run 和 Exec 目录,并创建 macros.make、组件名称列表、3.case.build 用于构建单个组件库和模型可执行文件 4.case.submit 运行模型。我现在的问题在第三步。
0赞 Dima Chubarov 11/10/2023
错误消息适用于 libpnetcdf 中的函数。由于 -lpnetcdf 出现在命令行上的 -lpio 之后,因此除非它不兼容,否则会使用它。您是自己构建了 libpnetcdf,还是使用了发行版提供的库?请注意,并行库必须使用与使用它们的代码相同的 MPI 编译器和 MPI 库来构建。
1赞 Aatreyee 11/10/2023
是的,我自己构建了 libpnetcdf,并且还使用 mpich(configure、make、make tests、make check、make ptest、make ptests 和 make install)编译了所有内容。没有错误。我已经使用 nm libpnetcdf.a 检查了那里缺少的符号。我可以在那里找到它们。我应该尝试更改 pnetcdf 的版本吗?
0赞 Dima Chubarov 11/11/2023
看起来很难重现您的问题,因为您的 CESM 安装不是很便携。即使 dockerized 也需要相当多的配置。但是,有报道称在 Ubuntu 上成功设置了 CESM。例如,这个中型帖子。您是否尝试重现此配置?

答:

0赞 Dima Chubarov 11/11/2023 #1

虽然很难重现此特定错误。看起来问题出在PNetCDF库上,该库似乎不包含某些FORTRAN函数。

以下是从头开始使用 OpenMPI 在 Ubuntu 上设置 CESM 的简要说明。

警告:此示例适用于 Ubuntu 22.04 (Jammy),但应该适用于所有最新的 Ubuntu 版本。这适用于 GCC 版本 11.4。从 OpenMPI 切换到 MPICH 可能需要进行某些更改。

它基于 Yonash Mersha 的一篇非常详细的帖子。如果似乎缺少某些细节,可以将下面的说明与该帖子中的说明进行比较。

假设主机名是 。ubuntu-jammy

  1. 安装必要的系统软件包和库
apt-get install -y gcc g++ gfortran build-essential cmake git \
subversion python-is-python3 perl vim python3-pip libxml2-utils unzip libopenmpi-dev
  1. 对于 OpenMPI 测试,请配置计算机上的插槽数。 假设您有 8 个 CPU 内核。此数字将在下面多次用作 选项的参数。-jmake
echo "ubuntu-jammy slots=8" >> /etc/openmpi/opempi-default-hostfile
  1. 下载 CESM 并设置 CIME
mkdir CESM
cd CESM
RUN git clone -b release-cesm2.1.3 https://github.com/ESCOMP/CESM.git my_cesm_sandbox
mkdir ~/.cime
export CIME_MODEL=cesm
mkdir -p cesm/inputdata
  1. 一些UCAR SVN服务器使用自签名证书或来自某个未知CA的证书,因此请在第267行附近进行编辑,以添加忽略未知CA的选项。这可能会引入漏洞,因此请三思而后行。 使 SVN 命令如下所示:my_cesm_sandbox/manage_externals/manic/repository_svn.py
cmd = ['svn', 'checkout', '--non-interactive', '--trust-server-cert-failures=unknown-ca', '--quiet', url, repo_dir_path]
  1. 查看型号代码
./manage_externals/checkout_externals

用于检查是否已交付所有必要的代码。./manage_externals/checkout_externals -S

  1. 现在构建 IO 库和 Lapack。我们假设 CESM 的库将安装在 下。$HOME/CESM/lib
CESM_LIB_DIR=$HOME/CESM/lib
ZLIB=$CESM_LIB_DIR/zlib
HDF5=$CESM_LIB_DIR/hdf5
NETCDF=$CESM_LIB_DIR/netcdf
PNETCDF=$CESM_LIB_DIR/pnetcdf
export ZLIB HDF5 NETCDF PNETCDF
  1. 下载并解压 zlibhdf5、netcdf-c、netcdf-fortranpnetcdflapack

  2. 要构建 zlib,请使用默认设置: 在包含 zlib 源码的目录中

./configure --prefix=$ZLIB
make -j 8
make check
make install
  1. 重要提示:构建具有并行支持的 HDF5 在包含 HDF5 源的目录中
CPPFLAGS="-I$ZLIB/include" LDFLAGS="-L$ZLIB/lib" \
CC=mpicc CXX=mpicxx ./configure --prefix=$HDF5 --with-zlib=$ZLIB --enable-hl --enable-fortran --enable-parallel

配置后,检查是否启用了并行支持:

        SUMMARY OF THE HDF5 CONFIGURATION
        =================================
...
Features:
---------
                   Parallel HDF5: yes
Parallel Filtered Dataset Writes: yes
              Large Parallel I/O: yes
              High-level library: yes
...

现在构建、检查和安装。

make -j8
make -j8 check
make install
  1. 构建支持 Parallel-NetCDF4 的 NetCDF C 绑定 在包含 netcdf-c 源的目录中
CPPFLAGS="-I$HDF5/include -I$ZLIB/include" LDFLAGS="-L$HDF5/lib -L$ZLIB/lib" \
CC=mpicc CXX=mpicxx ./configure --prefix=$NETCDF --disable-dap --enable-parallel4

确保启用了正确的选项

# NetCDF C Configuration Summary
==============================
...
HDF5 Support:       yes
NetCDF-4 API:       yes
NC-4 Parallel Support:  yes
...

现在制作、检查和安装

make -j8
make -j8 check
make install
  1. 生成 NetCDF FORTRAN 绑定 在包含 netcdf-fortran 源的目录中
CPPFLAGS="-I$NETCDF/include -I$HDF5/include -I$ZLIB/include" \
FFLAGS="-fallow-argument-mismatch -fallow-invalid-boz" \
LDFLAGS="-L$NETCDF/lib -L$HDF5/lib -L$ZLIB/lib" LD_LIBRARY_PATH="$NETCDF/lib:$LD_LIBRARY_PATH" \
CC=mpicc CXX=mpicxx FC=mpifort ./configure --prefix=$NETCDF

检查并行选项是否按如下方式配置:

# NetCDF Fortran Configuration Summary
==============================
...
Parallel IO:                    yes
NetCDF4 Parallel IO:            yes
PnetCDF Parallel IO:            no
...

现在构建、检查和安装

make -j8 
make -j8 check
make install
  1. 构建 PNetCDF 切换到包含 pnetcdf 源的目录
CPPFLAGS="-I$NETCDF/include -I$HDF5/include -I$ZLIB/include" \
FFLAGS="-fallow-argument-mismatch -fallow-invalid-boz" \
LDFLAGS="-L$NETCDF/lib -L$HDF5/lib -L$ZLIB/lib" \
LD_LIBRARY_PATH="$NETCDF/lib:$LD_LIBRARY_PATH" \
CC=mpicc CXX=mpicxx FC=mpifort ./configure --prefix=$PNETCDF --enable-shared --enable-fortran --enable-profiling --enable-large-file-test --with-netcdf4

make -j8
make -j8 tests
make check
make ptest
make ptests
make install

在 4 个处理器上运行时,至少应有此数字。 如果某些测试因系统没有足够的处理器而失败,请不要担心,因为某些测试需要 10 个处理器才能实现 MPI 或更多。ptest

  1. 构建和安装 LAPACK

切换到 LAPACK 源目录

make -j8 blaslib
make -j8 lapacklib
mkdir -p $LAPACK/lib
mv librefblas.a $LAPACK/lib/libblas.a
mv liblapack.a $LAPACK/lib/liblapack.a
  1. 配置计算机 将以下文本复制到 .cime/config_machines.xml
<?xml version="1.0"?>
<config_machines version="2.0">
 <machine MACH="ubuntu-jammy">
    <DESC>
      Example port to Ubuntu Jammy linux system with gcc, netcdf, pnetcdf and openmpi
    </DESC>
    <NODENAME_REGEX>ubuntu-jammy</NODENAME_REGEX>
    <OS>LINUX</OS>
    <COMPILERS>gnu</COMPILERS>
    <MPILIBS>openmpi</MPILIBS>
    <PROJECT>none</PROJECT>
    <SAVE_TIMING_DIR> </SAVE_TIMING_DIR>
    <CIME_OUTPUT_ROOT>$ENV{HOME}/cesm/scratch</CIME_OUTPUT_ROOT>
    <DIN_LOC_ROOT>$ENV{HOME}/cesm/inputdata</DIN_LOC_ROOT>
    <DIN_LOC_ROOT_CLMFORC>$ENV{HOME}/cesm/inputdata/lmwg</DIN_LOC_ROOT_CLMFORC>
    <DOUT_S_ROOT>$ENV{HOME}/cesm/archive/$CASE</DOUT_S_ROOT>
    <BASELINE_ROOT>$ENV{HOME}/cesm/cesm_baselines</BASELINE_ROOT>
    <CCSM_CPRNC>$ENV{HOME}/cesm/tools/cime/tools/cprnc/cprnc</CCSM_CPRNC>
    <GMAKE>make</GMAKE>
    <GMAKE_J>8</GMAKE_J>
    <BATCH_SYSTEM>none</BATCH_SYSTEM>
    <SUPPORTED_BY>[email protected]</SUPPORTED_BY>
    <MAX_TASKS_PER_NODE>8</MAX_TASKS_PER_NODE>
    <MAX_MPITASKS_PER_NODE>8</MAX_MPITASKS_PER_NODE>
    <PROJECT_REQUIRED>FALSE</PROJECT_REQUIRED>
    <mpirun mpilib="default">
      <executable>mpiexec</executable>
      <arguments>
        <arg name="ntasks"> -np {{ total_tasks }} </arg>
      </arguments>
    </mpirun>
    <module_system type="none" allow_error="true">
    </module_system>
    <environment_variables>
      <env name="NETCDF">$ENV{HOME}/CESM/lib/necdf</env>
      <env name="PNETCDF">$ENV{HOME}/CESM/lib/pnetcdf</env>
      <env name="OMP_STACKSIZE">256M</env>
    </environment_variables>
    <resource_limits>
      <resource name="RLIMIT_STACK">-1</resource>
    </resource_limits>
  </machine>
</config_machines>

验证 XML 文件

xmllint --noout --schema $HOME/CESM/my_cesm_sandbox/cime/config/xml_schemas/config_machines.xsd $HOME/.cime/config_machines.xml
  1. 配置编译器 将以下文本放在.cime/config_compilers.xml
<?xml version="1.0" encoding="UTF-8"?>
<config_compilers version="2.0">

  <compiler>
        <LDFLAGS>
                <append compile_threaded="true"> -fopenmp </append>
        </LDFLAGS>
        <FFLAGS>
                <append>   -fallow-argument-mismatch -fallow-invalid-boz</append>
        </FFLAGS>
        <SFC>gfortran</SFC>
        <SCC>gcc</SCC>
        <SCXX>g++</SCXX>
        <MPIFC>mpifort</MPIFC>
        <MPICC>mpicc</MPICC>
        <MPICXX>mpicxx</MPICXX>
        <CXX_LINKER>FORTRAN</CXX_LINKER>
        <NETCDF_PATH>$ENV{HOME}/CESM/lib/nectdf</NETCDF_PATH>
        <PNETCDF_PATH>$ENV{HOME}/CESM/lib/pnectdf</PNETCDF_PATH>
        <SLIBS>
                <append>-L $ENV{HOME}/CESM/lib/nectdf/lib -lnetcdff -lnetcdf -lm</append>
                <append>-L $ENV{HOME}/CESM/lib/lapack/lib -llapack -lblas</append>
        </SLIBS>
</compiler>

</config_compilers>

验证 xml 文件

xmllint --noout --schema $HOME/CESM/my_cesm_sandbox/cime/config/xml_schemas/config_compilers_v2.xsd $HOME/.cime/config_compilers.xml
  1. 创建一个新案例,设置它,然后构建它。
cd $HOME/CESM/my_cesm_sandbox
cime/scripts/create_newcase --case mycase --compset X --res f19_g16
cd mycase
./case.setup
./case.build

评论

0赞 Aatreyee 11/12/2023
非常感谢您的回复。我会尝试这个并更新。
0赞 Dima Chubarov 11/12/2023
@Aatreyee,如果有任何失败,请发表评论,我可以重现它并为帖子添加修复程序。
0赞 Aatreyee 11/13/2023
非常感谢,我将根据您的建议从头开始一切,并将对此进行更新。但是,我确实想澄清我应该使用 OpenMPI 还是 MPICH?
0赞 Dima Chubarov 11/13/2023
@Aatreyee,我使用 OpenMPI 的原因有很多,这源于我过去的经验。如果您对 MPICH 更满意,我想我们也可以尝试一下。但无论如何,我建议从发行版附带的 MPICH 或 OpenMPI 的构建开始,直到您 100% 确信您知道您的构建在哪些方面与机器附带的有所不同。
1赞 Aatreyee 11/14/2023
非常感谢,模型构建现已成功完成。
1赞 Aatreyee 11/23/2023
根据您的建议,已经发布了另一个问题,其中包含问题 mpi 的详细信息