<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing with OASIS Tables v3.0 20080202//EN" "journalpub-oasis3.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:oasis="http://docs.oasis-open.org/ns/oasis-exchange/table" xml:lang="en" dtd-version="3.0" article-type="research-article"><?xmltex \makeatother\@nolinetrue\makeatletter?>
  <front>
    <journal-meta><journal-id journal-id-type="publisher">GMD</journal-id><journal-title-group>
    <journal-title>Geoscientific Model Development</journal-title>
    <abbrev-journal-title abbrev-type="publisher">GMD</abbrev-journal-title><abbrev-journal-title abbrev-type="nlm-ta">Geosci. Model Dev.</abbrev-journal-title>
  </journal-title-group><issn pub-type="epub">1991-9603</issn><publisher>
    <publisher-name>Copernicus Publications</publisher-name>
    <publisher-loc>Göttingen, Germany</publisher-loc>
  </publisher></journal-meta>
    <article-meta>
      <article-id pub-id-type="doi">10.5194/gmd-14-4401-2021</article-id><title-group><article-title>fv3gfs-wrapper: a Python wrapper of the FV3GFS atmospheric model</article-title><alt-title>fv3gfs-wrapper: a Python wrapper of the FV3GFS atmospheric model</alt-title>
      </title-group><?xmltex \runningtitle{fv3gfs-wrapper: a Python wrapper of the FV3GFS atmospheric model}?><?xmltex \runningauthor{J.~McGibbon et al.}?>
      <contrib-group>
        <contrib contrib-type="author" corresp="yes" rid="aff1">
          <name><surname>McGibbon</surname><given-names>Jeremy</given-names></name>
          <email>mcgibbon@uw.edu</email>
        <ext-link>https://orcid.org/0000-0003-4955-9772</ext-link></contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Brenowitz</surname><given-names>Noah D.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Cheeseman</surname><given-names>Mark</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1 aff2">
          <name><surname>Clark</surname><given-names>Spencer K.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Dahm</surname><given-names>Johann P. S.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Davis</surname><given-names>Eddie C.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1 aff2">
          <name><surname>Elbert</surname><given-names>Oliver D.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>George</surname><given-names>Rhea C.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff2">
          <name><surname>Harris</surname><given-names>Lucas M.</given-names></name>
          
        <ext-link>https://orcid.org/0000-0001-6072-8624</ext-link></contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Henn</surname><given-names>Brian</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Kwa</surname><given-names>Anna</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Perkins</surname><given-names>W. Andre</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Watt-Meyer</surname><given-names>Oliver</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Wicky</surname><given-names>Tobias F.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1 aff3">
          <name><surname>Bretherton</surname><given-names>Christopher S.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Fuhrer</surname><given-names>Oliver</given-names></name>
          
        </contrib>
        <aff id="aff1"><label>1</label><institution>Vulcan Inc., Seattle, WA, USA</institution>
        </aff>
        <aff id="aff2"><label>2</label><institution>Geophysical Fluid Dynamics Laboratory, NOAA, Princeton, NJ, USA</institution>
        </aff>
        <aff id="aff3"><label>3</label><institution>Department of Atmospheric Sciences, University of Washington, Seattle, WA, USA</institution>
        </aff>
      </contrib-group>
      <author-notes><corresp id="corr1">Jeremy McGibbon (mcgibbon@uw.edu)</corresp></author-notes><pub-date><day>16</day><month>July</month><year>2021</year></pub-date>
      
      <volume>14</volume>
      <issue>7</issue>
      <fpage>4401</fpage><lpage>4409</lpage>
      <history>
        <date date-type="received"><day>28</day><month>January</month><year>2021</year></date>
           <date date-type="rev-request"><day>10</day><month>March</month><year>2021</year></date>
           <date date-type="rev-recd"><day>21</day><month>May</month><year>2021</year></date>
           <date date-type="accepted"><day>16</day><month>June</month><year>2021</year></date>
      </history>
      <permissions>
        <copyright-statement>Copyright: © 2021 Jeremy McGibbon et al.</copyright-statement>
        <copyright-year>2021</copyright-year>
      <license license-type="open-access"><license-p>This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this licence, visit <ext-link ext-link-type="uri" xlink:href="https://creativecommons.org/licenses/by/4.0/">https://creativecommons.org/licenses/by/4.0/</ext-link></license-p></license></permissions><self-uri xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021.html">This article is available from https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021.html</self-uri><self-uri xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021.pdf">The full text article is available as a PDF file from https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021.pdf</self-uri>
      <abstract><title>Abstract</title>
    <p id="d1e232">Simulation software in geophysics is traditionally written in Fortran or C++ due to the stringent performance requirements these codes have to satisfy. As a result, researchers who use high-productivity languages for exploratory work often find these codes hard to understand, hard to modify, and hard to integrate with their analysis tools. fv3gfs-wrapper is an open-source Python-wrapped version of the NOAA (National Oceanic and Atmospheric Administration)  FV3GFS (Finite-Volume Cubed-Sphere Global Forecast System) global atmospheric model, which is coded in Fortran. The wrapper provides simple interfaces to progress the Fortran main loop and get or set variables used by the Fortran model. These interfaces enable a wide range of use cases such as modifying the behavior of the model, introducing online analysis code, or saving model variables and reading forcings directly to and from cloud storage. Model performance is identical to the fully compiled Fortran model, unless routines to copy the state in and out of the model are used. This copy overhead is well within an acceptable range of performance and could be avoided with modifications to the Fortran source code. The wrapping approach is outlined and can be applied similarly in other Fortran models to enable more productive scientific workflows.</p>
  </abstract>
    </article-meta>
  </front>
<body>
      

      <?xmltex \hack{\newpage}?>
<sec id="Ch1.S1" sec-type="intro">
  <label>1</label><title>Introduction</title>
      <p id="d1e246">FV3GFS (Finite-Volume Cubed-Sphere Global Forecast System) <xref ref-type="bibr" rid="bib1.bibx29" id="paren.1"/> is a prototype of the operational Global Forecast System of the National Centers for Environmental Prediction. In this document when we say FV3GFS we are referring specifically to the atmospheric component of the US National Oceanic and Atmospheric Administration (NOAA) Unified Forecast System (UFS; <uri>https://ufscommunity.org/</uri>, last access: 21 May 2021) for operational numerical weather prediction. We forked this code from the v1 branch of the UFS model in December 2019. It uses the Geophysical Fluid Dynamics Laboratory (GFDL) Finite-Volume Cubed-Sphere Dynamical Core (FV3). FV3 solves the non-hydrostatic equations of atmospheric motion discretized on a cubed sphere using a finite volume scheme on a terrain-following grid with D-grid wind staggering <xref ref-type="bibr" rid="bib1.bibx26 bib1.bibx10" id="paren.2"/>. The model is written in Fortran <xref ref-type="bibr" rid="bib1.bibx7" id="paren.3"/> and parallelized using a hybrid OpenMP (open multi-processing; <xref ref-type="bibr" rid="bib1.bibx22" id="altparen.4"/>)–MPI (message passing interface; <xref ref-type="bibr" rid="bib1.bibx19" id="altparen.5"/>) approach, which allows for performant execution through compilation.</p>
      <p id="d1e268">However, development of an atmospheric model using a low-level, strongly typed programming language with a small user base has trade-offs. Libraries for interacting with cloud storage, performing physical or statistical analysis, and using machine learning are not as readily available or widely used in languages like Fortran as they are in high-level<?pagebreak page4402?> languages such as Python. A Python interface to the compiled Fortran code can enable a much larger user base to interact with this code and allow a large ecosystem of Python tools to be interfaced with model routines.</p>
      <p id="d1e271">Python is often integrated into Fortran modeling workflows as a post-processing tool, as shown in Fig. <xref ref-type="fig" rid="Ch1.F1"/>. In this workflow, Python is used to perform computations on data saved to the filesystem by the Fortran model. This approach has several shortcomings. It is rarely feasible to store the full-resolution model state at each model time step, so often statistics over time are stored instead. Unless sufficiently frequent snapshots are stored, computing new statistics directly from full-resolution instantaneous fields requires writing Fortran code to run in the model. This can be an issue if developer documentation is not available or the user is not familiar with Fortran. This approach requires writing to disk before data can be used in Python, which may be unnecessary if the written data do not comprise a necessary end product. Such filesystem operations can be a significant bottleneck in computation time. This approach also does not provide a way to use Python libraries when modifying the behavior of the Fortran model, as any logic after the data are read from disk must be written in Fortran. Instead, machine learning practitioners port machine learning routines to Fortran using models that have been trained and saved using Python <xref ref-type="bibr" rid="bib1.bibx23 bib1.bibx3" id="paren.6"/>.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F1"><?xmltex \currentcnt{1}?><?xmltex \def\figurename{Figure}?><label>Figure 1</label><caption><p id="d1e282">Schematic of Fortran-centric workflow using the filesystem to transfer data to Python user code. Arrowheads indicate the direction of the model main loop, as well as data transfer out of the Fortran model and into the Python user script.</p></caption>
        <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-f01.png"/>

      </fig>

      <p id="d1e291">In this work, we present a Python wrapper for the FV3GFS global atmospheric model. As shown in Fig. <xref ref-type="fig" rid="Ch1.F2"/>, the FV3GFS model is compiled as a shared library with wrapper routines that provide an API (application programming interface) to control and interact with the model. At the core of any weather or climate model is the main integration loop, which integrates the model state forward by a period of time. The wrapper splits the simple model main loop into a sequence of subroutines that can be called from Python. This allows the main loop to be written in Python, through calls to each section of the Fortran main loop (<monospace>step_dynamics</monospace>, <monospace>step_physics</monospace>). Furthermore, it allows copying variables into (<monospace>set_state</monospace>) or out of (<monospace>get_state</monospace>) the Fortran runtime environment, so it can be used in Python functions that can affect the integration of the Fortran model state. Data retrieved with <monospace>get_state</monospace> include unit information, for ease of debugging and for reference to data written to disk.</p>
      <p id="d1e312">As the wrapper currently stands, configuration is deferred entirely to the Fortran model code. The only change in initialization is that MPI is initialized by mpi4py (MPI for Python), after which the MPI communicator is passed as a Fortran handle to the model initialization routines. This allows us to maintain feature completeness with the existing Fortran model, without re-writing configuration logic.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F2"><?xmltex \currentcnt{2}?><?xmltex \def\figurename{Figure}?><label>Figure 2</label><caption><p id="d1e317">Schematic of Python-centric workflow using fv3gfs-wrapper, showing how it can interface with Python libraries during model execution. Arrowheads indicate data transfer between user Python code and Fortran model.</p></caption>
        <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-f02.png"/>

      </fig>

      <p id="d1e326">This Python-centric workflow enables a fundamentally different way to integrate tools available in the Python ecosystem into a Fortran modeling workflow. A user can add online diagnostic code after a physics or dynamics step and perform input or output (I/O) to or from cloud resources. The model state can be reset to a previous one, allowing sensitivity studies to be run online. Custom logic can be added to the main loop after a physics or dynamics step, such as a machine learning corrector parameterization or nudging to a cloud-based forcing dataset. The use of a Python main loop makes it significantly easier to integrate custom I/O, diagnostic routines, and physical parameterizations into the model.</p>
      <p id="d1e330">This ease of integration is an important tool when developing parameterizations using machine learning. When developing such schemes, offline performance does not guarantee performance when run online within a model. However it can be difficult to rapidly train a model in a language with machine learning libraries such as Python and then convert it for use in Fortran. Solutions have so far been based on Fortran executables, either by calling Python from Fortran <xref ref-type="bibr" rid="bib1.bibx2" id="paren.7"/> or by re-implementing neural network codes in Fortran <xref ref-type="bibr" rid="bib1.bibx23 bib1.bibx3" id="paren.8"/>. Because of the strong tooling available for machine learning in Python, it is advantageous to be able to include Python machine learning code within the atmospheric model. Presently Python code can only be integrated outside of the dynamics and physics routines and not within the physics suite. Adding flexibility to introduce Python code<?pagebreak page4403?> between individual physics schemes remains a subject for future work.</p>
      <p id="d1e339">This is not the first time Python and high-performance compiled programs have been combined. qtcm <xref ref-type="bibr" rid="bib1.bibx14" id="paren.9"/> applies a similar wrapping approach to a quasi-equilibrium tropical circulation model using F2PY <xref ref-type="bibr" rid="bib1.bibx24" id="paren.10"/>, an automated Fortran-to-Python interface generator. PyCLES <xref ref-type="bibr" rid="bib1.bibx25" id="paren.11"/> is a full large-eddy simulation written in Cython, a variant of Python that compiles to C code and can interoperate with Python codes. climt <xref ref-type="bibr" rid="bib1.bibx21" id="paren.12"/> wraps Fortran model components into Python objects that can be composed to define a model main loop in Python. In astronomy, Python computational codes such as nbodykit <xref ref-type="bibr" rid="bib1.bibx8" id="paren.13"/> run using NumPy <xref ref-type="bibr" rid="bib1.bibx9" id="paren.14"/> and MPI for Python <xref ref-type="bibr" rid="bib1.bibx4" id="paren.15"/> and are shown to scale to thousands of ranks. These previous works provide confidence that a model using Python to call compiled code can provide the level of scaling and performance required for atmospheric and climate science research.</p>
      <p id="d1e364">A consideration in designing new atmospheric models is the large amount of legacy Fortran code already available. As a consequence, new model components are often written in Fortran so that they can interface with such legacy code. Efforts to re-write existing Fortran models (for example, to run on graphics processing unit (GPU) architectures) can benefit from the ability to progressively replace existing components with refactored or re-written codes in other languages.</p>
      <p id="d1e367">To motivate the design choices made in this work, we present our main priorities: retain existing functionality of the Fortran model, minimal sacrifice of performance, a main time-stepping loop which is easy to understand and modify, and minimal changes to Fortran code.</p>
      <p id="d1e370">Most of these priorities clearly come from our focus on improving model accessibility for researchers interested in modifying the behavior of the Fortran code. They would benefit from retaining the existing functionality they would like to modify, and they should be able to easily understand how the code can be modified. They may require efficient model performance on high-performance computers for research problems using higher-resolution simulations. By minimizing the needed changes to the Fortran code, we can reduce the effort required to switch to a new Fortran model version.</p>
      <p id="d1e373">While this wrapper has many applications, we will focus on illustrative scenarios relevant to our own FV3GFS model development work. In addition to reproducing the existing model behavior, we will show how to augment the Fortran model with a machine learning parameterization, include custom MPI communication as part of online diagnostic code, and perform online analysis in a Jupyter notebook.</p>
      <p id="d1e377">We will begin by showing in Sect. <xref ref-type="sec" rid="Ch1.S2"/> how fv3gfs-wrapper can be used to reproduce, bit for bit, the results of the existing Fortran model. We will then show in Sect. <xref ref-type="sec" rid="Ch1.S3"/> how fv3gfs-wrapper enables each of these use cases while achieving our priorities of performance, ease of understanding, and ease of modification. Having presented the features of fv3gfs-wrapper by example, we will delve more deeply into their implementation in Sect. <xref ref-type="sec" rid="Ch1.S4"/>. Finally, we will discuss some of the challenges encountered in designing and implementing fv3gfs-wrapper in Sect. <xref ref-type="sec" rid="Ch1.S4.SS5"/> before drawing our conclusions in Sect. <xref ref-type="sec" rid="Ch1.S5"/>.</p>
</sec>
<sec id="Ch1.S2">
  <label>2</label><title>Validation</title>
      <p id="d1e398">For completeness and testing, fv3gfs-wrapper should be able to reproduce, bit for bit, the results of the Fortran model. This allows us to test the logic wrapping the Fortran code. Because the wrapper executes Fortran code identical to the original Fortran model, bit-for-bit regression on one parameter configuration or forcing dataset gives us confidence the code can be used for any parameter configuration or forcing dataset. The implementation of this use case is as follows:
<?xmltex \igopts{width=236.157874pt}?><inline-graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-g01.png"/></p>
      <p id="d1e405">The existing main routine in coupler_main.f90 separates relatively cleanly into five routines: one each to initialize and finalize the model, one for dynamics (resolved fluid flow), one for physics (subgrid-scale processes), and one that will write intermediate restart data if intermediate restart files are enabled for the run and if we should write a restart on the current time step. Each of these Python routines calls that section of the Fortran code and then returns to a Python context.</p>
      <p id="d1e408">The overhead of the Python time step loop and the wrapper functions is negligible in comparison to the computation performed within a process (Table <xref ref-type="table" rid="Ch1.T1"/>), meeting our performance goal. The conciseness of the main loop makes it easy to understand what the code is doing at a high level. This example is easy to modify, as shown in the use cases in the next section.</p>
      <p id="d1e413">This code and the command-line examples below are available in the examples/gmd_timings directory of the Git repository for fv3gfs-wrapper as referenced in the “Code and data availability” statement, using a 6 h C48 run directory <xref ref-type="bibr" rid="bib1.bibx18" id="paren.16"/>. The timings for each of these examples are included in Table <xref ref-type="table" rid="Ch1.T1"/>. We can see the wrapper does not add significant overhead to the Fortran baseline timing.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T1"><?xmltex \currentcnt{1}?><label>Table 1</label><caption><p id="d1e425">Runtimes of examples and compiled Fortran model. Baseline refers to reproducing existing Fortran behavior. Examples were run for 6 h of simulation time at C48 resolution in six processes on a 2019 MacBook Pro. Each example was run three times, and the shortest time is reported.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="2">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Example</oasis:entry>
         <oasis:entry colname="col2">Runtime (s)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">Fortran baseline</oasis:entry>
         <oasis:entry colname="col2">110</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Wrapper baseline</oasis:entry>
         <oasis:entry colname="col2">110</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Random forest</oasis:entry>
         <oasis:entry colname="col2">116</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Minimum surface pressure</oasis:entry>
         <oasis:entry colname="col2">110</oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

</sec>
<sec id="Ch1.S3">
  <label>3</label><title>Use cases in action</title>
      <p id="d1e496">All examples discussed in this section are included in the public repository for fv3gfs-wrapper linked to in the “Code<?pagebreak page4404?> and data availability” statement. We encourage the reader to download and run these examples on their own computer, using the example run directory <xref ref-type="bibr" rid="bib1.bibx18" id="paren.17"/>.</p>
<sec id="Ch1.S3.SS1">
  <label>3.1</label><title>Augmenting the model with machine learning</title>
      <p id="d1e509">An important use case motivating this work is to be able to modify the operation of the model main loop, for example by adding a machine learning model that applies tendencies at the end of each time step. This serves as an example for how the main loop can be modified more generically, such as by adding I/O functionality or online diagnostics, using <monospace>fv3gfs.wrapper.get_state</monospace> and <monospace>fv3gfs.wrapper.set_state</monospace> to interface with the Fortran model.</p>
      <p id="d1e518"><?xmltex \igopts{width=236.157874pt}?><inline-graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-g02.png"/></p>
      <p id="d1e524">The example includes a compact random forest we have trained on nudging tendencies towards reanalysis data. The separation of physics and dynamics steps in the code makes it clear that the machine learning update is applied at the end of a physics step and is included in any intermediate restart data. The random forest model used in this example is trained according to the approach in <xref ref-type="bibr" rid="bib1.bibx28" id="text.18"/>, with a small number of trees and layers chosen to decrease model size. As a proof of concept, the example model has not been tuned for stability and may crash if run for longer than 6 h or if a run directory other than the example provided is used. Model stability can be increased by enforcing the model specific humidity to be non-negative after applying the random forest update.</p>
      <p id="d1e530">This example showcases how the wrapper makes it easy to modify the operation of the Fortran model. In our own efforts to re-write the FV3 dynamical core in a Python-based domain-specific language (DSL), we have directly replaced a call to the Fortran dynamics step with Python-based code. We have also added nudging routines that directly access Zarr <xref ref-type="bibr" rid="bib1.bibx20" id="paren.19"/> reference datasets stored in the cloud and I/O routines to save model snapshots to Zarr files in cloud storage as the model executes. With Python's threading support, this data transfer can happen as the Fortran code is running. These tasks would be difficult to implement in Fortran due to more complex threading interfaces, no existing bindings for Zarr, and a lack of support from cloud storage providers.</p>
</sec>
<sec id="Ch1.S3.SS2">
  <label>3.2</label><title>MPI communication</title>
      <p id="d1e544">When writing parallel models, inter-process communication is an important functionality. mpi4py <xref ref-type="bibr" rid="bib1.bibx4" id="paren.20"/> provides Python bindings for MPI routines and supports the use of NumPy arrays. Using mpi4py, we have been able to implement halo updates and gather and scatter operations. The syntax for mpi4py is similar to the syntax used in Fortran. In our implementation, the same MPI communicator is used by the Fortran code as is used by mpi4py.</p>
      <p id="d1e550">Here we show a simple example of computing the minimum global surface temperature and printing it from the root process. This showcases how you can use mpi4py within the model to compute diagnostics using inter-rank communication.</p>
      <?pagebreak page4405?><p id="d1e553"><?xmltex \hack{\newpage}?><?xmltex \igopts{width=236.157874pt}?><inline-graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-g03.png"/></p>
</sec>
<sec id="Ch1.S3.SS3">
  <label>3.3</label><title>Interactive use in a Jupyter notebook</title>
      <p id="d1e568">While we typically run the model using batch submission or from the command line, all of the examples above can be executed from within a Jupyter notebook using ipyparallel. This allows retrieving, computing, and plotting variables from the Fortran model while it is paused at a point of interest. It also can serve as explicit documentation of modeled phenomena, whether to communicate to other model developers or for use in an educational setting.</p>
      <p id="d1e571">We have prepared an example that inspects the machine learning example model, using MPI communication from Python to gather and plot variables on a single rank (Fig. <xref ref-type="fig" rid="Ch1.F3"/>). It can be accessed in the examples/jupyter directory of the GitHub repository and makes use of Docker to ensure portability. While the example is written to run in six processes, ipyparallel allows notebooks to be run at larger scales on high-performance computing (HPC) clusters if the configuration is modified appropriately.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F3" specific-use="star"><?xmltex \currentcnt{3}?><?xmltex \def\figurename{Figure}?><label>Figure 3</label><caption><p id="d1e578">Screenshot of Jupyter notebook example using MPI communication to gather a field in six processes and plot it on the first process. Note the FV3GFS uses a “cubed-sphere” grid, so for six processes each one is responsible for one face of the cube.</p></caption>
          <?xmltex \igopts{width=341.433071pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/14/4401/2021/gmd-14-4401-2021-f03.png"/>

        </fig>

</sec>
</sec>
<sec id="Ch1.S4">
  <label>4</label><title>Implementation</title>
<sec id="Ch1.S4.SS1">
  <label>4.1</label><title>Information transfer</title>
      <p id="d1e604">To augment the Fortran model, we must read from and write to its state. This information transfer can be done in two ways, either by providing an interface to copy data between Fortran and Python arrays (effectively C arrays) or by using the same memory in both codes. Re-using memory requires that the Fortran code use a pointer to a C array, allowing the same pointer to be used by the NumPy array on the Python side. In the Fortran code for FV3GFS, arrays used for physical variables are defined as non-target <monospace>allocatable</monospace> arrays, which precludes sharing them with Python. It would require significant changes to the Fortran code to instead use pointers to C arrays, which conflicts with our priority of making minimal changes to the Fortran code. Instead, the getters and setters (the routines which transfer variable values between Python and Fortran) perform a data copy between NumPy-allocated C arrays and Fortran arrays within the wrapper layer.</p>
</sec>
<sec id="Ch1.S4.SS2">
  <label>4.2</label><title>Metaprogramming to pass arrays</title>
      <p id="d1e618">Copying data from Python into a Fortran array requires a significant amount of code. Unless a structure of the Fortran data can be assumed, each Fortran variable to be accessed needs at least its own line of Fortran code and in practice its own pair of subroutines, containing an assignment between a Python buffer and the correct Fortran variable. In our approach, each variable has two Fortran wrapper subroutines for getting and setting that variable, logic within a C wrapper layer for calling those Fortran wrapper subroutines, and header declarations for those subroutines.</p>
      <p id="d1e621">Writing each of these manually would take significant time and effort. Instead we use Jinja templates <xref ref-type="bibr" rid="bib1.bibx27" id="paren.21"/> to generate these wrappers using JSON files declaring necessary information such as the Fortran variable name, standard name, units, and dimensionality. For example, the Fortran variable name “zorl” has the standard name “surface_roughness”, units “cm”, and dimensionality <monospace>["y", "x"]</monospace>. This greatly reduces the number of lines required to write the code. For physics variables, the template file and data file are 89 and 459 lines, respectively, while the generated Fortran file is 1894 lines. Physics variables are also responsible for most of the lines in the 1680-line Cython file generated. Adding a new physics variable requires adding an entry to a JSON file with its standard name, Fortran name, Fortran data container name, dimensions, and units. This JSON file is also used to automatically enable unit tests for the getters and setters of each physics variable.</p>
</sec>
<sec id="Ch1.S4.SS3">
  <label>4.3</label><title>Portability and testing using Docker</title>
      <p id="d1e638">One choice made in developing fv3gfs-wrapper was to use Docker containers for testing and our own research use of<?pagebreak page4406?> the wrapped model. Using a Docker image ensures that across systems, we can consistently install the dependencies of FV3GFS, the Flexible Modeling System (FMS), and the Earth System Modeling Framework (ESMF) on a host system. Users can make use of the Docker container identically on cloud computing resources, continuous integration systems, and our host machines without the need for separate configuration of the compilation process for each system. This removes the possibility of error from incorrect build instructions or execution of those instructions or unexpected interactions with the host environment. Furthermore, it documents the process required to build the environment for the model and fv3gfs-wrapper, which should help in setting it up directly (i.e., without use of containers) on a machine. Finally, it facilitates distribution of the model to others who may not have access to HPC resources and may want to reproduce our results on personal computers or cloud resources. The Docker image at the time of publication can be retrieved as gcr.io/vcm-ml/fv3gfs-wrapper:v0.6.0 or from <xref ref-type="bibr" rid="bib1.bibx16" id="text.22"/>.</p>
</sec>
<sec id="Ch1.S4.SS4">
  <label>4.4</label><title>Extending this approach to other models</title>
      <p id="d1e652">While we have applied this wrapping approach to the FV3GFS model specifically, nothing about it is particular to this model. Our methodology should generalize to other atmospheric and climate models. This wrapper is an example of how one can wrap Fortran models in general to be accessible through Python. While using Cython and Fortran wrapper layers (as we have done here) involves writing more code than using automated wrapping tools such as f90wrap <xref ref-type="bibr" rid="bib1.bibx13" id="paren.23"/>, it provides the flexibility necessary to wrap the existing Fortran code with minimal changes. We found much of the repetitive boilerplate needed for this wrapping can be handled through Jinja templating. With this approach, a Python wrapper can be produced for very complex build systems with only minimal modifications (such as ensuring the necessary variables and routines are externally accessible) to the existing model code.</p>
      <p id="d1e658">The use of getters and setters introduces a copy overhead cost when modifying the base model behavior. However, it avoids refactoring necessary for a shared memory implementation, which would require modifying the Fortran code to use C-accessible arrays that can be shared with Python. Writing a Fortran wrapper layer for the getters and setters ensures that any variable modifiable in Fortran can also be modified in Python.</p>
      <p id="d1e661">In wrapping the FV3GFS, we have split the FV3GFS model main loop into a sequence of subroutines, which are then wrapped to call from Python. This task is likely to be different in other Fortran models, particularly models with abstract main loops or complex coupling infrastructures. So long as Fortran subroutines can be defined to execute each part of the model main loop, these can be wrapped to call from Python for model integration.</p>
</sec>
<sec id="Ch1.S4.SS5">
  <label>4.5</label><title>Challenges and limitations</title>
      <p id="d1e673">Python reads many files on initialization when it imports packages. This can cause significant slowdown on HPC<?pagebreak page4407?> systems using shared filesystems. Approaches using parallel filesystems, such as Sarus on HPC or Docker-based cloud solutions, can avoid this issue. When a shared filesystem must be used, solutions exist such as python-mpi-bcast <xref ref-type="bibr" rid="bib1.bibx6" id="paren.24"/> modifying the CPython binary as reported by <xref ref-type="bibr" rid="bib1.bibx5" id="text.25"/>.</p>
      <p id="d1e682">Both the dynamics and the physics are treated as single subroutines in the wrapper. This does not allow inserting Python code within the physics suite, between schemes. This limitation may be removed in the future by adding a wrapper for physics schemes in the Common Community Physics Package (CCPP; <xref ref-type="bibr" rid="bib1.bibx11" id="altparen.26"/>). Through CCPP, it should be possible to separate the physics driver into multiple calls, allowing Python code to be called between any chosen physics schemes.</p>
      <p id="d1e688">It is also important to remember when trying to modify the behavior of FV3GFS that, with or without a wrapper, it is still fundamentally a complex parallel model. Parallel code is difficult to test, since the order of code execution is non-deterministic <xref ref-type="bibr" rid="bib1.bibx1" id="paren.27"/>.</p>
      <p id="d1e694">It may also be necessary to understand the physical relationships between different model variables in the Fortran code. For example, the dry air mass of a model layer in FV3GFS is a diagnostic function of the layer pressure thickness and tracer mixing ratios. Increasing the model specific humidity will remove dry air mass, unless the layer pressure thickness is also increased. To account for this, we have included a routine, <monospace>fv3gfs.set_state_mass_conserving</monospace>, that modifies layer pressure thickness according to any changes in water tracer amounts.</p>
</sec>
</sec>
<sec id="Ch1.S5" sec-type="conclusions">
  <label>5</label><title>Conclusions</title>
      <p id="d1e709">We have presented fv3gfs-wrapper, a Python-wrapped version of the FV3GFS atmospheric model. The wrapper allows users to control and interact with an atmospheric model written in Fortran. The simple and intuitive interface allows for a Python-centric workflow and can be used to enable a wide range of use cases, such as machine learning parameterization development, online analysis, and interactive model execution. We do not see a decrease in model performance relative to the fully compiled model, unless routines to copy the model state in and out of the Fortran model are used. This copy overhead is well within an acceptable range of performance and could be avoided with modifications to the Fortran source code.</p>
      <p id="d1e712">We showed examples of how Python and Docker can be used to reproduce and modify the existing Fortran model and how the Fortran code can be called in an interactive Jupyter environment. In addition to accelerating research and development workflows, these examples show how a full-fledged weather and climate model can be made available for reproducible science and teaching.</p>
      <p id="d1e715">The outlined wrapping approach can be applied to other Fortran models. The Python-wrapped FV3GFS atmospheric model shows the way for a new generation of weather and climate models, where the top-level control flow of the model is implemented in a high-level language such as Python while the performance-critical sections are implemented in a low-level, performant language. This is a powerful approach that has already been used in popular Python packages such as NumPy and TensorFlow. We hope to see this approach extended to other models, enabling more widespread access to Python tools in developing traditional Fortran models and reducing the barrier to access for researchers and students interested in introducing online analysis code into these models.</p>
</sec>

      
      </body>
    <back><notes notes-type="codedataavailability"><title>Code and data availability</title>

      <p id="d1e722">Code for this project is available on GitHub at <uri>https://github.com/VulcanClimateModeling/fv3gfs-wrapper</uri> tag v0.6.0 <xref ref-type="bibr" rid="bib1.bibx15" id="paren.28"><named-content content-type="post"><ext-link xlink:href="https://doi.org/10.5281/zenodo.4429298" ext-link-type="DOI">10.5281/zenodo.4429298</ext-link></named-content></xref>, <uri>https://github.com/VulcanClimateModeling/fv3gfs-fortran</uri> tag gmd_submission <xref ref-type="bibr" rid="bib1.bibx12" id="paren.29"><named-content content-type="post"><ext-link xlink:href="https://doi.org/10.5281/zenodo.4470023" ext-link-type="DOI">10.5281/zenodo.4470023</ext-link></named-content></xref>, and <uri>https://github.com/VulcanClimateModeling/fv3gfs-util</uri> tag v0.6.0 <xref ref-type="bibr" rid="bib1.bibx17" id="paren.30"><named-content content-type="post"><ext-link xlink:href="https://doi.org/10.5281/zenodo.4470011" ext-link-type="DOI">10.5281/zenodo.4470011</ext-link></named-content></xref>. It is also available as a Docker image at gcr.io/vcm-ml/fv3gfs-wrapper:v0.6.0 <xref ref-type="bibr" rid="bib1.bibx16" id="paren.31"><named-content content-type="post"><ext-link xlink:href="https://doi.org/10.5281/zenodo.4474639" ext-link-type="DOI">10.5281/zenodo.4474639</ext-link></named-content></xref>. The run directory used to time the examples may be retrieved from <xref ref-type="bibr" rid="bib1.bibx18" id="text.32"/> (<ext-link xlink:href="https://doi.org/10.5281/zenodo.4429298" ext-link-type="DOI">10.5281/zenodo.4429298</ext-link>).</p>
  </notes><notes notes-type="authorcontribution"><title>Author contributions</title>

      <p id="d1e768">JM contributed the initial version of the wrapper and has led its development. Significant code contributions have been made by NDB, OWM, SKC, MC, BH, TFW, OF, and AK. All authors were involved in design discussions and provided feedback on the code. JM prepared the manuscript with contributions from all co-authors.</p>
  </notes><notes notes-type="competinginterests"><title>Competing interests</title>

      <p id="d1e774">The authors declare that they have no conflict of interest.</p>
  </notes><notes notes-type="disclaimer"><title>Disclaimer</title>

      <p id="d1e780">Publisher's note: Copernicus Publications remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.</p>
  </notes><ack><title>Acknowledgements</title><p id="d1e786">We thank Vulcan Inc. for supporting this work. We acknowledge NOAA EMC, NOAA GFDL, and the UFS community for publicly hosting source code for the FV3GFS model (<uri>https://github.com/ufs-community/ufs-weather-model</uri>, last access: 21 May 2021) and NOAA-EMC for providing the necessary forcing data to run FV3GFS. The FV3GFS model code used was forked from the UFS public release branch in December 2019. Computations supporting this work were also supported by a grant from the Swiss National Supercomputing Centre (CSCS) under project ID s1053.</p></ack><notes notes-type="reviewstatement"><title>Review statement</title>

      <p id="d1e794">This paper was edited by James Kelly and reviewed by Dom Heinzeller and two anonymous referees.</p>
  </notes><ref-list>
    <title>References</title>

      <ref id="bib1.bibx1"><?xmltex \def\ref@label{{{Bianchi} et~al.(2018)}}?><label>Bianchi et al.(2018)</label><?label Bianchi2018?><mixed-citation>Bianchi, F. A., Margara, A., and Pezzè, M.: A Survey of Recent Trends in
Testing Concurrent Software Systems, IEEE T. Soft.
Eng., 44, 747–783, <ext-link xlink:href="https://doi.org/10.1109/TSE.2017.2707089" ext-link-type="DOI">10.1109/TSE.2017.2707089</ext-link>, 2018.</mixed-citation></ref>
      <ref id="bib1.bibx2"><?xmltex \def\ref@label{{Brenowitz and Bretherton(2019)}}?><label>Brenowitz and Bretherton(2019)</label><?label Brenowitz2019?><mixed-citation>Brenowitz, N. D. and Bretherton, C. S.: Spatially Extended Tests of a Neural
Network Parametrization Trained by Coarse-Graining, J. Adv.
Model. Earth Sy., 11, 2728–2744, <ext-link xlink:href="https://doi.org/10.1029/2019MS001711" ext-link-type="DOI">10.1029/2019MS001711</ext-link>, 2019.</mixed-citation></ref>
      <ref id="bib1.bibx3"><?xmltex \def\ref@label{{Curcic(2019)}}?><label>Curcic(2019)</label><?label Curcic2019?><mixed-citation>Curcic, M.: A parallel Fortran framework for neural networks and deep learning,
CoRR, abs/1902.06714, available at: <uri>http://arxiv.org/abs/1902.06714</uri> (last access: 21 May 2021), 2019.</mixed-citation></ref>
      <ref id="bib1.bibx4"><?xmltex \def\ref@label{{Dalc{\'{\i}}n et~al.(2008)}}?><label>Dalcín et al.(2008)</label><?label mpi4py?><mixed-citation>Dalcín, L., Paz, R., Storti, M., and D'Elía, J.: MPI for
Python: Performance improvements and MPI-2 extensions, J. Parallel
Distr. Com., 68, 655–662, <ext-link xlink:href="https://doi.org/10.1016/j.jpdc.2007.09.005" ext-link-type="DOI">10.1016/j.jpdc.2007.09.005</ext-link>,
2008.</mixed-citation></ref>
      <ref id="bib1.bibx5"><?xmltex \def\ref@label{{Enkovaara et~al.(2011)}}?><label>Enkovaara et al.(2011)</label><?label Enkovaara2011?><mixed-citation>Enkovaara, J., Romero, N. A., Shende, S., and Mortensen, J. J.: GPAW –
massively parallel electronic structure calculations with Python-based
software, Procedia Comput. Sci., 4, 17–25,
<ext-link xlink:href="https://doi.org/10.1016/j.procs.2011.04.003" ext-link-type="DOI">10.1016/j.procs.2011.04.003</ext-link>, 2011.</mixed-citation></ref>
      <ref id="bib1.bibx6"><?xmltex \def\ref@label{{Feng(2021)}}?><label>Feng(2021)</label><?label mpibcast?><mixed-citation>Feng, Y.: python-mpi-bcast,
available at: <uri>https://github.com/rainwoodman/python-mpi-bcast</uri> (last access: 7 April 2021), 2021.</mixed-citation></ref>
      <ref id="bib1.bibx7"><?xmltex \def\ref@label{{{Global Engineering Documents}(1991)}}?><label>Global Engineering Documents(1991)</label><?label fortran90?><mixed-citation>
Global Engineering Documents: Fortran 90, Global Engineering Documents,
Washington, D.C., USA, 1991.</mixed-citation></ref>
      <ref id="bib1.bibx8"><?xmltex \def\ref@label{{Hand and Feng(2017)}}?><label>Hand and Feng(2017)</label><?label Hand2017?><mixed-citation>Hand, N. and Feng, Y.: nbodykit, in: Proceedings of the 7th Workshop on Python
for High-Performance and Scientific Computing – PyHPC'17,
ACM Press, <ext-link xlink:href="https://doi.org/10.1145/3149869.3149876" ext-link-type="DOI">10.1145/3149869.3149876</ext-link>, 2017.</mixed-citation></ref>
      <ref id="bib1.bibx9"><?xmltex \def\ref@label{{Harris et~al.(2020)}}?><label>Harris et al.(2020)</label><?label Harris2020?><mixed-citation>Harris, C. R., Millman, K. J., van der Walt, S. J., Gommers, R., Virtanen, P.,
Cournapeau, D., Wieser, E., Taylor, J., Berg, S., Smith, N. J., Kern, R.,
Picus, M., Hoyer, S., van Kerkwijk, M. H., Brett, M., Haldane, A., del
Río, J. F., Wiebe, M., Peterson, P., Gérard-Marchant, P.,
Sheppard, K., Reddy, T., Weckesser, W., Abbasi, H., Gohlke, C., and Oliphant,
T. E.: Array programming with NumPy, Nature, 585, 357–362,
<ext-link xlink:href="https://doi.org/10.1038/s41586-020-2649-2" ext-link-type="DOI">10.1038/s41586-020-2649-2</ext-link>, 2020.</mixed-citation></ref>
      <ref id="bib1.bibx10"><?xmltex \def\ref@label{{Harris and Lin(2013)}}?><label>Harris and Lin(2013)</label><?label Harris2013?><mixed-citation>Harris, L. M. and Lin, S.-J.: A Two-Way Nested Global-Regional Dynamical Core
on the Cubed-Sphere Grid, Mon. Weather Rev., 141, 283–306,
<ext-link xlink:href="https://doi.org/10.1175/MWR-D-11-00201.1" ext-link-type="DOI">10.1175/MWR-D-11-00201.1</ext-link>, 2013.</mixed-citation></ref>
      <ref id="bib1.bibx11"><?xmltex \def\ref@label{{Heinzeller et~al.(2020)}}?><label>Heinzeller et al.(2020)</label><?label Heinzeller2020?><mixed-citation>Heinzeller, D., Firl, G., Bernardet, L., Carson, L., Zhang, M., and Kain, J.: The Common Community Physics Package (CCPP): bridging the gap between research and operations to improve U.S. numerical weather prediction capabilities, EGU General Assembly 2020, Online, 4–8 May 2020, EGU2020-23, <ext-link xlink:href="https://doi.org/10.5194/egusphere-egu2020-23" ext-link-type="DOI">10.5194/egusphere-egu2020-23</ext-link>,
2020.</mixed-citation></ref>
      <ref id="bib1.bibx12"><?xmltex \def\ref@label{{Heinzeller et~al.(2021)}}?><label>Heinzeller et al.(2021)</label><?label fv3gfs_fortran?><mixed-citation>Heinzeller, D., Underwood, S., Firl, G., Wang, J., Liang, Z., Menzel, R.,
Robinson, T., Brown, T., Benson, R., Hartnett, E., Schramm, J., Ramirez, U.,
gbw gfdl, Carson, L., McGibbon, J., Fuhrer, O., Jess, Clark, S., Smirnova,
T., Hallberg, R., Bernardet, L., Potts, M., Zadeh, N., Olson, J., Jovic, D.,
George, R., Paulot, F., Goldhaber, S., and Li, H.:
VulcanClimateModeling/fv3gfs-fortran: GMD release [code], Zenodo,
<ext-link xlink:href="https://doi.org/10.5281/zenodo.4470023" ext-link-type="DOI">10.5281/zenodo.4470023</ext-link>, 2021.</mixed-citation></ref>
      <ref id="bib1.bibx13"><?xmltex \def\ref@label{{Kermode(2020)}}?><label>Kermode(2020)</label><?label f90wrap?><mixed-citation>Kermode, J. R.: f90wrap: an automated tool for constructing deep Python
interfaces to modern Fortran codes, J. Phys. Condens. Matter,
<ext-link xlink:href="https://doi.org/10.1088/1361-648X/ab82d2" ext-link-type="DOI">10.1088/1361-648X/ab82d2</ext-link>, 2020.</mixed-citation></ref>
      <ref id="bib1.bibx14"><?xmltex \def\ref@label{{Lin(2009)}}?><label>Lin(2009)</label><?label Lin2009?><mixed-citation>Lin, J. W.-B.: qtcm 0.1.2: a Python implementation of the Neelin-Zeng Quasi-Equilibrium Tropical Circulation Model, Geosci. Model Dev., 2, 1–11, <ext-link xlink:href="https://doi.org/10.5194/gmd-2-1-2009" ext-link-type="DOI">10.5194/gmd-2-1-2009</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx15"><?xmltex \def\ref@label{{McGibbon et~al.(2021{\natexlab{a}})}}?><label>McGibbon et al.(2021a)</label><?label fv3gfs_wrapper?><mixed-citation>McGibbon, J., Brenowitz, N. D., Watt-Meyer, O., Clark, S., Cheeseman, M., Henn,
B., Fuhrer, O., Wicky, T., and Elbert, O.:
VulcanClimateModeling/fv3gfs-wrapper: v0.6.0 GMD release [code], Zenodo,
<ext-link xlink:href="https://doi.org/10.5281/zenodo.4474598" ext-link-type="DOI">10.5281/zenodo.4474598</ext-link>, 2021a.</mixed-citation></ref>
      <ref id="bib1.bibx16"><?xmltex \def\ref@label{{McGibbon et~al.(2021{\natexlab{b}})}}?><label>McGibbon et al.(2021b)</label><?label fv3gfs_wrapper_image?><mixed-citation>McGibbon, J., Brenowitz, N. D., Watt-Meyer, O., Clark, S., Cheeseman, M., Henn,
B., Fuhrer, O., Wicky, T., and Elbert, O.:
VulcanClimateModeling/fv3gfs-wrapper: v0.6.0 GMD release Docker Image [code], Zenodo,
<ext-link xlink:href="https://doi.org/10.5281/zenodo.4474639" ext-link-type="DOI">10.5281/zenodo.4474639</ext-link>, 2021b.</mixed-citation></ref>
      <ref id="bib1.bibx17"><?xmltex \def\ref@label{{McGibbon et~al.(2021{\natexlab{c}})}}?><label>McGibbon et al.(2021c)</label><?label fv3gfs_util?><mixed-citation>McGibbon, J., Watt-Meyer, O., Brenowitz, N. D., Clark, S., Kwa, A., Cheeseman,
M., Wicky, T., and Henn, B.: VulcanClimateModeling/fv3gfs-util: v0.6.0 GMD
release [code], Zenodo, <ext-link xlink:href="https://doi.org/10.5281/zenodo.4470011" ext-link-type="DOI">10.5281/zenodo.4470011</ext-link>, 2021c.</mixed-citation></ref>
      <ref id="bib1.bibx18"><?xmltex \def\ref@label{{McGibbon et~al.(2021{\natexlab{d}})}}?><label>McGibbon et al.(2021d)</label><?label run_directory?><mixed-citation>McGibbon, J., Watt-Meyer, O., Yang, F., and Harris, L.: Example 6-hour
directory for FV3GFS atmospheric model [data set], Zenodo, <ext-link xlink:href="https://doi.org/10.5281/zenodo.4429298" ext-link-type="DOI">10.5281/zenodo.4429298</ext-link>,
2021d.</mixed-citation></ref>
      <ref id="bib1.bibx19"><?xmltex \def\ref@label{{{Message Passing Interface Forum}(2015)}}?><label>Message Passing Interface Forum(2015)</label><?label mpi15?><mixed-citation>Message Passing Interface Forum: MPI: A Message-Passing Interface Standard
Version 3.1,
available at: <uri>https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf</uri> (last access: 21 May 2021),
2015.</mixed-citation></ref>
      <ref id="bib1.bibx20"><?xmltex \def\ref@label{{Miles et~al.(2020)}}?><label>Miles et al.(2020)</label><?label zarr?><mixed-citation>Miles, A., Kirkham, J., Durant, M., Bussonnier, M., Bourbeau, J., Onalan, T.,
Hamman, J., Patel, Z., Rocklin, M., Goenka, S., Abernathey, R., Moore, J.,
Schut, V., Dussin, R., de Andrade, E. S., Noyes, C., Jelenak, A.,
Banihirwe, A., Barnes, C., Sakkis, G., Funke, J., Kelleher, J., Jevnik, J.,
Swaney, J., Rahul, P. S., Saalfeld, S., Tran, J. T., pyup.io bot, and
sbalmer: zarr-developers/zarr-python: v2.5.0, Zenodo, <ext-link xlink:href="https://doi.org/10.5281/zenodo.4069231" ext-link-type="DOI">10.5281/zenodo.4069231</ext-link>,
2020.</mixed-citation></ref>
      <ref id="bib1.bibx21"><?xmltex \def\ref@label{{Monteiro et~al.(2018)}}?><label>Monteiro et al.(2018)</label><?label Monteiro2018?><mixed-citation>Monteiro, J. M., McGibbon, J., and Caballero, R.: sympl (v. 0.4.0) and climt (v. 0.15.3) – towards a flexible framework for building model hierarchies in Python, Geosci. Model Dev., 11, 3781–3794, <ext-link xlink:href="https://doi.org/10.5194/gmd-11-3781-2018" ext-link-type="DOI">10.5194/gmd-11-3781-2018</ext-link>, 2018.</mixed-citation></ref>
      <ref id="bib1.bibx22"><?xmltex \def\ref@label{{{OpenMP Architecture Review Board}(2020)}}?><label>OpenMP Architecture Review Board(2020)</label><?label openmp20?><mixed-citation>OpenMP Architecture Review Board: OpenMP Application Programming Interface
Version 5.0,
available at: <uri>https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-1.pdf</uri> (last access: 21 May 2021),
2020.</mixed-citation></ref>
      <ref id="bib1.bibx23"><?xmltex \def\ref@label{{Ott et~al.(2020)}}?><label>Ott et al.(2020)</label><?label Ott2020?><mixed-citation>Ott, J., Pritchard, M., Best, N., Linstead, E., Curcic, M., and Baldi, P.: A
Fortran-Keras Deep Learning Bridge for Scientific Computing, Scientific
Programming, 2020, 8888 811, <ext-link xlink:href="https://doi.org/10.1155/2020/8888811" ext-link-type="DOI">10.1155/2020/8888811</ext-link>, 2020.</mixed-citation></ref>
      <ref id="bib1.bibx24"><?xmltex \def\ref@label{{Peterson(2009)}}?><label>Peterson(2009)</label><?label f2py?><mixed-citation>Peterson, P.: F2PY: a tool for connecting Fortran and Python programs,
International Journal of Computational Science and Engineering, 4, 296,
<ext-link xlink:href="https://doi.org/10.1504/ijcse.2009.029165" ext-link-type="DOI">10.1504/ijcse.2009.029165</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx25"><?xmltex \def\ref@label{{Pressel et~al.(2015)}}?><label>Pressel et al.(2015)</label><?label Pressel2015?><mixed-citation>Pressel, K. G., Kaul, C. M., Schneider, T., Tan, Z., and Mishra, S.: Large-eddy
simulation in an anelastic framework with closed water and entropy balances,
J. Adv. Model. Earth Sy., 7, 1425–1456,
<ext-link xlink:href="https://doi.org/10.1002/2015MS000496" ext-link-type="DOI">10.1002/2015MS000496</ext-link>, 2015.</mixed-citation></ref>
      <?pagebreak page4409?><ref id="bib1.bibx26"><?xmltex \def\ref@label{{Putman and Lin(2007)}}?><label>Putman and Lin(2007)</label><?label Putman2007?><mixed-citation>Putman, W. M. and Lin, S.-J.: Finite-volume transport on various cubed-sphere
grids, J. Comput. Phys., 227, 55–78,
<ext-link xlink:href="https://doi.org/10.1016/j.jcp.2007.07.022" ext-link-type="DOI">10.1016/j.jcp.2007.07.022</ext-link>, 2007.</mixed-citation></ref>
      <ref id="bib1.bibx27"><?xmltex \def\ref@label{{{The Pallets Projects}(2019)}}?><label>The Pallets Projects(2019)</label><?label Jinja2019?><mixed-citation>The Pallets Projects: Jinja,
available at: <uri>https://jinja.palletsprojects.com/en/2.10.x/</uri> (last access: 21 May 2021), 2019.
</mixed-citation></ref><?xmltex \hack{\newpage}?>
      <ref id="bib1.bibx28"><?xmltex \def\ref@label{{Watt-Meyer et~al.(2021)}}?><label>Watt-Meyer et al.(2021)</label><?label WattMeyer2021?><mixed-citation>Watt-Meyer, O., Brenowitz, N. D., Clark, S. K., Henn, B., Kwa, A., McGibbon,
J. J., Perkins, W. A., and Bretherton, C. S.: Correcting weather and climate
models by machine learning nudged historical simulations, Earth and Space
Science Open Archive,  13, <ext-link xlink:href="https://doi.org/10.1002/essoar.10505959.1" ext-link-type="DOI">10.1002/essoar.10505959.1</ext-link>, 2021.</mixed-citation></ref>
      <ref id="bib1.bibx29"><?xmltex \def\ref@label{{Zhou et~al.(2019)}}?><label>Zhou et al.(2019)</label><?label Zhou2019?><mixed-citation>Zhou, L., Lin, S.-J., Chen, J.-H., Harris, L. M., Chen, X., and Rees, S. L.:
Toward Convective-Scale Prediction within the Next Generation Global
Prediction System, B. Am. Meteorol. Soc., 100, 1225–1243, <ext-link xlink:href="https://doi.org/10.1175/BAMS-D-17-0246.1" ext-link-type="DOI">10.1175/BAMS-D-17-0246.1</ext-link>, 2019.</mixed-citation></ref>

  </ref-list></back>
    <!--<article-title-html>fv3gfs-wrapper: a Python wrapper of the FV3GFS atmospheric model</article-title-html>
<abstract-html><p>Simulation software in geophysics is traditionally written in Fortran or C++ due to the stringent performance requirements these codes have to satisfy. As a result, researchers who use high-productivity languages for exploratory work often find these codes hard to understand, hard to modify, and hard to integrate with their analysis tools. fv3gfs-wrapper is an open-source Python-wrapped version of the NOAA (National Oceanic and Atmospheric Administration)  FV3GFS (Finite-Volume Cubed-Sphere Global Forecast System) global atmospheric model, which is coded in Fortran. The wrapper provides simple interfaces to progress the Fortran main loop and get or set variables used by the Fortran model. These interfaces enable a wide range of use cases such as modifying the behavior of the model, introducing online analysis code, or saving model variables and reading forcings directly to and from cloud storage. Model performance is identical to the fully compiled Fortran model, unless routines to copy the state in and out of the model are used. This copy overhead is well within an acceptable range of performance and could be avoided with modifications to the Fortran source code. The wrapping approach is outlined and can be applied similarly in other Fortran models to enable more productive scientific workflows.</p></abstract-html>
<ref-html id="bib1.bib1"><label>Bianchi et al.(2018)</label><mixed-citation>
Bianchi, F. A., Margara, A., and Pezzè, M.: A Survey of Recent Trends in
Testing Concurrent Software Systems, IEEE T. Soft.
Eng., 44, 747–783, <a href="https://doi.org/10.1109/TSE.2017.2707089" target="_blank">https://doi.org/10.1109/TSE.2017.2707089</a>, 2018.
</mixed-citation></ref-html>
<ref-html id="bib1.bib2"><label>Brenowitz and Bretherton(2019)</label><mixed-citation>
Brenowitz, N. D. and Bretherton, C. S.: Spatially Extended Tests of a Neural
Network Parametrization Trained by Coarse-Graining, J. Adv.
Model. Earth Sy., 11, 2728–2744, <a href="https://doi.org/10.1029/2019MS001711" target="_blank">https://doi.org/10.1029/2019MS001711</a>, 2019.
</mixed-citation></ref-html>
<ref-html id="bib1.bib3"><label>Curcic(2019)</label><mixed-citation>
Curcic, M.: A parallel Fortran framework for neural networks and deep learning,
CoRR, abs/1902.06714, available at: <a href="http://arxiv.org/abs/1902.06714" target="_blank"/> (last access: 21 May 2021), 2019.
</mixed-citation></ref-html>
<ref-html id="bib1.bib4"><label>Dalcín et al.(2008)</label><mixed-citation>
Dalcín, L., Paz, R., Storti, M., and D'Elía, J.: MPI for
Python: Performance improvements and MPI-2 extensions, J. Parallel
Distr. Com., 68, 655–662, <a href="https://doi.org/10.1016/j.jpdc.2007.09.005" target="_blank">https://doi.org/10.1016/j.jpdc.2007.09.005</a>,
2008.
</mixed-citation></ref-html>
<ref-html id="bib1.bib5"><label>Enkovaara et al.(2011)</label><mixed-citation>
Enkovaara, J., Romero, N. A., Shende, S., and Mortensen, J. J.: GPAW –
massively parallel electronic structure calculations with Python-based
software, Procedia Comput. Sci., 4, 17–25,
<a href="https://doi.org/10.1016/j.procs.2011.04.003" target="_blank">https://doi.org/10.1016/j.procs.2011.04.003</a>, 2011.
</mixed-citation></ref-html>
<ref-html id="bib1.bib6"><label>Feng(2021)</label><mixed-citation>
Feng, Y.: python-mpi-bcast,
available at: <a href="https://github.com/rainwoodman/python-mpi-bcast" target="_blank"/> (last access: 7 April 2021), 2021.
</mixed-citation></ref-html>
<ref-html id="bib1.bib7"><label>Global Engineering Documents(1991)</label><mixed-citation>
Global Engineering Documents: Fortran 90, Global Engineering Documents,
Washington, D.C., USA, 1991.
</mixed-citation></ref-html>
<ref-html id="bib1.bib8"><label>Hand and Feng(2017)</label><mixed-citation>
Hand, N. and Feng, Y.: nbodykit, in: Proceedings of the 7th Workshop on Python
for High-Performance and Scientific Computing – PyHPC'17,
ACM Press, <a href="https://doi.org/10.1145/3149869.3149876" target="_blank">https://doi.org/10.1145/3149869.3149876</a>, 2017.
</mixed-citation></ref-html>
<ref-html id="bib1.bib9"><label>Harris et al.(2020)</label><mixed-citation>
Harris, C. R., Millman, K. J., van der Walt, S. J., Gommers, R., Virtanen, P.,
Cournapeau, D., Wieser, E., Taylor, J., Berg, S., Smith, N. J., Kern, R.,
Picus, M., Hoyer, S., van Kerkwijk, M. H., Brett, M., Haldane, A., del
Río, J. F., Wiebe, M., Peterson, P., Gérard-Marchant, P.,
Sheppard, K., Reddy, T., Weckesser, W., Abbasi, H., Gohlke, C., and Oliphant,
T. E.: Array programming with NumPy, Nature, 585, 357–362,
<a href="https://doi.org/10.1038/s41586-020-2649-2" target="_blank">https://doi.org/10.1038/s41586-020-2649-2</a>, 2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib10"><label>Harris and Lin(2013)</label><mixed-citation>
Harris, L. M. and Lin, S.-J.: A Two-Way Nested Global-Regional Dynamical Core
on the Cubed-Sphere Grid, Mon. Weather Rev., 141, 283–306,
<a href="https://doi.org/10.1175/MWR-D-11-00201.1" target="_blank">https://doi.org/10.1175/MWR-D-11-00201.1</a>, 2013.
</mixed-citation></ref-html>
<ref-html id="bib1.bib11"><label>Heinzeller et al.(2020)</label><mixed-citation>
Heinzeller, D., Firl, G., Bernardet, L., Carson, L., Zhang, M., and Kain, J.: The Common Community Physics Package (CCPP): bridging the gap between research and operations to improve U.S. numerical weather prediction capabilities, EGU General Assembly 2020, Online, 4–8 May 2020, EGU2020-23, <a href="https://doi.org/10.5194/egusphere-egu2020-23" target="_blank">https://doi.org/10.5194/egusphere-egu2020-23</a>,
2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib12"><label>Heinzeller et al.(2021)</label><mixed-citation>
Heinzeller, D., Underwood, S., Firl, G., Wang, J., Liang, Z., Menzel, R.,
Robinson, T., Brown, T., Benson, R., Hartnett, E., Schramm, J., Ramirez, U.,
gbw gfdl, Carson, L., McGibbon, J., Fuhrer, O., Jess, Clark, S., Smirnova,
T., Hallberg, R., Bernardet, L., Potts, M., Zadeh, N., Olson, J., Jovic, D.,
George, R., Paulot, F., Goldhaber, S., and Li, H.:
VulcanClimateModeling/fv3gfs-fortran: GMD release [code], Zenodo,
<a href="https://doi.org/10.5281/zenodo.4470023" target="_blank">https://doi.org/10.5281/zenodo.4470023</a>, 2021.
</mixed-citation></ref-html>
<ref-html id="bib1.bib13"><label>Kermode(2020)</label><mixed-citation>
Kermode, J. R.: f90wrap: an automated tool for constructing deep Python
interfaces to modern Fortran codes, J. Phys. Condens. Matter,
<a href="https://doi.org/10.1088/1361-648X/ab82d2" target="_blank">https://doi.org/10.1088/1361-648X/ab82d2</a>, 2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib14"><label>Lin(2009)</label><mixed-citation>
Lin, J. W.-B.: qtcm 0.1.2: a Python implementation of the Neelin-Zeng Quasi-Equilibrium Tropical Circulation Model, Geosci. Model Dev., 2, 1–11, <a href="https://doi.org/10.5194/gmd-2-1-2009" target="_blank">https://doi.org/10.5194/gmd-2-1-2009</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib15"><label>McGibbon et al.(2021a)</label><mixed-citation>
McGibbon, J., Brenowitz, N. D., Watt-Meyer, O., Clark, S., Cheeseman, M., Henn,
B., Fuhrer, O., Wicky, T., and Elbert, O.:
VulcanClimateModeling/fv3gfs-wrapper: v0.6.0 GMD release [code], Zenodo,
<a href="https://doi.org/10.5281/zenodo.4474598" target="_blank">https://doi.org/10.5281/zenodo.4474598</a>, 2021a.
</mixed-citation></ref-html>
<ref-html id="bib1.bib16"><label>McGibbon et al.(2021b)</label><mixed-citation>
McGibbon, J., Brenowitz, N. D., Watt-Meyer, O., Clark, S., Cheeseman, M., Henn,
B., Fuhrer, O., Wicky, T., and Elbert, O.:
VulcanClimateModeling/fv3gfs-wrapper: v0.6.0 GMD release Docker Image [code], Zenodo,
<a href="https://doi.org/10.5281/zenodo.4474639" target="_blank">https://doi.org/10.5281/zenodo.4474639</a>, 2021b.
</mixed-citation></ref-html>
<ref-html id="bib1.bib17"><label>McGibbon et al.(2021c)</label><mixed-citation>
McGibbon, J., Watt-Meyer, O., Brenowitz, N. D., Clark, S., Kwa, A., Cheeseman,
M., Wicky, T., and Henn, B.: VulcanClimateModeling/fv3gfs-util: v0.6.0 GMD
release [code], Zenodo, <a href="https://doi.org/10.5281/zenodo.4470011" target="_blank">https://doi.org/10.5281/zenodo.4470011</a>, 2021c.
</mixed-citation></ref-html>
<ref-html id="bib1.bib18"><label>McGibbon et al.(2021d)</label><mixed-citation>
McGibbon, J., Watt-Meyer, O., Yang, F., and Harris, L.: Example 6-hour
directory for FV3GFS atmospheric model [data set], Zenodo, <a href="https://doi.org/10.5281/zenodo.4429298" target="_blank">https://doi.org/10.5281/zenodo.4429298</a>,
2021d.
</mixed-citation></ref-html>
<ref-html id="bib1.bib19"><label>Message Passing Interface Forum(2015)</label><mixed-citation>
Message Passing Interface Forum: MPI: A Message-Passing Interface Standard
Version 3.1,
available at: <a href="https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf" target="_blank"/> (last access: 21 May 2021),
2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib20"><label>Miles et al.(2020)</label><mixed-citation>
Miles, A., Kirkham, J., Durant, M., Bussonnier, M., Bourbeau, J., Onalan, T.,
Hamman, J., Patel, Z., Rocklin, M., Goenka, S., Abernathey, R., Moore, J.,
Schut, V., Dussin, R., de Andrade, E. S., Noyes, C., Jelenak, A.,
Banihirwe, A., Barnes, C., Sakkis, G., Funke, J., Kelleher, J., Jevnik, J.,
Swaney, J., Rahul, P. S., Saalfeld, S., Tran, J. T., pyup.io bot, and
sbalmer: zarr-developers/zarr-python: v2.5.0, Zenodo, <a href="https://doi.org/10.5281/zenodo.4069231" target="_blank">https://doi.org/10.5281/zenodo.4069231</a>,
2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib21"><label>Monteiro et al.(2018)</label><mixed-citation>
Monteiro, J. M., McGibbon, J., and Caballero, R.: sympl (v. 0.4.0) and climt (v. 0.15.3) – towards a flexible framework for building model hierarchies in Python, Geosci. Model Dev., 11, 3781–3794, <a href="https://doi.org/10.5194/gmd-11-3781-2018" target="_blank">https://doi.org/10.5194/gmd-11-3781-2018</a>, 2018.
</mixed-citation></ref-html>
<ref-html id="bib1.bib22"><label>OpenMP Architecture Review Board(2020)</label><mixed-citation>
OpenMP Architecture Review Board: OpenMP Application Programming Interface
Version 5.0,
available at: <a href="https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-1.pdf" target="_blank"/> (last access: 21 May 2021),
2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib23"><label>Ott et al.(2020)</label><mixed-citation>
Ott, J., Pritchard, M., Best, N., Linstead, E., Curcic, M., and Baldi, P.: A
Fortran-Keras Deep Learning Bridge for Scientific Computing, Scientific
Programming, 2020, 8888&thinsp;811, <a href="https://doi.org/10.1155/2020/8888811" target="_blank">https://doi.org/10.1155/2020/8888811</a>, 2020.
</mixed-citation></ref-html>
<ref-html id="bib1.bib24"><label>Peterson(2009)</label><mixed-citation>
Peterson, P.: F2PY: a tool for connecting Fortran and Python programs,
International Journal of Computational Science and Engineering, 4, 296,
<a href="https://doi.org/10.1504/ijcse.2009.029165" target="_blank">https://doi.org/10.1504/ijcse.2009.029165</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib25"><label>Pressel et al.(2015)</label><mixed-citation>
Pressel, K. G., Kaul, C. M., Schneider, T., Tan, Z., and Mishra, S.: Large-eddy
simulation in an anelastic framework with closed water and entropy balances,
J. Adv. Model. Earth Sy., 7, 1425–1456,
<a href="https://doi.org/10.1002/2015MS000496" target="_blank">https://doi.org/10.1002/2015MS000496</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib26"><label>Putman and Lin(2007)</label><mixed-citation>
Putman, W. M. and Lin, S.-J.: Finite-volume transport on various cubed-sphere
grids, J. Comput. Phys., 227, 55–78,
<a href="https://doi.org/10.1016/j.jcp.2007.07.022" target="_blank">https://doi.org/10.1016/j.jcp.2007.07.022</a>, 2007.
</mixed-citation></ref-html>
<ref-html id="bib1.bib27"><label>The Pallets Projects(2019)</label><mixed-citation>
The Pallets Projects: Jinja,
available at: <a href="https://jinja.palletsprojects.com/en/2.10.x/" target="_blank"/> (last access: 21 May 2021), 2019.

</mixed-citation></ref-html>
<ref-html id="bib1.bib28"><label>Watt-Meyer et al.(2021)</label><mixed-citation>
Watt-Meyer, O., Brenowitz, N. D., Clark, S. K., Henn, B., Kwa, A., McGibbon,
J. J., Perkins, W. A., and Bretherton, C. S.: Correcting weather and climate
models by machine learning nudged historical simulations, Earth and Space
Science Open Archive,  13, <a href="https://doi.org/10.1002/essoar.10505959.1" target="_blank">https://doi.org/10.1002/essoar.10505959.1</a>, 2021.
</mixed-citation></ref-html>
<ref-html id="bib1.bib29"><label>Zhou et al.(2019)</label><mixed-citation>
Zhou, L., Lin, S.-J., Chen, J.-H., Harris, L. M., Chen, X., and Rees, S. L.:
Toward Convective-Scale Prediction within the Next Generation Global
Prediction System, B. Am. Meteorol. Soc., 100, 1225–1243, <a href="https://doi.org/10.1175/BAMS-D-17-0246.1" target="_blank">https://doi.org/10.1175/BAMS-D-17-0246.1</a>, 2019.
</mixed-citation></ref-html>--></article>
