External Libraries
Depending on the ROMS configuration, several third-party libraries are required for linking and compiling an application.
ARPACK (ARnoldi PACKage)
Serial and parallel legacy libraries applied to solve large eigenvalue problems using either the Implicitly Restarted Arnoldi Method (IRAM) for sparse matrices or the Lanczos algorithm for symmetric matrices. It includes a subset of the BLAS and LAPACK libraries. Some of its functions are used in 4D-Var and the adjoint-based stability analysis propagators.
To obtain ARPACK, execute the following:
> cd ARPACK
To compile, customize ARmake.inc for the desired compiler and its flags for the serial (FC and FFLAGS) and parallel (PFC and PFFLAGS) versions of the library. Once configured type:
to build libarpack.a and libparpack.a. Once the libraries are built you can move them anywhere you like to make it easier to tell ROMS where to find them through environmental variables or with the my_build_paths script.
Note: Prior to SVN revision 1080 (July 23, 2021), ARPACK was distributed in the ROMS Lib/ARPACK subdirectory. For more information about why this was changed see TRAC ticket #891
ESMF (Earth System Modeling Framework)
High-performance, open-source library for grid interpolation, remapping, and data exchange between coupled Earth System Model (ESM) components. It includes the NUOPC (National Unified Operation Prediction Capability) layer that provides templates and protocols for sequential and concurrent coupling between ESM components. The NUOPC cap file is a Fortran module layer that sits on top of each ESM component that provides the protocols and methods to interact and share data in a coupled system.
ROMS supports version 8.0 or higher since the NUOPC layer includes the native CoupleSets for ESM applications with nested grids. Various types of connections are possible, like nest-to-nest, fine-to-coarse, or coarse-to-fine. The user decides which nested grids to connect.
- Downloaded from github:
- Configure with environment variables:> export ESMF_DIR=/projects/dmcs_1/src/esmfNote that ESMF_MPIRUN is only needed for running test on clusters that use scheduling systems like SLURM. Your submission script should take -np, N (number of processes requested), and programName (in that order) as arguments to construct the appropriate command to run using the scheduling system on your cluster. A SLURM example is provided below:
> export ESMF_COMM=mvapich2
> export ESMF_COMPILER=intel
> export ESMF_BOPT=O
> export ESMF_OPTLEVEL=3
> export ESMF_ABI=64
> export ESMF_INSTALL_PREFIX=/ESMF/install/dir ESMF_NETCDF="/path/to/netcdf/bin/nc-config"
> export ESMF_NETCDF_LIBS="-lnetcdf -lhdf5_hl -lhdf5 -lm -lz -lcurl -lhdf5_hl -lhdf5 -lm -lz -lcurl"
> export ESMF_NETCDF_LIBPATH="/path/to/netcdf/lib /path/to/hdf5/lib"
> export ESMF_SHARED_LIB_BUILD=OFF
> export ESMF_MPIRUN=/path/to/cluster/submission/script# 1) <this_script> -np N prog
# runs N copies of executable "prog" in parallel. The script must hide all
# of the system specific details, such as going through a queueing system
# and/or calling a system specific mpirun script with modified arguments.
#
# 2) The output of the application must arrive at the calling shell via
# stdout and stderr.
if [ "$1" != "-np" ]
then
echo "Usage: mpirun -np # prog"
exit 1
fi
num_procs=$2
shift 2
prog=$*
echo "srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog"
srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog
- Build, test, and install:> make -j 10
> make all_tests
> make install
MCT (Model Coupling Toolkit)
Open-source library distributed as a set of Fortran-90 modules for constructing a coupled model system from Earth System Model (ESM) components (Larson et al., 2004). Each component model has its own grid and runs on its own set of processors. The MCT library provides protocols for decomposition and allocation of model grids among different processors, efficient transfer of data fields between the different models, and interpolation algorithms for the data fields that are transferred.
The MCT library is used to couple ROMS atmosphere models (like WRF) and wave models (like SWAN and WW3). For example, SWAN sends to ROMS arrays of wave height, wavelength, average wave periods at the surface and near the bottom, wave propagation direction, near-bottom orbital velocity, and wave-energy dissipation rate. ROMS provides SWAN arrays of water depth, sea-surface elevation, and current velocity. Data exchange between SWAN and ROMS occurs at user-defined synchronization intervals. The frequency of data exchange depends on the application. If the exchanged fields fluctuate rapidly, more frequent synchronization is required. However, data exchange increases run time, so experience is required to determine the optimum synchronization interval for each application.
MCT is available via github:
NetCDF (Network Common Data Form)
Open-source, machine-independent libraries for storing self-describing scientific data into portable, scalable, appendable, and sharable computer files. It provides API in several computer languages to create files, to write data into a file, to read data from the file, and access information about the dataset dimensions, variables, and attributes.
ROMS uses NetCDF for all its input and output data management. Its NetCDF3 or NetCDF4 type files can be processed using the standard library developed and distributed UCAR/Unidata, the Parallel-IO (PIO) developed at ANL/NCAR (Dennis et al., 2012; Hartnett and Edwards, 2021), or the Software for Cashing Output and Reads for Parallel I/O (SCORPIO) library available in E3SM. We have migrated to the Fortran-90 API interface, which consists of a library and one or two module files. See the makefile and build script for how to tell ROMS where these are located. You will have to use a copy of the library and module files that were compiled using the same compiler you are using to compile ROMS - this is especially true for the module files.
Building NetCDF-4/HDF5
NetCDF-4 uses HDF5 for it's underlying data format so you first need to build HDF5. We recommend 1.10.6 because 1.10.7 causes errors in the NetCDF-C test suite. Here we will describe how to build parallel versions for use on an HPC cluster. We will note what changes are necessary if you are building for a system that doesn't have parallel I/O.
Building HDF5
- First, download HDF5 source code as a gzipped tarball or via git clone:or
- Configure HDF5:> ./configure CC=mpicc CXX=mpicxx FC=mpifort \Note: RUNPARALLEL is only needed if your system uses a scheduler to run MPI jobs. The example here is for a SLURM system but you will need to adjust this for your cluster.
RUNPARALLEL="srun --nodes=1 --ntasks=6 --cpus-per-task=1 --time=00:13:00 --export=ALL " \
--prefix=/path/to/parallel/hdf5/1.10.6 --enable-static-exec --enable-shared=no \
--enable-parallel --disable-silent-rules --enable-fortran
Note: To compile serial, remove RUNPARALLEL=... and --enable-parallel and change the CC, CXX, and FC to the corresponding serial compilers (e.g. gcc, g++, and gfortran).
Note: If you would like shared libraries to be built, also remove --enable-shared=no.
- Build, test, and install HDF5:> make -j 5
> make all_tests
> make install
Building NetCDF-C
The C and Fortran APIs for NetCDF are in separate packages and the C version must be built first.
- Download NetCDF-C source code as a gzipped tarball or via git clone:or
- Configure NetCDF-C:> ./configure CC=mpicc FC=mpifort CFLAGS=-O3 CPPFLAGS="-I/path/to/parallel/hdf5/1.10.6/include" \Note that --with-mpiexec is only needed for running test on clusters that use scheduling systems like SLURM. Your submission script should take -n, N (number of processes requested), and programName (in that order) as arguments to construct the appropriate command to run using the scheduling system on your cluster. A SLURM example is provided below:
LDFLAGS="-L/path/to/parallel/hdf5/1.10.6/lib" \
--with-mpiexec=/path/to/job/submistion/script \
--prefix=/path/to/parallel/netcdf/4.7.4 \
--enable-parallel-tests --disable-shared --disable-silent-rules# 1) <this_script> -n N progNote: To compile serial, remove --with-mpiexec and --enable-parallel-tests and change the CC, and FC to the corresponding serial compilers (e.g. gcc and gfortran).
# runs N copies of executable "prog" in parallel. The script must hide all
# of the system specific details, such as going through a queueing system
# and/or calling a system specific mpirun script with modified arguments.
#
# 2) The output of the application must arrive at the calling shell via
# stdout and stderr.
if [ "$1" != "-n" ]
then
echo "Usage: mpirun -n # prog"
exit 1
fi
num_procs=$2
shift 2
prog=$*
echo "srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog"
srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog
Note: If you would like shared libraries to be built, also remove --disable-shared.
- Build, test, and install NetCDF-C:> make -j 5
> make check
> make install
Building NetCDF-Fortran
Now we can build the Fortran API.
- Download NetCDF-Fortran source code as a gzipped tarball or via git clone:orgit clone https://github.com/Unidata/netcdf-fortran
> cd netcdf-fortan
> git checkout tags/v4.5.3
> autoconf -i
- There is a bug/typo in configure that makes nf-config report the wrong linking information to ROMS. To fix the error, edit the configure file (and configure.ac if you plan to run autoconf -i again) and change the line:NC_FLIBS="-lnetcdff $NC_FLIBS"toNC_FLIBS="-lnetcdff $NC_LIBS"more details can be found here.
- Configure NetCDF-Fortran. Note that we set prefix to the same as NetCDF-C so the C and Fortran libraries live together:> ./configure CC=mpicc FC=mpifort CFLAGS=-O3 FFLAGS=-O3 \Note that --with-mpiexec should point to the submision script you created while building NetCDF-C and is only needed for running test on clusters that use scheduling systems like SLURM.
CPPFLAGS="-I/path/to/parallel/hdf5/1.10.6/include -I/path/to/parallel/netcdf/4.7.4/include" \
LDFLAGS="-L/path/to/parallel/hdf5/1.10.6/lib -L/path/to/parallel/netcdf/4.7.4/lib" \
LIBS="-lnetcdf -lhdf5_hl -lhdf5 -lm -lz -lcurl" \
--with-mpiexec=/path/to/job/submistion/script \
--prefix=/path/to/parallel/netcdf/4.7.4 \
--enable-parallel-tests --disable-shared --disable-silent-rules
Note: To compile serial remove --with-mpiexec and --enable-parallel-tests and change the CC, and FC to the corresponding serial compilers (e.g. gcc and gfortran).
Note: If you would like shared libraries to be built, also remove --disable-shared.
- If you are running on clusters that use scheduling systems like SLURM, you will need to edit 4 testing scripts replacing all occurrences of mpiexec with the full path to the submision script you created for NetCDF-C:> vi examples/F90/run_f90_par_examples.sh
> vi nf03_test4/run_f90_par_test.sh
> vi nf_test4/run_f77_par_test_03.sh
> vi nf_test4/run_f77_par_test.sh
- Build, test, and install NetCDF-C:> make -j 5
> make check
> make install
PIO (Parallel I/O)
Open-source parallel library for reading and writing distributed arrays to several scientific data formats like pNetCDF, NetCDF3, and NetCDF4/HDF5. PIO provides the flexibility to regulate the number of I/O tasks through data rearrangement between computational and I/O processes to improve performance and memory usage. It allows both synchronous and asynchronous I/O. In synchronous mode, a subset of processes performs both I/O and computations (MPI intra-communications). Alternatively, in asynchronous mode, the I/O is carried out by a set of disjointed and dedicated processes (MPI inter-communications).
The PIO or SCORPIO library is intended for ROMS Message Passing Interface (MPI) applications running on a large number of processes in an HPC computer with a Parallel File System (Lustre, GPFS, and so on). It uses the MPI-IO interface to facilitate the partitioning of data across computational or dedicated I/O processes. Both PIO and SCORPIO will work with ROMS svn revision 1064 (May 10, 2021) or newer but we recommend PIO for its better performance. We recommend you read the manuals for all the build options, but below we show an example build process for both PIO and SCORPIO.
Building PIO (autotools)
PIO can use NetCDF (version 4.6.1+) and/or PnetCDF (version 1.9.0+) for I/O. NetCDF may be built with or without netCDF-4 features. NetCDF is required for PIO, PnetCDF is optional. However, the ROMS build system assumes that PIO is built with PnetCDF support and will need customization if PIO is built without it.
The NetCDF C library must be built with MPI, which requires that it be linked with an MPI-enabled version of HDF5. Optionally, NetCDF can be built with DAP support, which introduces a dependency on CURL. HDF5, itself, introduces dependencies on LIBZ and (optionally) SZIP.
PIO recently introduced a NetCDF integration option that allows standard NetCDF library calls to be implemented with the PIO library but ROMS Parallel I/O is not currently implemented this way. In order to build PIO with NetCDF integration, you will need NetCDF version 4.7.4 or higher. However, the Fortran API integration has not been implemented in ROMS.
The PIO library can be built with the classic Autotools or Cmake. For PIO we show the Autotools procedure but will show Cmake for SCORPIO in the next section.
- First download the PIO source code as a gzipped tarball or via git clone:or> git clone https://github.com/NCAR/ParallelIO
> cd ParallelIO
> git checkout tags/pio2_5_4
> autoconf -i
- If you downloaded the gzipped tarball, you should run make clean because some Fortran .mod files are included and need to be removed:> make clean
- Configure PIO:> ./configure CC=mpicc CXX=mpicxx FC=mpifort CFLAGS=-O3 FFLAGS=-O3 FCFLAGS=-O3 \Note that --with-mpiexec is only needed for running test on clusters that use scheduling systems like SLURM. Your submission script should take -n, N (number of processes requested), and programName (in that order) as arguments to construct the appropriate command to run using the scheduling system on your cluster. A SLURM example is provided below:
CPPFLAGS="-I/path/to/netcdf/include -I/path/to/hdf5/include -I/path/to/pnetcdf/include" \
LDFLAGS="-L/path/to/netcdf/lib -L/path/to/hdf5/lib -L/path/to/pnetcdf/lib" \
LIBS="-lhdf5_hl -lhdf5 -lm -lcurl -lz" \
--with-mpiexec=/path/to/cluster/submission/script \
--prefix=/pio/install/path --enable-fortran --disable-timing \
--disable-silent-rules --disable-shared# 1) <this_script> -n N prog
# runs N copies of executable "prog" in parallel. The script must hide all
# of the system specific details, such as going through a queueing system
# and/or calling a system specific mpirun script with modified arguments.
#
# 2) The output of the application must arrive at the calling shell via
# stdout and stderr.
if [ "$1" != "-n" ]
then
echo "Usage: mpirun -n # prog"
exit 1
fi
num_procs=$2
shift 2
prog=$*
echo "srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog"
srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog
- Build, test, and install PIO:> make -j 5Warning: If you are using the Intel compilers, you will probably need to remove "test_darray_async_many" from line 50 of test/cunit/run_tests.sh for make check to complete without errors. Details here.
> make check
> make install
Building SCORPIO (Cmake)
Note: SORPIO recently released version 1.2.0 and 1.2.1 but ROMS has not been tested with these versions. It is likely that the new version will work fine with ROMS but use these new versions at your own risk.
SCORPIO can use NetCDF (version 4.3.3+), PnetCDF (version 1.6.0+) or ADIOS (version 2.6.0+) for I/O. ADIOS is not implemented in ROMS.
Ideally, the NetCDF version should be built with MPI, which requires that it be linked with an MPI-enabled version of HDF5. Optionally, NetCDF can be built with DAP support, which introduces a dependency on CURL. Additionally, HDF5, itself, introduces dependencies on LIBZ and (optionally) SZIP. If your NetCDF is built with DAP support, you will need to edit cmake/TryNetCDF_DAP.c, changing line 8 from
to
- Download the SCORPIO source code:If your NetCDF is built with DAP support, you will need to edit cmake/TryNetCDF_DAP.c, changing line 8 from #if NC_HAS_DAP==1to#if NC_HAS_DAP==1 || NC_HAS_DAP2==1 || NC_HAS_DAP4==1
- Configure SCORPIO:> cd ..Note that -DMPIEXEC is only needed for running test on clusters that use scheduling systems like SLURM. Your submission script should take -n, N (number of processes requested), and programName (in that order) as arguments to construct the appropriate command to run using the scheduling system on your cluster. A SLURM example is provided below:
> mkdir build_scorpio
> cd build_scorpio
> CC=mpicc CXX=mpicxx FC=mpifort cmake \
-DNetCDF_PATH=/path/to/netcdf \
-DPnetCDF_PATH=/path/to/pnetcdf \
-DMPIEXEC=/path/submission/scipt \
-DMPIEXEC_MAX_NUMPROCS=8 -DMPIEXEC_NUMPROC_FLAG=-n \
-DPIO_FILESYSTEM_HINTS=gpfs -DPIO_ENABLE_TIMING=OFF -DPIO_ENABLE_TESTS=ON \
-DCMAKE_INSTALL_PREFIX=/scorpio/install/path ../scorpio# 1) <this_script> -n N prog
# runs N copies of executable "prog" in parallel. The script must hide all
# of the system specific details, such as going through a queueing system
# and/or calling a system specific mpirun script with modified arguments.
#
# 2) The output of the application must arrive at the calling shell via
# stdout and stderr.
if [ "$1" != "-n" ]
then
echo "Usage: mpirun -n # prog"
exit 1
fi
num_procs=$2
shift 2
prog=$*
echo "srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog"
srun --mpi=pmi2 --partition=my_partition --nodes=1 --ntasks=${num_procs} --cpus-per-task=1 --time=00:10:00 --exclusive --export=ALL $prog
- Compile, test, and install:> make -j 6
> make -j 6 tests
> ctests
> make install