1 of 27

CCPP History

Cheryl Craig, Courtney Peverley,�Dustin Swales, Dom Heinzeller

May 2026

2 of 27

Before CCPP, there was IPD

Interoperable Physics Driver written by P. Tripp (EMC) and R. Benson (GFDL) for the NGGPS “dycore” bake off.

IPD refactored old GCM physics drivers and made GFS physics accessible to others: interoperable physics!

COORD_X: 00010101

TIMESTAMP: PRE-EPOCH

FV3

MPAS

GCM

NEPTUNE

NIM

NMMUJ

FV3

3 of 27

Gaps in IPD interoperability

IPD did not increase flexibility for adding or reorganizing physical parameterizations.

IPD drivers were maintained by hand, 10k+ lines long.

No information (metadata) on variables needed to run a parameterization: Which quantity exactly? What units?

CCPP: improve interoperability through metadata and auto-generated interfaces based on suite definition.

COORD_X: 00010101

TIMESTAMP: PRE-EPOCH

4 of 27

ccpp-prebuild v0: dynamic loading

Suite definition file

All schemes compiled�into dynamic library

Open libexmaple.so

Load and run scheme test

BUILD

RUN

2017

Original design: Tim Brown (NOAA/CIRES), Dave Gill (MMM)

5 of 27

ccpp-prebuild metadata in code

CCPP hooks + doxygen

metadata + doxygen

looong lines and many rows

6 of 27

ccpp-scm: physics R&D + CCPP sandbox

COORD_X: 00010101

TIMESTAMP: PRE-EPOCH

2017

7 of 27

Early adoption in FV3GFS, NEPTUNE

NEPTUNE: Dom sat down with Alex Reinecke (NRL) for half a day to implement a dynamic CCPP “helloworld” suite. No visibility of code (restricted access).�Alex and his team took it from there.

FV3GFS: Incremental approach termed “hybrid CCPP”. Schemes were one by one called from CCPP instead of IPD (no CCPP group/suite caps - needed dynamic CCPP).

COORD_X: 00010101

TIMESTAMP: PRE-EPOCH

2018-ish

8 of 27

Issues with dynamic loading

��

  1. Developers and debugging tools can’t see final code
  2. Data is retrieved from memory by location (symbol)
  3. IPD used blocked data structures for performance;�all N blocks were combined for init/final phases.
  4. CCPP couldn’t do this, thus had to run init N times
  5. This and dynamic loading made it SLOOOOOOOW

Host code�(Fortran)

CCPP API�(C)

Scheme code�(Fortran)

9 of 27

ccpp-prebuild v3: static caps

ccpp-prebuild v3 was the first real “code generator”; it generated Fortran caps for groups and suites. This was only possible after a full adoption of CCPP in the UFS.

Side plot: the UFS-CCPP�acceptance drama (aka�bit-for-bit challenge)

2019

10 of 27

Metadata updates

Unwieldy metadata tables in Fortran code were replaced with accompanying metadata files. The metadata parser used by ccpp-prebuild was retired in favor of the new capgen metadata parser (see later in this talk).

2019

11 of 27

ccpp-prebuild static: pros & cons

  1. Static build alleviated all issues identified�with dynamic CCPP, ran faster, used less memory
  2. Enabled optional arguments, debugging features (allocation and size checks), and unit conversions
  3. No runtime flexibility: suites defined at build�time. Addressed by building caps for multiple suites

Static ccpp-prebuild v4 replaced IPD in the UFS in 2020

12 of 27

ccpp-prebuild v4-v7 features 1/2

optional argument

allocation/size check

unit conversion

13 of 27

ccpp-prebuild v4-v7 features 2/2

Subcycling of schemes to call at�higher frequency, do iterations.

�Replaced blocked data structures�(IPD-style) with chunked arrays.

foo%bar(1:ncolums)

foo(1:nblocks)

foo(1:nblocks)%� bar(1:blocksize)

vs

14 of 27

ccpp-prebuild releases, operations

Release

Date

v1

Mar 2018

v3

Jun 2019

v4

Mar 2020

v5

Mar 2021

v6

Aug 2022

v7

Sep 2024

final

Apr 2026

Operations (model)

Date

HAFS v1+

2023

GEFS-Aerosols v12.3+

2023

AQM (2 implement.)

2024

NEPTUNE v1.6

2025-2026

Planned: GFS v17, GEFS v13, GCAFS, SFS, RRFS (2026-2027)

CCPP v6 published in GMD and BAMS!

15 of 27

Capgen motivation

Prebuild has some limitations…

  • Hard to extend
  • No mechanism for handling tracers/constituents, presenting challenges for physics-to-chemistry coupling
  • Host model needs to allocate interstitial physics variables, which is burdensome for development
  • Limited error checking
  • Unwieldy in-line metadata (discussed in prior slide), addressed by moving to capgen’s metadata parser

Capgen is a “clean sheet” design to address these limitations.

16 of 27

capgen features

17 of 27

Fortran parser

In prebuild, only the metadata files are parsed. There is no mechanism to ensure that the fortran arguments match what is in the metadata. Bad! ��Capgen parses the fortran files and compares it to the metadata for consistency.

This is done at build-time, catching potential run-time errors sooner.

Fortran/metadata checking can also be performed independently (for example, as part of a Github action)

18 of 27

Facilitate Scheme Portability

Prebuild has support for unit-conversions, allowing for the host and schemes to maintain their own unit conventions.

Capgen extends this approach to do a range of “variable transformations”

  • Unit conversions (e.g., m -> microns)
  • Type conversions (e.g., R4 -> R8)
  • Vertical reordering (e.g., top-down -> bottom-up)
  • Re-indexing (e.g., [i,k]->[k,i]) *Not yet implemented

19 of 27

Introduce “Suite variables”

Some schemes require fields output from other schemes.

In prebuild, these needed to be allocated by the host (e.g., CCPP_typedefs in UFS).

In capgen, there is no need to do this. Instead, capgen will define these fields as module variables within the suite cap.

This greatly reduces the overhead in the host.

20 of 27

Introduce “register” phase

In addition to the “init”, “timestep_init”, “run”, and “timestep_final” phases that exist in prebuild, capgen introduces a new register phase. This phase is to be (optionally) be called before “init”.

  • This allows physics schemes to set variables before the host model grid is initialized

21 of 27

Add built-in constituents handling

The constituents/tracer object is known to and handled by the framework, allowing schemes to:

  • Request the full object or individual tracer(s) via metadata (build-time)
  • Register tracer(s) at run-time during the register phase
  • Update the tracer tendencies via a identically-indexed tendency array
  • Get important metadata for tracers (molar mass, diagnostic name)

without any intervention needed by the host model (meaning that schemes that use the constituent object are portable to other CCPP-enabled host models)

22 of 27

CCPP Timeline

2017

2026

2019

2021

2023

2025

v0 dynamic

v3 static

v6

capgen

prebuild

NEPTUNE v1.6

v7

v4

v5

development begins

constituents added

testing revamped

CAM4 physics

in CAM-SIMA

HAFS v1

HAFS v2/v2.1

GEFS-Aerosols v12.3

23 of 27

capgen challenges

24 of 27

Challenges with Capgen…

Capgen is currently

  • Vastly more powerful than prebuild, but it is an extremely complicated code base that is close to its limits of its extensibility. This is prior to meeting�all of NOAA/NRL’s operational needs.�
  • Much slower than prebuild. Tests in the SCM are ~20x slower when writing the suite caps for all of NOAA operational SDFs.

25 of 27

Challenges with Capgen…

Capgen was

  • Not designed with the same operational considerations as prebuild (e.g., Performance and NCO requirements)

  • A great deal of time was spent trying to overcome these challenges, ultimately requiring a refactoring of capgen, yielding a more complicated codebase. Issues remain.

26 of 27

Challenges with Capgen…

Capgen has been under development for ~7 years!

  • Primary developer of Capgen left NCAR 3(?) years ago.�
  • We continued to engage, develop, and push forward�with Capgen development, but recently we lost this collaboration with the primary developer.

27 of 27

Considerations going forward

How can we best leverage the pros of both the capgen and prebuild designs?

As we look towards capgen version 2.0 (?), what do we want to simplify and/or clean up? What features can be removed?

How can we best improve on capgen while minimizing impacts to participant host models?