Installation
Prerequisites
Compilers
Cocoa requires a C++20 compatible compiler. The minimum versions are dictated by Kokkos 5.0 (included with Trilinos 17), which sets stricter requirements than C++20 alone.
Compiler |
Minimum Version |
Notes |
|---|---|---|
GCC |
11.1.0 |
Recommended for CPU and as CUDA host compiler. The first release
whose standard library parses floating-point numbers with
|
Clang (CPU) |
14.0.0 |
For CPU-only builds, with libstdc++ from GCC 11 or newer |
Clang (CUDA host) |
15.0.0 |
When used as nvcc host compiler |
NVIDIA nvcc |
12.2 |
Requires CUDA Toolkit 12.2+ |
Intel icpx (CPU) |
2022.0.0 |
Intel oneAPI DPC++/C++ Compiler |
Intel icpx (SYCL) |
2024.2.1 |
For SYCL backend builds |
ROCm (HIPCC) |
6.2.0 |
For AMD GPU builds |
NVIDIA HPC SDK (NVC++) |
22.3 |
Alternative to nvcc for NVIDIA GPUs |
Note
See the Kokkos Requirements documentation for the most up-to-date information.
Build System
CMake 3.23 or later
GNU Make or Ninja build system
Required Libraries
Install these before configuring:
Trilinos 17.0 or later (with Kokkos, KokkosKernels, Tpetra, Belos, Ifpack2, Zoltan2, Intrepid2 and Shards enabled)
NetCDF-C (4.9.3+ recommended; for mesh and output I/O)
HDF5 (development headers required; installed automatically as a NetCDF-C dependency)
Warning
NetCDF-C versions prior to 4.9.3 have a bug (#2674) that causes spurious HDF5 error messages on stderr when reading variables. Ubuntu 24.04 ships NetCDF-C 4.9.2; if using that distribution, build NetCDF-C 4.9.3+ from source.
ParMETIS (for mesh partitioning, required via Zoltan2 for MPI builds)
Note
Trilinos 17.0+ is required because it ships Kokkos 5.0+, whose APIs Cocoa depends on.
Automatically Fetched Dependencies
CMake configuration downloads and builds these through CPM:
yaml-cpp (configuration file parsing)
valijson (configuration schema validation)
CLI11 (command-line parsing)
spdlog (logging)
fmt (string formatting)
Catch2 (unit testing, with
BUILD_TESTING)Google Benchmark (with
cocoa_ENABLE_BENCHMARKS)
Optional Dependencies
CUDA Toolkit (for NVIDIA GPUs; required by a Trilinos CUDA build)
ROCm (for AMD GPUs; required by a Trilinos HIP build)
MPI (for distributed runs, if Trilinos was built with MPI)
Building from Source
Clone the Repository
git clone https://github.com/zcobell/cocoa.git
cd cocoa
Configure with a Preset
CMakePresets.json at the repository root holds the configurations CI
builds plus two developer ones. Presets locate Trilinos and NetCDF through the TRILINOS_DIR and
NETCDF_DIR environment variables; export them once for your machine:
export TRILINOS_DIR=/path/to/trilinos/lib/cmake/Trilinos
export NETCDF_DIR=/path/to/netcdf-c
cmake --preset release
cmake --build --preset release
ctest --preset release
cmake --list-presets lists them; cmake --build --list-presets and
ctest --list-presets do the same for the build and test presets of the
same names.
Preset |
Purpose |
|---|---|
|
Optimized build, for running the model. |
|
Debug build with the unit tests. |
|
Release build with |
|
What the serial CI job configures, GRIB included. |
|
The CUDA compile check. Its |
|
Compile database for the clang-tidy gate; configures into
|
|
The instrumented build behind the coverage job. |
Every preset but ci-tidy configures into build/, so switching between
them reconfigures that one tree rather than creating a second one. Pass -B
to put a preset somewhere else.
A -D on the command line overrides the preset, so
cmake --preset release -Dcocoa_ENABLE_GRIB=ON is enough for a one-off change.
For a permanent one, put a CMakeUserPresets.json beside CMakePresets.json
(it is untracked) and inherit:
{
"version": 4,
"configurePresets": [
{
"name": "my-release",
"inherits": "release",
"cacheVariables": {
"Trilinos_DIR": "/home/me/trilinos/lib64/cmake/Trilinos",
"NETCDF_DIR": "/home/me/spack/opt/spack/netcdf-c-4.9.3"
}
}
]
}
Configure with CMake
Every option below can also be passed without a preset. A basic build:
mkdir build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DNETCDF_DIR=/path/to/netcdf-c \
-DTrilinos_DIR=/path/to/trilinos/lib/cmake/Trilinos
CMake Options
Option |
Description |
Default |
|---|---|---|
|
Hint path for CMake’s |
(auto-detected; required if not in system paths) |
|
Path to the Trilinos CMake config directory (e.g.,
|
(auto-detected; required if not in system paths) |
|
Combined execution space and MPI configuration. Available options
depend on the Trilinos build. Examples: |
|
|
Build type. Options: |
|
|
Installation directory for |
|
|
Build the unit test suite (requires Catch2, fetched automatically). |
|
|
Enable strict compiler warnings, sanitizers, cppcheck, and hardening. Must be requested explicitly; developer builds and CI pass it. |
|
|
CUDA memory space. |
|
|
Use |
|
|
Enable GRIB2 meteorological forcing (GFS, HRRR, …). Requires an
installed ECMWF ecCodes (found via |
|
|
Path to the ecCodes CMake config directory (e.g.,
|
(auto-detected) |
|
Prefix each screen log line with the wall-clock date and time. |
|
|
Add the end-to-end integration tests to |
|
|
Build the benchmark executables (fetches Google Benchmark). |
|
|
Maximum concurrent link steps under Ninja; bounds peak memory when
many test binaries link at once. The CI presets set it to |
(empty: no limit) |
Floating-Point Precision
Cocoa computes in double precision (FP64). There is no build-time precision option: to reduce GPU memory traffic, a fixed set of bandwidth-sensitive fields is stored as float and promoted to double on read, while all arithmetic stays in double. See Numerical Methods for the list of mixed-precision fields and the rationale.
Stream Compaction
Each step, the wet/dry solver rebuilds compacted lists of the currently wet
elements and nodes, a stream compaction (copy_if over an index range).
The backend picks the implementation:
CUDA:
cub::DeviceSelect::Ifon the Kokkos execution-space stream, with the algorithm’s temporary storage allocated once at setup and reused every step (no per-stepcudaMalloc/cudaFree). CUB ships with the CUDA Toolkit, so no extra setup is needed.OpenMP or Serial with
cocoa_USE_THRUST=ON:thrust::copy_ifthrough the matching thrust host device system.Otherwise: a fused Kokkos
parallel_scan.
All implementations use the same selection predicate and produce identical results.
Enabling cocoa_USE_THRUST requires a
Thrust installation, typically via
NVIDIA CCCL, with CMake pointed at it:
cmake .. \
-Dcocoa_BACKEND=OPENMP+MPI \
-Dcocoa_USE_THRUST=ON \
-DCCCL_DIR=/path/to/cccl/lib/cmake/cccl
# or, for a standalone Thrust:
# -DThrust_DIR=/path/to/thrust/lib/cmake/thrust
If cocoa_USE_THRUST=ON is requested but no Thrust/CCCL installation is
found, or the backend is neither OpenMP nor Serial (and not CUDA, where the
option is ignored), configuration fails with an explanatory error.
Compile
cmake --build --preset release # or, from the build directory, make -j$(nproc)
Install
cmake --install build
Python Tools
Mesh conversion, baroclinic forcing preparation and plotting use the
cocoa-tools Python package (Python 3.10 or newer), which installs the
cocoa-mesh-tools, cocoa-ocean3d and cocoa-plot commands and their
dependencies:
pip install utils/cocoa_tools
Use the package from the same release or checkout as the model. See Cocoa Tools (Python).
Verifying the Installation
Run the test suite:
ctest --preset release # or, from the build directory, ctest --output-on-failure
The test presets exclude the validation label, which covers the channel
studies that compare against analytic solutions rather than committed
references. Run those with ctest -L validation.