Skip to content

Setting Up MAPL Automatic Code Generator

Darian Boggs edited this page Feb 7, 2025 · 20 revisions

Overview

The MAPL Automatic Code Generator (ACG) creates Fortran include files for gridded components to:

  • add ESMF_Field instances in the SetServices phase
  • add pointer declarations in the Run phase
  • add MAPL_GetPointer calls in the Run phase

The ACG processes a text file commonly called a spec file and based on the spec file, ACG creates include files for the MAPL_Add<STATE>Spec calls for fields, where <STATE> is an ESMF_State in the spec file. The ACG creates include files declaring pointer variables and calling MAPL_GetPointer for the fields, as well. There is a separate include file for each ESMF_State, an include file for all pointer variable declarations, and an include for all MAPL_GetPointer calls.

The file specs defines the component fields in the spec file, rather than in the source code. With a properly configured spec file, the user replaces the calls in the source code below:

! SetServices
call MAPL_AddImportSpec(GC,&
    SHORT_NAME='V',& 
    LONG_NAME='northward_wind',& 
    UNITS='m s-1',& 
    DIMS			=  MAPL_DimsHorzVert, &
    VLOCATION	=  MAPL_VLocationCenter, &
    RC=STATUS)

! Run (Declare Pointers)
real, pointer :: v(:,:,:)

! Run (Get Pointers)
call MAPL_GetPointer(IMPORT, v, 'V",rc=status)

with

! SetServices
#include "import.h"

! Run (Declare Pointers)
#include "declare_pointers.h"

! Run (Get Pointers)
#include "get_pointers.h"

and a spec_file.

The ACG is best suited for fields specified by simple subroutine calls or subroutine calls in if/end if blocks with simple conditions. It does not support loops.

The procedure to use the ACG consists of three steps:

  1. Create a specs file that the ACG will use to generate source code.
  2. Edit the source code to include the files that will be generated.
  3. Edit CMakeLists.txt to generate the include files at build time.

1. Create a specs file.

spec file Format

The spec file consists of a header and a section for each ESMF_State described by the file. The headers and sections are separated by blank lines. Comment lines are allowed, and they are not considered blank lines. A comment line begins with the character #.

Header

The header lines have the format: label: value
The space between label: and value is significant.

The first line specifies the schema, and the second line specifies the gridded component to which the spec file refers. The schema version should be: 2.0.0

Header Example
schema_version: 2.0.0
component: <COMPONENT NAME>

where <COMPONENT NAME> is the name of the gridded component.

State Section

Each section contains two or more consecutive nonblank lines followed by a line for each field that is specified in that section. The section is terminated by a blank line.

The first line specifies the name of the ESMF_State for the fields that follow and has the format: category: <STATE NAME>.

The remaining lines in the section are a pipe-delimited (|) table. The first line in the table is the column names for the table, and the lines that follow are the table rows. The pipe symbol (|) is significant, but spaces are not significant. All rows in the table must have the same number of columns as the column name row, but blank values are allowed. In the case that the remaining columns are blank for a row, the pipe symbols must be present to delimit the empty values.

State Section Example
category: EXPORT
#----------------------------------------------------------------------------------------
#  FIELD                    | DIMENSIONS  |          Additional Metadata
#----------------------------------------------------------------------------------------
 NAME          | UNITS      | DIMS | VLOC | UNGRIDDED                      | LONG NAME
#----------------------------------------------------------------------------------------
 DUMASS        | kg kg-1    | xyz  | C    |                                | Dust Mass Mixing Ratio
 DUMASS25      | kg kg-1    | xyz  | C    |                                | Dust Mass Mixing Ratio
 DUCONC        | kg m-3     | xyz  | C    |                                | Dust Mass Concentration
 DUEXTCOEF     | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient
 DUEXTCOEFRH20 | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient - Fixed RH=20%
 DUEXTCOEFRH80 | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient - Fixed RH=80%
 DUSCACOEF     | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Scattering Coefficient
Full Spec File Example
schema_version: 2.0.0
component: DU

category: EXPORT
#----------------------------------------------------------------------------------------
#  FIELD                    | DIMENSIONS  |          Additional Metadata
#----------------------------------------------------------------------------------------
 NAME          | UNITS      | DIMS | VLOC | UNGRIDDED                      | LONG NAME
#----------------------------------------------------------------------------------------
 DUMASS        | kg kg-1    | xyz  | C    |                                | Dust Mass Mixing Ratio
 DUMASS25      | kg kg-1    | xyz  | C    |                                | Dust Mass Mixing Ratio
 DUCONC        | kg m-3     | xyz  | C    |                                | Dust Mass Concentration
 DUEXTCOEF     | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient
 DUEXTCOEFRH20 | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient - Fixed RH=20%
 DUEXTCOEFRH80 | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Extinction Coefficient - Fixed RH=80%
 DUSCACOEF     | m-1        | xyz  | C    | size(self%wavelengths_profile) | Dust Scattering Coefficient

Rows and Columns

The first row specifies names of arguments in the MAPL_Add<STATE>Spec subroutines. An optional column creates an if/end if block in the source code for the fields in the section. Column names are case-insensitive. Subsequent rows specify the values of the arguments and conditions for the fields.

These columns are required:

  • short_name
  • long_name
  • units
  • dims

Each row must have a nonblank value in these columns.

Abbreviations

The ACG allows for abbreviations for column names and row values. It supports these abbreviations:

Column Name Abbreviations
short_name NAME
long_name LONG NAME
add2export ADDEXP
averaging_interval AVINT
friendlyto FRIEND2
num_subtiles NUMSUBS
precision PREC
ungridded_dims UNGRID, UNGRIDDED
vlocation VLOC
condition COND

Row Value Abbreviation Column Name
MAPL_DimsVertOnly Z dims
MAPL_DimsHorzOnly XY dims
MAPL_DimsHorzVert XYZ dims
MAPL_VlocationCenter C vlocation
MAPL_VlocationEdge E vlocation
MAPL_VlocationNone N vlocation
MAPL_RestartOptional OPT restart_emit
MAPL_RestartSkip SKIP restart_emit
MAPL_RestartRequired REQ restart_emit
MAPL_RestartBoot BOOT restart_emit
MAPL_RestartSkipInitial SKIPI restart_emit

In these tables, Column Name is the name of the argument or the default name of the column.

Conditions

The condition column does not correspond to a subroutine argument. Instead, it specifies the condition for an if/end if block that the MAPL_AddSTATESpec call appears within in the generated source code. In a section of the spec file that has a condition column, all the fields will have a value for the condition, but it will be ignored for a field is the value is blank.

Asterisk in SHORT and LONG NAMES

The values in the short_name and long_name columns can be preceded by an *. When the ACG processes the spec file , the * is substituted with the component name. In this way the same file can be shared by multiples instances of a component.

Asterisk Example

For example, given this spec file:

schema_version: 2.0.0
component: DU

category: EXPORT
#-------------------------------------------------------------------------------
#  FIELD                        | DIMENSIONS  |  Additional Metadata
#-------------------------------------------------------------------------------
     NAME          | UNITS      | DIMS | VLOC | UNGRIDDED | LONG NAME
#-------------------------------------------------------------------------------
 *MASS             | kg kg-1    | xyz  | C    |           | * Mass Mixing Ratio
#-------------------------------------------------------------------------------

the generated code would be:

   call MAPL_AddImportSpec(GC,           &
       SHORT_NAME = 'DUMASS',                &
       LONG_NAME  = 'DU Mass Mixing Ratio',  &
       UNITS      = 'kg kg-1',               &
       DIMS       =  MAPL_DimsHorzVert,      &
       VLOCATION  =  MAPL_VLocationCenter,   &
       RC=STATUS  )

...

real, pointer :: dumass(:,:,:)

...

call MAPL_GetPointer(EXPORT, dumass, 'DUMASS",rc=status)

Aliases

By default, the ACG creates a pointer variable that is the same as the short_name of the field. For the ESMF_Field "MASS", the ACG would create a pointer variable mass. To overload this name, add a column ALIAS in the section for the field, and set the value of ALIAS to your preferred name for the pointer variable.

2. Edit source code.

Converting Existing Source Code

If you are writing new source code, proceed to the next subsection. link

If you are converting existing source code for a gridded component does not use the ACG, do the following:

For each field in the specs file remove:

  1. the MAPL_Add...Spec call in the SetServices subroutine
  2. the corresponding pointer declaration the Run subroutine
  3. the MAPL_GetPointer call in the subroutine

Add #include Lines

SetServices

Add a line to the SetServices subroutine for each ESMF_State name in the spec file of this form:

#include "<STATE INCLUDE>"

where <STATE INCLUDE> is the name of the include file for the ESMF_State.

Run

Add this line to the declaration section in the Run subroutine:

#include "<DECLARE INCLUDE>"

where <DECLARE INCLUDE is the name of the include file for all the pointer variables.

Add this to the statements in the Run subroutine:

#include "<GET INCLUDE>"

where <GET INCLUDE> is the name of the include file for all the pointer variables.

3. Edit CMakeLists.txt files.

Modify the CMakeLists.txt files for the gridded component and for the repository.

Edit gridded component CMakeLists.txt file.

Add the following block to CMakeLists.txt in the directory that contains the gridded component source files:

mapl_acg(${this} SPECS_FILENAME
    IMPORT_SPECS EXPORT_SPECS INTERNAL_SPECS
    GET_POINTERS DECLARE_POINTERS)

replacing SPECS_FILENAME with the name of the specs file you created. If the directory contains multiple gridded component source files, add a separate block for each gridded component source file. Each block runs the ACG and generates include files for the corresponding gridded component source file.

Edit Repository CMakeLists.txt.

At the top level directory of the Repository, add the following line to CMakeLists.txt:

include(mapl_acg)

Source Code Generation

The source code will be generated the next time you build the gridded component.

Clone this wiki locally