xDSL-CCPP: An alternative code generator for atmospheric modelling
Analyze & explore related research in Conceptio
Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.
xDSL-CCPP: An alternative code generator for atmospheric modelling Nick Brown1[0000−0003−2925−7275] and John Dennis2[0000−0002−2119−8242] 1
arXiv:2611.08060v1 [cs.DC] 5 Nov 2026
2
EPCC at the University of Edinburgh, Edinburgh, UK National Center for Atmospheric Research (NCAR), Boulder, USA
Abstract. The Common Community Physics Package (CCPP) is a framework designed to simplify the exchange of physics packages between state-of-the-art atmospheric models. A core software component of CCPP is a code generator: a bespoke Python-based application that uses regular expressions to transform an input specification into Fortran source code. While the code generator initially provided a simple transformation capability, the demands of state-of-the-art atmospheric models have resulted in significant increases in its complexity. Furthermore, ongoing code modernisation efforts to enable GPU-based computing have placed additional demands on the code generator for which it was never designed. Domain Specific Languages (DSLs) have proven to be highly effective in High Performance Computing (HPC), offering the ability to simplify code modernisation efforts. However, traditionally the effort and specialist skills required in the development of a DSL have been a blocker to adoption. In recent years, however, there have been great advances in compiler technologies, and frameworks such as MLIR and xDSL have the potential to greatly lower this barrier to entry. In this paper, we present xDSL-CCPP, a new application-specific code generator based upon the latest MLIR and xDSL compiler technologies, for CCPP. Demonstrating a reduction in bespoke tooling code of around three times, from approximately 15,000 LoC to 5,000 LoC, we highlight the opportunities provided by these compiler frameworks and demonstrate how they significantly lower the barrier to development of HPC application-specific DSLs whilst maintaining application performance and promoting flexibility. Keywords: MLIR, xDSL, Common Community Physics Package, Domain Specific Language (DSL)
1
Introduction
The scientific computing community supports many large scientific code bases that must efficiently utilize modern High Performance Computing (HPC) computers. Frequently, these large scientific code bases contain the contributions of a large number of domain scientists and represent 10 to 100 years of development effort. The rapid advancement of HPC computing architectures typically means that these large scientific code bases are constantly being modernised. In addition
2
N. Brown and J. Dennis
to the need to evolve for every change computer architecture, these codes are frequently focused on adapting how the end-user will interact with the reworked code. The Common Community Physics Package (CCPP) is one example of this, where the code has recently been modernised to simplify the exchange of physics packages between different climate and weather models. Once a particular physics package has adopted the CCPP interface, it can be easily used by different CCPPenabled models. However, flexibility of use comes at a cost. Specifically, it is based on a bespoke code generator (capgen) that automatically generates the Fortran interface code. Furthermore, additional files that describe the transformation process and the source code must be maintained. Effectively, the CCPP is a Domain Specific Language (DSL) in all but name. DSLs have proven to be highly effective; however, arguably, there are two major disadvantages to them that put people off. The first is the word language, which implies that users must learn a new way of expressing their computation and/or configuration which is specific to the application in question. The second is the overhead in developing and maintaining bespoke compiler infrastructure to translate from the DSL to source code. Indeed, CCPP suffers from both of these issues, where configuration is undertaken by XML and metadata files that have grown unwieldy and the underlying Python-based tooling has become complex and difficult to maintain. In this paper, we describe the development of xDSL-CCPP, which is a DSL for configuring the CCPP framework. Leveraging xDSL, a Python-based compiler framework that follows MLIR-based industry standard abstractions and concepts, we demonstrate that this not only significantly simplifies code generation tooling, but furthermore provides a range of additional opportunities, including embedding the DSL within an existing language that users are already familiar with. This paper is structured as follows: In Section 2 we explore the background to this work, highlighting the role of CCPP and current code generation approaches along with the MLIR and xDSL compiler technologies. Section 3 then describes our xDSL-CCPP tool, which provides a compiler flow for CCPP code generation, along with exploring how this addresses limitations with the current bespoke approach. Section 4 then compares the code complexity, compile time, and resulting runtime of our approach against the existing approach. Lastly, Section 5 draws conclusions and discusses further work.
2
Background
The Common Community Physics Package (CCPP) is a collaborative, open-source framework jointly developed by the National Center for Atmospheric Research (NCAR), the National Oceanic and Atmospheric Administration (NOAA), and additional collaborators via the Developmental Testbed Center (DTC). Modelling atmospheric physics within weather, climate, and Earth systems applications, CCPP is especially popular for exploring the integration, evaluation, and dissemination of physical parameterisations among research and operational entities [1].
xDSL-CCPP: An alternative code generator for atmospheric modelling
3
There are two main components to CCPP: the first is the physics, which comprises the modelling of physical processes including radiation, convection, microphysics (water interaction), and land-surface interaction. Secondly, the framework serves as the foundational software architecture which connects different physics modules together and is the structure that enables users to leverage CCPP as a toolkit. The framework is designed to enable a pick and mix approach to different configurations, where from one run to the next the set of enabled modules and their order can vary dramatically. Several groups interact with CCPP, and we use the following terms in this paper. Scheme developers are domain scientists who write and maintain individual physics schemes in Fortran, together with their metadata. Suite integrators, whom we refer to as users, assemble existing schemes into suites for a particular model configuration or experiment. These people write the suite configuration but do not modify scheme internals or the code generator. Host model developers write the driver code of the atmospheric model that calls the generated interfaces. Lastly, tool maintainers develop and maintain the code generator itself.
Fig. 1. Sketch of CCPP’s existing code generation tool flow
CCPP is currently in its sixth version, and has recently been extensively rewritten to adopt modern Fortran standards. The code follows a modular approach, where each physical process is represented as an independent scheme. One run to the next often comprises a different range of physical schemes run in different orders, and consequently a code generation approach based upon configuration files has been developed. Suite integrators provide an XML suite, illustrated in Listing 1.1, along with metadata about the schemes and host (driver) Fortran code, sketched in Listing 1.2. The tool flow is illustrated in Figure 1, where XML and metadata files are provided as inputs to the CCPP code generation tool. This tool starts by validating and then parsing the input configuration files, before internally generating the required API calls and matching them to variables across schemes, with Fortran 90 source code files generated as output. This generation tool is written in Python, with the input configuration being a mixture of XML that describes the suite(s) of physics schemes to run, and
4
N. Brown and J. Dennis
key-value pair files for metadata that describe each global variable and procedure along with each of its arguments. <suite name="hello_world_suite" version="1.0"> <group name="physics"> <scheme>hello_scheme</scheme> <scheme>temp_adjust</scheme> </group> </suite> Listing 1.1. Suite XML configuration
The hello_world_suite of Listing 1.1 is deliberately minimal for presentation and, in practice, a suite such as those used in Section 4 orders tens of schemes. These cover radiation, boundary-layer turbulence, convection and cloud microphysics, and some schemes, typically microphysics, are sub-cycled several times within each physics timestep. Integrators frequently require variants of a suite that differ only in a single scheme or a tunable parameter, and the same scheme is reused across multiple host models. This is why scheme interfaces are described by host-independent metadata. This code generation approach started as a fairly small Python script, but has grown significantly to support an increasing level of configuration complexity. There is a lot of boilerplate metadata for each Fortran source file, some of which can be mechanically generated while other components must be written by hand. An example is provided in Listing 1.2, which sketches the metadata of the hello_scheme_init procedure, which is part of the hello_scheme scheme, and the file contains key-value pairs describing the signature of the procedure. Not only is such a manual metadata approach potentially error-prone, but furthermore the fixed nature of these files means that it is not currently possible to specialise them at configuration time, which results in duplicate schemes with only very minor differences. [ccpp-table-properties] name = hello_scheme type = scheme [ccpp-arg-table] name = hello_scheme_init type = scheme [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP units = none dimensions = () type = character kind = len=512 intent = out [ errflg ] standard_name = ccpp_error_code long_name = Error flag for error handling in CCPP units = 1
xDSL-CCPP: An alternative code generator for atmospheric modelling
5
dimensions = () type = integer intent = out Listing 1.2. Extract of suite metadata for hello_scheme’s hello_scheme_init procedure
The underlying issue is that the parsing and code generation framework has grown significantly in complexity to over 15000 lines of code and become brittle. There are numerous assumptions hardcoded into this current set of scripts, meaning that it is risky to add new functionality. Furthermore, it would be a significant amount of work to adopt an alternative user interface, for instance replacing the current XML and metadata with Python, although that is potentially desirable as it would provide more flexibility, especially around better representing certain constructs such as loops. 2.1
MLIR and xDSL
LLVM [9] is a collection of reusable compiler and toolchain components for building compilers for many source languages and deploying to a wide variety of targets. It offers multiple language frontends and many architecture-specific backends, with LLVM-IR acting as the common interface between them. As a result, a frontend such as Clang (for C and C++) can emit LLVM-IR and immediately gain access to any supported backend, including those for CPUs, GPUs, and FPGAs. A drawback of this design is that LLVM-IR is relatively low-level, so frontends must implement substantial lowering logic themselves, often leading to duplicated effort across different frontends. MLIR, originally developed at Google and later released as open source, addresses this by introducing a hierarchy of intermediate representations called dialects together with reusable transformations between them. Rather than requiring frontends to target LLVM-IR directly, MLIR allows them to emit higher-level IR and then apply shared lowering and optimisation passes to progressively reduce abstraction until reaching LLVM-level code generation. Intermediate Representation (IR) is manipulated through a series of transformation passes, lowered from one to the next, ultimately resulting in IR that can be consumed by a backend such as LLVM. IR follows a standard form known as Static Single Assignment (SSA), and a key feature is that multiple dialects can coexist within the same IR module and be transformed independently, supporting staged lowering toward the LLVM dialect and ultimately to LLVM-IR. This structure encourages reuse of compiler infrastructure across frontends, reducing the engineering cost of developing new compilers, while also providing extension mechanisms for defining custom dialects and passes. Since becoming an LLVM sub-project, MLIR has gained significant adoption and an active development community. The project ships a broad set of standard dialects, including arith for arithmetic operations, scf for structured (serial and parallel) control flow, affine for affine loop representations, memref for memory and data access, func for functions and calls, openmp for OpenMP constructs, linalg for linear algebra operations, and vector for vectorisation. These dialects
6
N. Brown and J. Dennis
can be lowered to the llvm MLIR dialect, from which LLVM-IR is typically produced using the mlir-translate tool. A practical difficulty with MLIR is its substantial learning and development overhead: effective use commonly requires C++ expertise, familiarity with LLVM’s design principles, use of TableGen [8] to specify dialect interfaces, and continuing maintenance effort in response to a rapidly evolving codebase. In contrast, xDSL [12] is a Python-based compiler toolkit that is designed to be compatible with MLIR at a one-to-one level. It re-implements most standard MLIR dialects and also includes additional experimental dialects, with dialect definitions expressed using IRDL [6] as Python classes. xDSL is intended to support fast iteration and prototyping of MLIR-like ideas, which can later be upstreamed into MLIR once they mature; the MPI dialect provides an example, having been developed first in xDSL [2] before subsequent standardisation in MLIR. Because of this close compatibility, it is possible to move between xDSL and MLIR during a compilation workflow. In this work, we employ xDSL to implement the transformations and optimisations presented in the paper. A major purpose of xDSL has been to lower the barrier to developing DSL compilers by promoting the sharing of infrastructure and avoiding siloing of the underlying compiler stack. This was demonstrated in [2] where the compilers of Devito and PSyclone DSLs were integrated into xDSL. Whilst these two DSLs are very different, the former is Python-based for seismology simulation and the latter Fortran-based used by the weather and climate community, there was around a 95% reduction in compiler code size for PSyclone [2] resulting from this integration. There have been several other successes in using xDSL, for instance stencils running on the Cerebras [11] and an OpenMP flow for FPGAs [10] and AMD AIEs [4]; however, until this work it has not yet been used as infrastructure for replacing existing configuration tooling and supporting the formalisation of configuration via DSLs. However, the key benefits around sharing of infrastructure to lower the overhead required for individual DSLs can also apply here.
3
xDSL-CCPP: An xDSL-based code generation framework
Figure 2 illustrates the compiler flow of our approach, which leverages xDSL. We developed a bespoke dialect, ccpp, which represents the Intermediate Representation (IR) level description of suite(s) and metadata. The user’s XML configuration and metadata files are consumed by a Python-based frontend which parses the XML using the standard Python library and the key-value pairs in the metadata to generate IR containing this ccpp dialect. This is illustrated in Listing 1.3 where ccpp.suite defines the suite, hello_world_suite, which contains two schemes hello_scheme and temp_adjust. The ccpp.table_properties operation contains metadata for each scheme, hello_scheme in Listing 1.3. This comprises the signature of each procedure, and Listing 1.3 includes the definition of the hello_scheme_init procedure, which has two arguments errmsg and errflg.
xDSL-CCPP: An alternative code generator for atmospheric modelling
7
Fig. 2. Illustration of our xDSL-CCPP compiler flow, accepting either XML and metadata files or Python code, and generating either Fortran source code or LLVM-IR which can be provided to Clang
"ccpp.suite"() <{suite_name = "hello_world_suite", version = "1.0"}> ({ "ccpp.group"() <{group_name = "physics"}> ({ "ccpp.scheme"() <{scheme_name = "hello_scheme"}> : () -> () "ccpp.scheme"() <{scheme_name = "temp_adjust"}> : () -> () }) : () -> () }) : () -> () "ccpp.table_properties"() <{name = "hello_scheme", type = #ccpp<table_type_kind scheme>}> ({ "ccpp.arg_table"() <{name = "hello_scheme_init", type = #ccpp<table_type_kind scheme>}> ({ "ccpp.arg"() <{name = "errmsg", type = "character", standard_name = "ccpp_error_message ", long_name = "Error message for error handling in CCPP", kind = "len=512", intent = "out", units = "none"}> : () -> () "ccpp.arg"() <{name = "errflg", type = "integer", standard_name = "ccpp_error_code", long_name = "Error flag for error handling in CCPP", intent = "out", units = "1"}> : () -> () }) : () -> () }) : () -> ()
Listing 1.3. Sketch of IR with CCPP suite and meta description
The IR generated by the frontend is then consumed by our xDSL compiler pipeline where it is manipulated via a series of transformations developed in this work. The first of these transformations, generate_meta, interrogates the metadata within the IR and generates corresponding function signature definitions. This is required because subsequent pipeline stages insert operations that issue calls to these functions, and so the IR must contain the signature of these functions for error checking. Whilst the Flang Fortran compiler is built upon MLIR, its own dialects fir and hlfir are extensive and fairly low-level, not necessarily representing higher-level Fortran constructs. Consequently, we have developed our own ftn dialect, which contains the Fortran-specific types and operations required which includes the definition of kinds, string comparison and string assignment. The next transformation, generate_meta_kinds also operates on the ccpp dialect metadata held within the IR, and identifies any required Fortran kinds. These are specifically included for real number representation, such as the type real(kind=k), and the corresponding kind attribute and definition operation from the ftn dialect are inserted into the IR.
8
N. Brown and J. Dennis
At this point, the IR contains enough information upon which code-level IR constructs can be generated. Upstream MLIR contains a wide range of core dialects that describe code level aspects such as control flow (scf ), memory allocation and access (memref ) and functions (func). Consequently, the next transformation, generate_suites, consumes the suite description held in the IR by the ccpp dialect, and generates code level IR containing the core MLIR dialects. The constituent functions for suite initialisation, finalisation, and execution are generated, and Listing 1.4 sketches the hello_world_suite_initialize function that has been generated from the suite and metadata of Listing 1.3. This function accepts no arguments and produces two outputs which are memory references to data (an array). The memref.alloc operations at the start of the function allocate these arrays, and the value of 0 is then written into errflg to denote no initial error. It can be seen from Listing 1.4 that the generated initialisation function then calls into individual scheme initialisations if errflg equals zero, with these scheme functions also returning an errflg and errmsg which are copied into this function’s memrefs using the memref.copy operation. Lastly, errflg and errmsg are returned via the func.return operation to the caller. Other suite functions follow a similar structure, albeit more complex, to the initialisation sketched in Listing 1.4. func.func public @hello_world_suite_initialize() -> (memref<512xi8>, memref<i32>) { %errmsg = "memref.alloc"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<512 xi8> %errflg = "memref.alloc"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<i32> %0 = arith.constant 0 : i32 memref.store %0, %errflg[] : memref<i32> %10 = arith.constant 0 : i32 %11 = memref.load %errflg[] : memref<i32> %12 = arith.cmpi eq, %11, %10 : i32 scf.if %12 { %13, %14 = func.call @hello_scheme_init() : () -> (memref<512xi8>, memref<i32>) "memref.copy"(%13, %errmsg) : (memref<512xi8>, memref<512xi8>) -> () "memref.copy"(%14, %errflg) : (memref<i32>, memref<i32>) -> () } %15 = arith.constant 0 : i32 %16 = memref.load %errflg[] : memref<i32> %17 = arith.cmpi eq, %16, %15 : i32 scf.if %17 { %18, %19 = func.call @temp_adjust_init() : () -> (memref<512xi8>, memref<i32>) "memref.copy"(%18, %errmsg) : (memref<512xi8>, memref<512xi8>) -> () "memref.copy"(%19, %errflg) : (memref<i32>, memref<i32>) -> () } func.return %errmsg, %errflg : memref<512xi8>, memref<i32> }
Listing 1.4. Sketch of generated hello_world_suite_initialize subroutine which calls individual scheme initialisation
The next transformation, generate_host, generates IR that will be called by the overarching driver code for the entire application initialisation, finalisation and execution. This code calls into the corresponding suite functions as required, and marshals control between them. The strip_ccpp transformation now removes
xDSL-CCPP: An alternative code generator for atmospheric modelling
9
CCPP-specific configuration and metadata from the IR, with the IR now only containing code-level operations which closely represent the execution level. At this point we have one of two options in the compilation flow: either generating Fortran code directly from the IR and providing this as an input to any compiler, or passing the IR directly into LLVM via Clang and compiling to object files. The first of these is how the current framework operates and as such we developed a Fortran backend which consumes the IR and generates Fortran 90conforming code based upon this. A mapping is provided between each operation, such as the subroutine definition based upon the func.func (function definition) operation or a loop construct from scf.for. Expressions are also mapped to their Fortran equivalents, which tends to be a straightforward conversion. Fortranspecific constructs are represented by operations in our bespoke ftn dialect, such as string equality and kind definition, and this simplifies code generation as there is a one-to-one mapping here. Alternatively, the IR can be provided to LLVM via Clang to produce an object file which is then linked against the rest of the code. Whilst this avoids the need to generate Fortran code and leverage a separate compiler, it does tie the entire flow into LLVM, as object files from other parts of the code must be compatible with the object files generated here. The ftn_dialect_to_core transformation lowers constructs in our ftn dialect into core MLIR/LLVM dialects so that the IR can be consumed by LLVM. 3.1
Removing the need for manual metadata files
One of the major limitations with the current CCPP code generation approach is that scheme developers must manually maintain metadata key-value pair files similar to that sketched in Listing 1.2. While CCPP provides the capability to generate several of these fields mechanically, additional fields must be added and maintained by hand. Not only is this time consuming and error-prone, but it also imposes a maintenance burden where metadata and source files must remain up to date with respect to each other. As xDSL is one-to-one compatible with MLIR, it is possible to leverage the large ecosystem that has grown up around MLIR to help address this. In 2020, the Flang Fortran compiler [7] was rewritten from the ground up to support modern Fortran standards and built upon MLIR. To this end, we can leverage Flang as part of our compiler pipeline to automatically generate this metadata and avoid manually written metadata files. We developed a new transformation, fir_to_meta, which consumes the IR generated by Flang and deduces the metadata based upon the details encoded within. Even though Fortran sits outside the core MLIR ecosystem, xDSL provides both hlfir and fir dialects, so our transformation, fir_to_meta, interrogates each IR generated by Flang from Fortran source code and from this generates the corresponding CCPP metadata IR. Consequently, by leveraging xDSL and MLIR, now only the suite XML configuration file(s) need to be provided to the configuration flow, as metadata can be automatically inferred by leveraging the wider MLIR ecosystem.
10
N. Brown and J. Dennis
3.2
A Python-based DSL
As illustrated in Figure 2 the CCPP dialect, generated by the XML Python frontend, is the front door into our compiler pipeline, which then contains the majority of the functionality. This thin transformation layer from the user’s interface to the CCPP IR currently operates upon XML and metadata files, the latter either written explicitly or inferred from the Fortran source code. However, the IR can be trivially generated from any frontend as long as it follows the expected format. This is illustrated by the Python frontend in Figure 2 and enables us to readily drive the configuration by alternative user interfaces. This addresses an important problem because a challenge currently faced is that suite integrators need to represent more complex structures in their suite configuration, such as loops, which do not necessarily map naturally to XML. Consequently, we developed a Python-based configuration frontend where scientists describe their flow in Python code, and the imported Python module interrogates this and generates the corresponding CCPP IR that is compatible with the rest of the pipeline. 1 from xdsl_ccpp.frontend.py_api import Arg, ccpp_scheme, ccpp_suite 2 3 @ccpp_suite("hello_world_suite", version="1.0") 4 class hello_world: 5 physics = [hello_scheme, temp_adjust] 6 7 def run(): 8 physics() 9 10 @ccpp_scheme 11 class hello_scheme: 12 init = [errmsg, errflg] Listing 1.5. Sketch of suite definition using Python frontend
The Python representation of suite and scheme definitions from Listing 1.1 are illustrated in Listing 1.5. This frontend leverages the metadata inference approach described in Section 3.1, avoiding the need for this information to be provided by the programmer. Lines 3 to 8 in Listing 1.5 define the suite, and lines 10 to 12 the scheme. The suite definition of lines 3 to 8 groups each constituent scheme, in this case into the physics group, and the default is for each initialisation, execution and finalisation phase to call each group, and the schemes within a group, in the order that they are declared. However, it is also possible for the programmer to provide optional init, run and finalise methods that override this default. For instance, in the run method at lines 7 and 8 of Listing 1.5, and this is useful to support additional constructs and specialisation such as conditionals around scheme execution and loops. Python enables control flow to be represented more naturally than via XML files and also enables scheme parameterisation, where physics schemes are specialised at code generation time that currently requires duplicate schemes with
xDSL-CCPP: An alternative code generator for atmospheric modelling
11
the XML approach. This is illustrated in Listing 1.6, where the run function iterates over both schemes ten times and provides the loop counter to the scheme as well as all the other arguments. Furthermore, the arguments init_val=98, diagnostics=False to hello_scheme illustrate parameterisation of this scheme, where these arguments are set at compile time and enable convenient specialisation. 1 2 3 4 5 6 7 8 9 10 11 12
from xdsl_ccpp.frontend.py_api import ccpp_suite number_of_subcycles=10 @ccpp_suite("hello_world_suite", version="1.0") class hello_world: physics = [hello_scheme, temp_adjust] def run(): for i in range(0, number_of_subcycles): hello_scheme(i, init_val=98, diagnostics=False) temp_adjust(i) Listing 1.6. Sketch of more advanced suite definition in Python supporting loops and parameterisation of suites at compile time
One of the major advantages of the automation of metadata discovery and the Python frontend is that this helps address the language criticism of DSLs. Instead, we demonstrate that by leveraging xDSL and MLIR, one is able to significantly simplify the interface, in this case removing the need for manually written metadata files and embedding the suite configuration within Python that the users are already familiar with.
4
Results and evaluation
Table 1 reports a Lines of Code (LoC) comparison (ignoring code comments) between the existing CCPP code generation tool and our approach, xDSL-CCPP. Whilst lines of code is not an exact measure of code complexity, it still provides a measure of potential maintenance burden. It can be seen that our approach requires around three times fewer lines of code because it leverages xDSL, and indeed our xDSL-CCPP also includes the metadata discovery and Python-based frontend, which the existing approach does not provide.
Table 1. Lines of code comparison (ignoring code comments) between the existing CCPP code generation tool and our xDSL-CCPP approach Approach Lines of code Existing 15054 xDSL-CCPP 4859
12
N. Brown and J. Dennis
We now leverage three test cases to compare the existing configuration approach against our xDSL-CCPP framework. The advection test case simulates atmospheric advection, which is the movement of particles through the air, for 100,000 columns; the ddthost test case models simplified atmospheric physics parameterisations, providing a self-contained test of how host-provided state in Derived Data Types (DDT) drives physics computations, such as temperaturerelated adjustments, across 100,000 columns. Lastly, capgen focuses on thermodynamic and atmospheric state adjustment, also across 100,000 columns. In these test cases, the physics serves as a vehicle to exercise and test the underlying code generation and model integration features, such as how DDTs with temperature fields are represented, how dimensions affect allocations across slices of data, and the interaction between multiple suites and schemes. Averaged over three runs, Table 2 reports compile time for each of the three test cases on Cirrus, a Cray EX4000, comparing the existing code generation tool to xDSL-CCPP. It can be seen that our approach is slower than the existing tool, and the majority of this time is within the compilation pipeline, with the overhead being the generation of IR that is then marshalled between different transformations. However, the code generation time when using xDSL-CCPP is still less than a second. Table 2. Code generation time comparison between the existing tool and our xDSLCCPP Existing xDSL-CCPP compile time (s) compile time (s) advection 0.27 0.79 capgen 0.29 0.86 ddthost 0.28 0.84
Test case
Figure 3 reports single-core runtime performance of the three test cases on Cirrus, a CPU-based HPE Cray EX4000 with AMD Zen5 (Turin). Existing approach reports performance of the existing CCPP code generation tool and it can be seen that this is comparable to our xDSL-CCPP (Fortran) approach that is using the Fortran code generator flow and then compiled along with the rest of the Fortran source code. These two tests leverage GCC version 14.2, and as described in Section 3 an alternative approach is to instead lower directly to LLVM-IR which is then built by Clang, and Flang compiles the scheme Fortran source code. LLVM version 20.1.7 is used here, and it can be seen in Figure 3 that this is slightly slower than GCC v14.2. Consequently, the Fortran backend is the generally preferred approach for xDSL-CCPP, but having an LLVM-IR route provides additional future flexibility. Figure 4 reports the same performance comparison as in Figure 3, but this time on ARCHER2, which is a Cray EX and the UK national supercomputing service. ARCHER2 is a CPU-based HPC machine containing AMD Zen2 (Rome), whilst the relative performance between the approaches is unchanged, it can be
xDSL-CCPP: An alternative code generator for atmospheric modelling
13
Fig. 3. Single core runtime performance comparison across three test cases on Cirrus, which is an HPE Cray EX4000
observed that absolute runtime on ARCHER2 is much longer and this is due to Zen2 in ARCHER2 compared to Zen5 in Cirrus. Moreover, on ARCHER2 the advection testcase is slower than the other two, whilst on Cirrus it is faster. This is because this test case is the most computationally intensive, and AMD Zen2 only provides AVX2 (256 bits wide) whereas Zen5 provides AVX512 (512 bits wide), the latter being important for compute performance.
4.1
Single Column Model (SCM)
The test cases explored so far focus on correctness of realistic physics data flows and computations, rather than validating scientific accuracy. NCAR’s Single Column Model (SCM) is built upon CCPP and we integrated xDSL-CCPP into the build flow. We have compared our approach against the existing code generator across four SCM suites on Cirrus, all compiled with GCC v14.2 and using the xDSL-CCPP Fortran backend flow. The first suite is LASSO (Large eddy simulation ARM Symbiotic Simulation and Observation), modelling continental shallow convection based on input data from 2nd of October 2018. GABLS3 (GEWEX Atmospheric Boundary Layer Study) is used for the development of a nocturnal jet based on data from 1st of July 2006; BOMEX (Barbados Oceanographic and Meteorological EXperiment) simulates maritime shallow convection, and lastly COMBLE (Cold-Air Outbreaks in the Marine Boundary Layer Experiment) uses data from 12th of March 2020 to simulate mixed-phase clouds in the polar marine boundary layer region [5].
14
N. Brown and J. Dennis
Fig. 4. Single core runtime performance comparison across three test cases on ARCHER2 which is an HPE Cray EX
All runs simulate 1000 seconds, with a timestep of 0.1 seconds and reported results averaged over three runs. Figure 5 illustrates performance of these SCM suites when built with the existing code generation tool compared to xDSL-CCPP, and it can be seen that, for each of these suites, performance is comparable between the two approaches. This confirms that xDSL-CCPP can be swapped in without incurring runtime penalty. The runtime differences between the existing tool and xDSL-CCPP (Fortran) have a standard deviation of below 4% across three runs. This is expected, because both approaches generate functionally equivalent interface code and runtime is dominated by the physics schemes, which are unchanged. The purpose of these experiments was therefore to confirm that xDSL-CCPP introduces no runtime penalty, and its benefits lie in maintainability and usability rather than boosting performance.
5
Conclusions and further work
In this paper we have explored a new Domain Specific Language (DSL), xDSLCCPP, for configuring the execution of the Common Community Physics Package (CCPP). As HPC codes are modernised, a crucial question is how users can most appropriately drive them in a flexible manner, and the complexity traditionally associated with developing DSLs can be off-putting. We have demonstrated that modern compiler infrastructure provides a sea change and significantly reduces this overhead. Indeed, by formalising application configuration and interaction as
xDSL-CCPP: An alternative code generator for atmospheric modelling
15
Fig. 5. Existing code generation against our approach for four SCM suites on Cirrus
a DSL, one is able to both reduce bespoke code complexity and improve the user interface compared to configuration files, which often grow organically over time. Whilst xDSL-CCPP increased compilation time compared to the current tool, the amount of bespoke code reduced by three times and the overall model runtime is unaffected. Moreover, our approach provides additional flexibility such as being able to infer metadata from Fortran source code and hence avoid the need for manually written, and maintained, metadata files. Furthermore, we demonstrated that by working with Intermediate Representation (IR) at all stages in the pipeline, it is trivial to develop new frontends and provide a choice around the user interface. This enabled a Python-based frontend to be developed, which addresses some of the inflexibility associated with XML, especially when expressing control flow. The reduction in bespoke code benefits tool maintainers, metadata inference removes a manual burden from scheme developers, and the Python frontend gives suite integrators a more expressive configuration interface. For future work, we intend to explore automatic porting of suites to GPUs. There is a rich GPU ecosystem provided by MLIR, and previous work [3] demonstrated that existing MLIR passes were able to automatically transform serial loops in the scf dialect into the gpu dialect.
Acknowledgements This work was funded by the CONTINENTS EPSRC project grant number EP/Z531170/1. For the purposes of open access, the author has applied a CC
16
N. Brown and J. Dennis
BY public copyright license to any Author Accepted Manuscript version arising from this submission.
References 1. Bernardet, L., Bengtsson, L., Reinecke, P.A., Yang, F., Zhang, M., Hall, K., Doyle, J., Martini, M., Firl, G., Xue, L.: Common community physics package: fostering collaborative development in physical parameterizations and suites. Bulletin of the American Meteorological Society 105(8), E1490–E1505 (2024) 2. Bisbas, G., Lydike, A., Bauer, E., Brown, N., Fehr, M., Mitchell, L., RodriguezCanal, G., Jamieson, M., Kelly, P.H., Steuwer, M., et al.: A shared compilation stack for distributed-memory parallelism in stencil dsls. In: Proceedings of the 29th ACM International Conference on Architectural Support for Programming Languages and Operating Systems, Volume 3. pp. 38–56 (2024) 3. Brown, N.: Fully integrating the flang fortran compiler with standard mlir. In: SC24W: Workshops of the International Conference for High Performance Computing, Networking, Storage and Analysis. pp. 939–949. IEEE (2024) 4. Brown, N., Rodriguez-Canal, G.: Lifting to tensors when compiling scientific computing workloads for ai engines. In: Proceedings of the 26th IEEE International Symposium on Cluster, Cloud, and Internet Computing (2026) 5. CCPP SCM Development Team: Included cases. Single Column Model (SCM) for the Common Community Physics Package (CCPP) documentation, version 7.0.0, section 7.2 (2024), https://ccpp-scm.readthedocs.io/en/v7.0.0/chap_cases.html# included-cases, accessed: March 16, 2026 6. Fehr, M., Niu, J., Riddle, R., Amini, M., Su, Z., Grosser, T.: Irdl: an ir definition language for ssa compilers. In: Proceedings of the 43rd ACM SIGPLAN International Conference on Programming Language Design and Implementation. pp. 199–212 (2022) 7. Flang documentation (2024), https://flang.llvm.org/docs/ 8. Hsu, M.Y.: LLVM Techniques, Tips, and Best Practices Clang and Middle-End Libraries: Design powerful and reliable compilers using the latest libraries and tools from LLVM. Packt Publishing Ltd (2021) 9. Lattner, C., Adve, V.: Llvm: A compilation framework for lifelong program analysis & transformation. In: International symposium on code generation and optimization, 2004. CGO 2004. pp. 75–86. IEEE (2004) 10. Rodriguez-Canal, G., Katz, D., Brown, N.: An mlir pipeline for offloading fortran to fpgas via openmp. In: Proceedings of the SC’25 Workshops of the International Conference for High Performance Computing, Networking, Storage and Analysis. pp. 1096–1103 (2025) 11. Stawinoga, N., Katz, D., Lydike, A., Zarins, J., Brown, N., Bisbas, G., Grosser, T.: An mlir lowering pipeline for stencils at wafer-scale. In: Proceedings of the 31st ACM International Conference on Architectural Support for Programming Languages and Operating Systems, Volume 2. pp. 94–109 (2026) 12. A python compiler design toolkit (2023), https://github.com/xdslproject/xdsl
Related documents
- cmip5 output1 MOHC HadGEM2-CC piControl#1025895
- cmip5 output1 IPSL IPSL-CM5A-LR past1000#1025858
- cmip5 output1 NCC NorESM1-M historicalGHG#1025517
- cmip5 output1 MOHC HadGEM2-A sstClimSulfate#1025889
- cmip5 output1 CNRM-CERFACS CNRM-CM5 amip#1025914
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive