Subsections


6 Test Harness

The Test Harness is a flexible test control system intended to provide a thorough parameter space exploration of remapping and redistribution of distributed arrays and fields. The parameter space is defined through configuration files which are interpreted at run time to perform the desired tests.

The Test Harness is integrated into the Unit test framework, enabling the Test Harness to be built and run as part of the Unit tests. The test results are reported to a single standard-out file which is located with the unit test results.

The motivation for employing such a hierarchy configuration files is to allow a high degree of customization of the test configurations by combining individual specification files. Complex combinations of test cases are easily specified in high level terms. Each class will have its own collection of specification files tailored to the needs of that class.

6.1 Specifying Test Harness Tests

The test harness code consists of a single executable that uses a customizable configuration files which are located within the <classdir>/tests/harness_config directory of each supported class; currently only ESMF_ARRAY and ESMF_FIELD.

There are three ways to invoke the test harness, as an integral part of running unit tests; as a stand-alone test invoked through gmake; and as a standalone test invoked through the command line.

Running the harness along with the unit tests provides frequent regression testing of the redistribution and regridding features.

Running the test harness in stand alone mode using gmake is useful for isolating faults in failed test cases.

Running the test harness from the command line provides the most control over Test Harness execution. Understanding the underlying program allows the developer full access to test harness features. This is useful in developing makefiles, scripts, and configuration files.

6.2 Running Test Harness Tests as Part of Unit Tests

When running as an integral part of the unit tests, the makefile contained in the <classdir>/tests directory of each supported class is executed through the run_unit_tests target. As part of this target, the makefile selects the desired test harness target using a class specific environment variable (e.g. ESMF_TESTHARNESS_FIELD). A default case is provided in case the environment variable variable is not set.

The environment variables currently defined are:

The targets currently supported for the ESMF_TESTHARNESS_ARRAY variable are:

The targets currently supported for the ESMF_TESTHARNESS_FIELD variable are:

Each target selects the desired sequence of test cases for that target. For example, a series of test cases could be developed to run on different days providing partial test coverage on a particular day, but complete coverage over a week. In this case, each day would have a separate target and the environment variable would be set for that day's test case.

An example of a test harness appears below.

RUN_ESMF_TestHarnessField_1:
	\$(MAKE) TESTHARNESSCASE=field_1 NP=4 run_test_harness

In this example, the test harness target is RUN_ESMF_TestHarnessField_1. This target will execute a single test harness test case. Additional lines can be added if additional steps are desired. The next section will describe the details of invoking a test case.

6.3 Invoking a Single Test Harness Test Case Using gmake

A single test harness test case can be invoked from the <classdir>/tests directory through the make command with the local parameters TESTHARNESSCASE and NP with the run_test_harness target.

For example,

gmake TESTHARNESSCASE=field_1 NP=4 run_test_harness
will run the test harness test case, field_1 on 4 processors.

Each test case is defeined by a series of configuration files in the <classdir>/tests/harness_config directory. All of the configuration files for a particular test case will be prefixed with <casename>_ where <classname> is a unique name for the test. The top level configuration file will have a suffix of _test.rc. Thus, the top level configuration file for the field_1 test case will be field_1_test.rc.

The next section describes invoking the Test Harness from the Command Line.

6.4 Invoking a Single Test Harness Test Case from the Command Line

The Test Harness is built by invoking gmake from the $ESMF_DIR/src/test_harness/src directory or by building all the unit tests. This creates the exececutable file ESMF_TestHarnessUTest in the currently selected test directory.

To run the executable, enter:

\<run path\>ESMF\_TestHarnessUTest \<cmd args\>
where,
\<run path\> is the path to the executable,
and \<cmd args\> are the optional command arguments

The cmd args are as follows:
-path \<config path\>
-case \<case filename\>
-xml \<xml filename\>
-norun

The path argument sets the path to the configuration files. All of the configuration files for a testcase must reside in the same directory. If this argument is not present, the current working directory will be used as the path.

The case argument is the name of the top level configuration file. This is described in a later section of this document. If this argument is not present, test_harness.rc will be used.

The xml argument instructs the test harness to generate an XML test case summary file in the current working directory.

The norun argument instructs the test harness not to run the test cases. The configuration files will be parsed and if selected, an XML file will be generated. The XML file can be post-processed to generate human readable test configuration summary reports.

If running under mpi, you would need to prefix this command with the proper mpirun command.

The next section describes the format of the top level resource file.


6.5 Top Level Configuration File

As mentioned above, the top level configuration file will be located in the <classdir>/tests/harness_config directory and named <casename>_test.rc.

The top level configuration file specifies the test class, the format for reporting the test results, and the location and file names containing the problem descriptor files.

Originally, the test harness had a single configuration file for each class and supported only two test cases, a non-exhaustive case and an exhaustive case. This turned out to be too restrictive and test cases are now selected through environment variables. Unfortunately, some of the old constructs remain until the obsolete feature is removed.

Currently, the test harness only uses the non-exhaustive test case for each configuration file. So, referencing the example below, only the nonexhaustive tag is actually used by the test harness.

Also note, that comments are preceded by the # sign, that single parameter values follow a single colon : punctuation mark, while tables of multiple parameter values follow, and are terminated by, a double set of colon :: punctuation marks. This file is read by the ESMF_Config class methods, therefore must adhere to their specific syntax requirements. The entries can be in any order, but the name tags must be exact - including CAPITALIZATION. While it is not strictly necessary, the file names are enclosed in quotation marks, either single or double, to guarantee they are read correctly.

# Field test Harness Config file

# test class
test_class: FIELD 

# report a summary of the test configurations before actually conducting tests
setup_report: TRUE

# test result report - options are:
# test_report: FULL  - full report presenting both success and failure configs
# test_report: FAILURE - report only failure configurations
# test_report: SUCCESS - report only successful configurations
# test_report: NONE - no report
test_report: FAILURE

# descriptor file for the nonexhaustive case
nonexhaustive::
   'nonexhaustive_descriptor.rc'
::   # end of list

# descriptor files for the exhaustive case (obsolete, but keep in for awhile)
exhaustive::
   'exhaustive_descriptor.rc'
:: # end of list

The argument for the tag test_class: specifies the ESMF class to be tested. Here it is Field.The tag setup_report: specifies if a setup report is sent to the test report. The tag test_report: specifies the style of report to be constructed. This report is appended to the standard-out file which is located with the Unit test results. The tag nonexhaustive:: delimits a table which contains the file names of problem descriptor files pertaining to the current test configuration.

The tag exhaustive is obsolete and will be removed when time permits. It has been replaced with the Test Harness environment variables which can select the desired test case from the available portfolio.


6.5.1 Problem descriptor file

The problem descriptor files contain descriptor strings that describe the family of problems with the same memory topology, distribution, and grid association. The files also contain the names of specifier files which complete the descriptions contained within the descriptor strings. This structure allows a high level of customization of the test suite.

The problem descriptor file contains only one table, again conforming to the ESMF_Config class standard. The contents of the table must be delimited by the tag problem_descriptor_string::. The first element on the line, enclosed by quotes, is the problem descriptor string itself. Since the descriptor strings contain gaps and special characters, it is necessary to enclose the strings in quotation marks to guarantee proper parsing. The problem descriptor table may contain any number of descriptor strings, up to the limit imposed by the ESMF_Config class, each on a new line. Lines can be continued by use of an ampersand & as a continuation symbol at the beginning of any continued line. The syntax of the problem descriptor string follows the field taxonomy syntax. The following is a basic redistribution example.

# Basic redistribution example
#####################################
problem_descriptor_string::
'[B1G1;B2G2] --> [B1G1;B2G2]'  -d Dist.rc -g Grid.rc 
'[B1G1;B2G2] --> [B1G2;B2G1]'  -d DistGrid.rc 
 & otherDistGrid.rc yetanotherDistGrid.rc
 &  -g Grid.rc anotherGrid.rc  
::   # end of list
In the above example, the two problem descriptor strings specify that a redistribution test is to be conducted, indicated by the syntax ->, between a pair of rank two blocks of memory. Following the problem descriptor string, are multiple flags and the names of specifier files. Each flag indicates a portion of the configuration space which is defined by the contents of the indicated specifier files.
argument definition
-d DELayout/DistGrid specification
-g Grid specification
The filenames following a flag are used to specify the values for the parameter associated with that flag. The specified values from each file are combined to define that parameter's span of values. All the files associated with all the flags are combined to define the full ensemble of tests. The first problem descriptor string in the example indicates that the ensemble of distribution configurations to be tested are specified by the configurations contained within the file Dist.rc. Similarly, the range of grid configurations are specified within the single file Grid.rc. For the second problem descriptor string, the ensemble of distribution configurations to be tested are specified by the union of configurations contained within the three files DistGrid.rc, otherDistGrid.rc, and yetanotherDistGrid.rc. While in the first case, the range of grid configurations is specified by the single file Grid.rc, the second case adds the configurations found in anotherGrid.rc to the ensemble.

6.5.2 Problem descriptor string syntax

The problem descriptor string is contained in the problem descriptor file and describes a class of tests to be conducted. The basic syntax describes a contiguous chunk of memory spanned by some sort of logically rectangular indexing, where the left most index varies fastest in memory. Each semicolon delineated entry is associated with a native array dimension. The index locations are replaced by signifiers that express associations and distributions of the memory through the use of short descriptors.

For example $[ G1 \; ; G2 ]$ indicates that a 2D logically rectangular block of memory is associated with a 2D grid in its natural order. The signifier $G$ represents an undistributed tensor grid. Reversing the grid signifiers $[ G2; G1 ]$ indicates that the fastest varying dimension is instead associated with the second grid dimension. Specific information about the grid, such as its size, type, topology are left to be defined by the specifier files. It is the associations between memory and the grid that are stressed with this syntax.

To distribute the grid, a distribution signifier is needed. The block distribution of each memory dimension is indicated by the signifier $B$. Therefore $[B1 \; G1; \; B2 \; G2; \; G3]$ signifies that a 3D logically rectangular block of memory, which has a 3D associated grid, is distributed in its first two dimensions, and not its third.

6.5.2.1 Grid syntax

As we have already seen, the symbol $G$ in the problem descriptor string indicates that a dimension of a tensor grid is associated with a memory location. Alternatively, an unstructured grid is indicated with the symbol $U$.

As an example, consider a block of memory. To associate a tensor grid with specific dimensions of that block, the symbol $G$ is used with a numerical suffix to indicate a specific dimension of the grid. The specific aspects of this grid are left undefined at this point, only the fact that a particular dimension of a grid is associated with a particular dimension of the memory block is implied by the grid syntax.

The complete syntax for a tensor grid specification is $G i_g \; + H \{ \char93  : \char93  \}$ where

The symbol to indicate a halo is appended to the grid description through use of a $+$ sign. Its absence indicates that there is no halo. Currently, only symmetric haloes are supported.

To illustrate the use of this syntax consider the following example.

 [ G1 ; G2 + H{1:1} ]
This string indicates that each memory location of a 2D block of memory is associated with a grid dimension. The first memory location with the first grid dimension, and the second memory location with the second grid dimension. In addition the second memory index has an asymmetric halo of size one at the low end, and size 1 at the high end.

At times a memory location might have no grid association. The symbol $\ast$ is used in this case as a place holder. For example,

 [ G2 ; G1 ; * ]
indicates that only the first two memory locations are associated with grid dimensions. The symbol $\ast$ located in the last memory location is a placeholder that indicates that location in memory has no associations. We will see later that the $\ast$ can be used to indicate that a memory location has both no grid and no distribution association.

In this example, the grid association has been reversed from from its natural order. The first memory location is associated with the second grid dimension, and the second memory location with the first grid dimension.

6.5.2.2 Distribution syntax

The distribution syntax describes how a contiguous chunk of memory is distributed among the DEs. The syntax is analogous to the grid description syntax.Three styles of memory distribution are supported;
simple block
$B \; i_D$; where $i_D$ is the distribution space axis.
full block-cyclic
$C \; i_D$; where $i_D$ is the distribution space axis.
arbitrary
$A$
Assuming a two dimensional distribution, the expression $[ B1 \; G1; \; B2 \; G2 ]$ indicates that the two dimensional logically rectangular block of memory is; The order of the distribution signifiers can be reversed just as with the grid association.

As was mentioned before, the symbol $\ast$ is used as a place holder to indicate a lack of association. If the third memory location of an undistributed block of memory has no grid association, it would look like this;

[ G1; G2; * ]
Alternatively if the first two dimensions of a block of memory are distributed, but all three have associated grid dimensions it would take the form;
[ B1 G1; B2 G2; * G3 ]
An example of where the third memory location would have a grid association, but no distribution, is the case where the domain has been decomposed along the horizontal, but not the vertical. This is common for a 3D field such as the ocean or atmosphere.

Lastly, if the last memory location has no associations, it would look like;

[ B1 G1; B2 G2; * * ]
The purpose of the $\ast$ symbols is increase readability by acting as a place holder. An illustrative example of this memory configuration is a two dimensional spatial field with multiple species or tracers represented by the third dimension.

6.5.2.3 Transformation method

The action of redistribution and remapping are signified by the symbols $-- \!\!\! >$ and $=\chi=>$ respectively, where $\chi$ refers to a character key representing a specific interpolation method. The currently supported interpolation methods are $B$ for first order bilinear and $P$ for the patch recovery method, which provides a smoother first order surface, which can meaningly differentiated. Future implementations will include $C$, for first order conservative, $S$ for second order bilinear, and $N$ for nearest neighbor. The character $X$ is reserved for unknown or user provided methods.

$\chi$ Action
B first order bilinear interpolation
P patch recovery interpolation
   
C first order conservative interpolation
S second order conservative interpolation
N nearest neighbor distance weighted average interpolation
X unknown or user provided interpolation

The problem descriptor string

      [B1 G1; B2 G2 ] --> [B1 G1; B2 G2 ]
indicates an ensemble of redistribution problems where a 2D distributed source field, associated with a 2D grid, is redistributed into a new 2D destination distribution.

Alternatively the example

      [ B1 G1; B2 G2 ] =C=>  [ B1 G1; B2 G2 ]
indicates the interpolation of one distributed 2D gridded field to another 2D grid using a first order conservative method. The interpolation method of first order conservative is indicated by placing a character $C$ in between a pair of equal $=$ signs.

6.5.2.4 Staggering syntax (Not currently implemented)

In addition to the default grid description, the stagger of the associated grid can be indicated by appending a key with an @ sign to the end of the block memory syntax. Since the stagger relates to the whole grid and not individual components of the grid, it is natural for it to be located outside of the block memory syntax $[ \cdots ]$.
      [ B1 G1; B2 G2 ] @{#,#}
The key consists of values enclosed by a pair of brackets $\{ \cdots \}$. The rank of these values, equals the rank of the associated grid. Thus in the above example, there are two values indicating the stagger since the grid is of rank two.

The stagger location key represents the location of a field with respect to the cell center location. It is indicated by relative cartesian coordinates of a unit square, cube etc. To illustrate this further, consider the example of a 2D grid. The cell is represented by a unit square with the xy axis placed at its center, with the positive x-axis oriented East and the positive y-axis oriented North. The actual values are suppressed, only the directions $+$, and $0$ are used. This geometry is for reference purposes only, and does not literally represent the shape of an actual cell.

The cell center, located at the origin of the cell, is indicated by $\{ 0,0 \}$. The corner of the cell is indicated by $\{ +,+ \}$, where the ones have been dropped to just leave the plus signs. The cell face normal to the X axis (right wall) is indicated by $\{ +, 0 \}$, while the face normal to the Y axis ( top wall) is indicated by $\{ 0,+ \}$. This approach generalizes well to higher dimensions.

argument definition
Center { 0,0 }
Corner { +,+ }
Face normal to X axis {+,0 }
Face normal to Y axis {0,+ }

With these four locations, it is possible to indicate the standard Arakawa grid staggerings. A key of $\{ 0,0 \}$ would be equivalent to an Arakawa A-grid, while a key of $\{ +,+ \}$ would represent an Arakawa B-grid. Components of the C and D grids would be indicated by wall positions $\{ +, 0 \}$ and $\{ 0,+ \}$.

Grid Stagger coordinates
A-grid { 0,0 }
B-grid { 1,1 }
C-grid & D-grid { 0,1 } and { 1,0}
Therefore a key of $\{ 0,0 \}$ in the previous example would indicate that the stagger is located at the cell center location, or the A-grid. Typically the stagger coordinates are suppressed for the A-grid.

For example, the string

[B1 G1; B2 G2 ] =C=> [B1 G1; B2 G2 ] @(+,+)
indicates that a collection of regridding tests are to be run where a block distributed two dimensional field, is interpolated from one two dimensional grid onto a second two dimensional grid, using a first order conservative method. The source field data is located at the cell centers (an A-grid stagger location) and the destination field is to be located at north east corner (a B-grid stagger location). Additional information about the pair of grids and their distributions must be specified to run an actual test.

This process generalizes to higher dimensions. Consider

[B1 G1; B2 G2 ; G3 ] =C=> [B1 G1; B2 G2 ; G3 ] @(+,+,+)
indicates that a collection of regridding tests are to be run between a 3D source grid (cell centered) and a 3D destination grid where the field stagger location is the upper corner of the 3D cell (B-grid horizontally and top of the cell vertically).

A further discussion on grid staggers can be found in section on the ESMF Grid class in the Reference manual.

6.5.3 General Data Structures

It is possible to represent more general data structures which cannot be described as simple logically rectangular blocks of memory. These embedded structures are represented by combining multiple contiguous data chunks separated by commas.

For example, in models with nested grids or which employ multi-grid methods, it is useful to have an indexed structure of logically rectangular blocks of memory, where each block is generally a different shape and size. Such a structure can be represented with parentheses as delimiters, such as

   ( tile , [ B1 G1; B2 G2 ] )
Here we have a collection of 2D blocks of memory, each block being associated with a 2D grid and being distributed in both dimensions.

6.5.4 Specifier files

The problem descriptor strings are augmented by two types of specifier files which complete the description of the test configuration. The specifier files indicate which members of the family described by the problem descriptor string are to be tested. The two types of specifier files define the grid and the distribution information needed to completely define a test. The two specifier files define information such as the type, size, and coordinates of the grid, the test function to be interpolated or redistributed, and the size of the distribution.

The nature of the grid specifier file varies depending on whether the test is a redistribution or a regridding. A redistribution test takes a field associated with a grid and rearranges it in processor space. So while a source and destination distribution are needed, only a single grid is necessary to conduct the test. A regridding test, on the other hand, takes a field associated with a source grid and interpolates it to a destination grid thaty is also part of a field. In this case both source and destination grids are needed. It is also assumed that a source and destination distribution is specified.

Redistribution source grid
  source & destination distribution
Regridding source & destination grids
  source & destination distribution


6.5.5 Grid Specification

For the purposes of the test harness, a grid is completely defined in terms of its type, size, coordinates, and units. From this information either a rectilinear or a curvilinear grid is generated.

The first step of the grid generation is to generate a rectilinear grid of specified size, range of coordinates, and either uniform or gaussian spacing between the coordinates. If only a rectilinear grid needed, the grid generation is finished. If a curvilinear grid is desired, the rectilinear grid is taken as a base grid and its coordinates are smoothly stretched and/or shrunk according to an analytical function, to produce a curvilinear mesh according.

6.5.5.1 Curvilinear Grid Coordinate Generation (For Future Implementation)

If a curvilinear grid is desired, the rectilinear grid is taken as a base grid and its coordinates are smoothly stretched and/or shrunk according to an analytical function, to produce a curvilinear mesh according. The algebraic grid generation takes the form

\begin{eqnarray*}
X_{ij} &=& \hat{x}_{i} + \epsilon \Delta x \Gamma_{x}(x_{i},y_...
...{ij} &=& \hat{y}_{j} + \epsilon \Delta y \Gamma_{y}(x_{i},y_{j})
\end{eqnarray*}


where the new curvilinear coordinates $X_{ij}$ and $Y_{ij}$ are functions of the original rectilinear grid coordinates $\hat{x}_{i}$ and $\hat{y}_{j}$, a small parameter $0 < \epsilon < 1$, the smallest mesh spacings $\Delta x$ and $\Delta y$, and an analytical function of the coordinates $\Gamma$. Four forms of $\Gamma$ are supported, a contacted grid, an expanded grid, a symmetric sine perturbed grid, and an asymmetric sine perturbed grid.

key word formula $\Gamma(x_{i},y_{j})$
contracting $\Gamma_{x}(x_{i},y_{j}) = -(x_{i}/L_{x})(1-x_{i}/L_{x})(0.5-x_{i}/L_{x} )(y_{j}/L_{y})(1-y_{j}/L_{y})$
  $\Gamma_{y}(x_{i},y_{j}) = -(y_{j}/L_{y})(1-y_{j}/L_{y})(0.5-y_{j}/L_{y} )(x_{i}/L_{x})(1-x_{i}/L_{x})$
expanding $\Gamma_{x}(x_{i},y_{j}) = +(x_{i}/L_{x})(1-x_{i}/L_{x} )(0.5-x_{i}/L_{x} )(y_{j}/L_{y})(1-y_{j}/L_{y})$
  $\Gamma_{y}(x_{i},y_{j}) = +(y_{j}/L_{y})(1-y_{j}/L_{y})(0.5-y_{j}/L_{y} )(x_{i}/L_{x})(1-x_{i}/L_{x})$
symmetric_sin $\Gamma_{x}(x_{i},y_{j}) = \sin(4 \pi x{i}/L_{x}) \cos(6 \pi y_{j})/L_{y})$
  $\Gamma_{y}(x_{i},y_{j}) = \sin(4 \pi x{i}/L_{x}) \cos(6 \pi y_{j})/L_{y})$
asymmetric_sin $\Gamma_{x}(x_{i},y_{j}) = \sin(4 \pi x{i}/L_{x}) \cos(6 \pi y_{j})/L_{y})$
  $\Gamma_{y}(x_{i},y_{j}) = \sin(4 \pi y{j}/L_{y}) \cos(6 \pi x_{i})/L_{x})$

These four choices for $\Gamma$ equate into four options for analytically generated curvilinear grids.

Examples of these four curvilinear grid options are plotted in figure [*].

Figure: The four options for smooth curvilinear grids; clockwise from the top left corner, a contacted grid, an expanded grid, a symmetric sine perturbed grid, and an asymmetric sine perturbed grid.
\scalebox{0.3}{\includegraphics{Harness_ContractedGrid} } \scalebox{0.3}{\includegraphics{Harness_ExpandedGrid} }
\scalebox{0.3}{\includegraphics{Harness_SymmetricGrid} } \scalebox{0.3}{\includegraphics{Harness_AsymmetricGrid} }

This adds up to a total of 2 types of rectilinear grids (uniform and gaussian), each with three options (no connection, spherical pole connection, and a periodic option). A large variety of grids can be formed by mixing and matching the grid types and options. For example a standard latitude-longitude grid on a sphere is formed by using the pair of grid types uniform_periodic and uniform_pole. A gaussian grid is formed with uniform_periodic and gaussian_pole. And a regional grid on a sphere, without periodicity, with uniform and uniform. A summary of the rectilinear grid types is given below.

Rectilinear grid options
grid type modifier
UNIFORM none
  _POLE
  _PERIODIC
GAUSSIAN none
  _POLE
  _PERIODIC

The various curvilinear grid types are created in the same way of mixing and matching grid type options. A regional expanding grid is formed using the grid types expanding and expanding. Likewise a rotated regional grid is created by using the grid types rotation_15degrees and rotation_15degrees to indicate the grid type. A summary of the curvilinear grid types is given below.

Curvilinear grid options
grid type modifier
CONTRACTING none
  _POLE
  _PERIODIC
EXPANDING none
  _POLE
  _PERIODIC
SYMMETRIC_SIN none
  _POLE
  _PERIODIC
ASYMMETRIC_SIN none
  _POLE
  _PERIODIC
rotation_15degrees none
rotation_30degrees none
rotation_30degrees none
It should be noted that the rotated grid type only supports non-connected domains, and therefore has no option for _pole and _periodic connectivity.

6.5.5.2 Specifier file syntax for redistribution

Since a redistribution test takes either an array or a field and rearranges it in processor space, the test requires only a single grid for the source and destination. The information required is:
parameters to define a grid for redistribution
Grid rank
Grid dimensions
Range of the coordinate axis
Coordinate units

This is the information is provided by the redistribution grid specifier file. An example of a redistribution grid specifier file is provided below.

# grid.rc
########################################
map_type: REDISTRIBUTION

# regular rectilinear Grid specification 
map_redist::
#rank spacing  size  range (min/max)  units
#
2  'UNIFORM'  120  -3.14159  3.14159  'RAD'   'UNIFORM'  90  -1.57  1.57  'RAD'   
#
2  'UNIFORM'  400  -180   180  'DEG_E'  'GAUSSIAN'  200 -88   88   'DEG_N'  
::

The first piece of information required for the file is the map_type key. It should be set to REDISTRIBUTION to indicate that it is intended to define grids for a redistribution test. Next is a configuration table which specifies multiple grids. The specification can be stretched over multiple table lines by use of the continuation symbol $\&$. The order of information is as follows:

parameters to define a grid for redistribution
Grid rank
Grid axis type
Grid size
Range of the coordinate axis
Coordinate units

There are two 2D grids specified in the file. The first is a standard uniformly spaced latitude-longitude grid, where none of the grid coordinates has any topological connections. The horizontal coordinates are in radians. The second 2D grid is a gaussian spherical grid. The gaussian grid has a spherical topology and is in degrees.

Four types of coordinate units are supported; degrees, radians, meters and kilometers. Each has multiple equivalent key words.

Supported units
name key word
Degrees DEGREES
  DEG
  DEG_E
  DEG_N
Radians RADIANS
  RAD
Meters METERS
  M
Kilometers KILOMETERS
  KM

6.5.5.3 Specifier file syntax for regridding

The process of regridding takes a distributed test field from a source grid and interpolates it to a distributed destination grid. Therefore it requires information specifying both a source and destination grid, and an explicit test function to interpolate. The information required is:
parameters to define a grid for remapping
source and destination grid rank
source and destination grid axis type
source and destination grid dimensions
source and destination range of coordinate axis
source and destination coordinate units
test function with parameters to interpolate

This information is provided by the regridding grid specifier file. An example of a regridding grid specifier file is provided below.

# grid.rc
########################################
map_type: REGRID

################################################################################
# grid | source | grid    |    grid   | grid  | units | destination | 
# rank |  tag   | spacing | dimension | range |       |    tag      |
################################################################################
# Grid specification for regridding

#rank spacing  size  range (min/max)  units
map_regrid::
# example of a pair of 2D periodic grids 
2   SRC    UNIFORM_PERIODIC   120   -3.14159  3.14159  RADIANS   
&              UNIFORM_POLE             90    -1.57        1.57        RADIANS   
&   DST    UNIFORM_PERIODIC   120  -180      180             DEG_E   
&              GAUSSIAN_POLE           88    -88        88             DEG_N   
&   FUNCTION    CONSTANT   2.1 0.1  END
::

The first piece of information required for the file is the map_type key. It should be set to REGRID to indicate that it is intended to define grids for a regridding test. Next is a configuration table which specifies multiple pairs of grids. The specification can be stretched over multiple table lines by use of the continuation symbol $\&$. The order of information is as follows:

parameters to define a grid for reremapping
Grid rank
Source grid axis type
Source grid size
Source range of the coordinate axis
Source coordinate units
Destination grid axis type
Destination grid size
Destination range of the coordinate axis
Destination coordinate units
Test function and parameters

The regridding grid specifier file contains a pair of 2D grids. The source grid is a standard latitude-longitude grid on a spherical topology. The destination grid is a spherical gaussian grid also on a spherical topology. The source grid is in radians, while the destination grid is in degrees. The test function is a periodic function of the grid coordinates.

The one new piece of information for the regridding specifier files are the predefined test functions. The test functions provide a physical field to be interpolated and are generated as an analytical function of the grid coordinates. Supported options include:

Test functions  
name function parameters
constant set value at all locations value, relative error
coordinate set to a multiple of the coordinate values scale, relative error
spherical harmonic periodic function of the grid coordinates amplitudes and phases, relative error

The CONSTANT value test function sets the field to the value of the first parameter following the name. The second value is the relative error threshold. For example, the test function specification:

&   FUNCTION    CONSTANT   2.1 0.1  END

indicates that the field is set to the constant value of $2.1$, with a relative error threshold of $0.1$. This test function specification holds for grids of any rank.

The COORDINATE test function sets the field to the value of the one of the grid coordinates multiplied by the value of the first parameter following the name. The second value is the relative error threshold. For example, the test function specification:

&   FUNCTION    COORDINATEX   0.5 0.1  END

indicates that the field is set to one half of the X coordinate values. For a 2D grid the coordinate options include COORDINATEX and COORDINATEY. For a 3D grid there is the additional option of COORDINATEZ. Again, the relative error threshold is $0.1$. This test function specification holds for grids of any rank.

The SPHERICAL_HARMONIC test function sets the field to the periodic harmonic function $\vert a+b\vert + a*\cos(2\pi * k_x * x/L_x ) + b*\sin(2\pi * l_y * x/L_y )$. The parameters follow the order

&   FUNCTION    SPHERICAL_HARMONIC  a   kx  b   ly    rel_error  END

This test function specification is only valid for 2D grids.


6.5.6 Distribution Specification

The purpose of the distribution specification is to characterize the distribution of the grid. It differs from the grid specification in that it is designed to specify the distribution as both absolute values such as $2 \times 3$ PETs as well as in relative terms based on fractions of the total number of PETs. This second option is intended to allow the distribution space to scale with changing machine resources without having to change the distribution specification file.

Here is an example of a distribution specification file for block and block cyclic distributions.

##################################################
# descriptive | source | source | operator | destination | dest | operator | end
# string      |  tag   |  rank  |  & value |     tag     | rank | & value  | tag
##################################################

# table specifing 2D to 2D distributions
distgrid_block_2d2d::

# example with two fixed distribution sizes
 '(1,2)-->(2,1)'  'SRC' 2  'D1==' 1  'D2==' 2  'DST' 2  'D1==' 2  'D2==' 1  'END'  

# example with one fixed and one variable distribution size
 '(1,n)-->(n,1)'  'SRC' 2  'D1==' 1  'D2=*' 1  'DST' 2  'D1=*' 1  'D2==' 1  'END'  

# example with variable distribution sizes
 '(2n,n/2)-->(n/2,2n)'  'SRC'  2  'D1=*'  2    'D2=*'  0.5  
 &                      'DST'  2  'D1=*'  0.5  'D2=*'  2     'END'

# another example with variable distribution sizes
 '(2n,n/2)-->(2n,(n/2)-1)'  'SRC' 2  'D1=*' 2  'D2=*'  0.5  
 &                          'DST' 2  'D1=*' 2  'D2=*'  0.5  'D2=+' 1   'END'
::

# table specifing 3D to 3D distributions
distgrid_block_3d3d::

# example with two fixed distribution sizes
 '(1,2,1)-->(2,1,1)'  'SRC' 3  'D1==' 1  'D2==' 2  'D3==' 1  
 &                    'DST' 3  'D1==' 2  'D2==' 1  'D3==' 1  'END'  
::
The contents of the file are tables which specify pairs of distributions. Each table specifies a particular rank of distributions. The first table consists of 2D to 2D distributions, while the second table consists of a 3D to 3D pair of distributions. The order of information is as follows:
parameters to define a grid distribution
Descriptive string
Source key
Source distribution rank
Source distribution axis and size for each dimension of the distribution
Destination key
Destination distribution rank
Destination grid size
Destination distribution axis and size for each dimension of the distribution
Termination key
The first example in the table starts with a string used by the report as a brief description of the distribution. Such as $(1,2)-->(2,1)$ which indicates a source distribution of $1 \times 2$ and a destination distribution of $2 \times 1$. Next comes a key word, either SRC or DST to indicate the beginning of the source and destination descriptions, respectively. Following each tag is a specification of the distribution. In the first case a fixed source distribution is specified by the entries $D1==1$ and $D2=2$. This indicates that the source distribution is fixed to be $1 \times 2$, provided that the test is running with at least two processors. Likewise the destination distribution is fixed to $2 \times 1$.

The second example, illustrates how to indicate a scalable distribution. Again the entry $D1==1$ indicates that the first dimension of the distribution is set to one, but the entry $D2=*1$ has a different meaning. It takes the total number of PETs NPETS and scales it by one. Therefore the source distribution becomes $1 \times NPETS$. It automatically scales with the number of PETs. Likewise, the destination distribution is set to $NPETS \times 1$.

The third example is completely dynamic. Since both $D1$ and $D2$ are scalable, each dimension starts with $N$ PETs, where $N$ is the square root of $NPETS$ rounded down to the nearest integer. Therefore $N\times N \leq NPETS$. So if $NPETS=4$, Then $N=2$. If $NPETS=6$ then $N$ still equals $4$. This base value is then modified by the indicated entries. In this case the source distribution is $2 N \times 1/2 N$, since the tag $D1=* 2$ indicates that first dimension is the result of the base value being multiplied by two, and the second dimension is the result of the base value being multiplied by one half. Likewise, the destination distribution is set to $1/2 N \times 2N$, no matter the number of $NPETS$.

For a rank three scalable distribution, $N$ is the cube root of NPETS rounded down to the next integer. And so on for higher rank distributions.

The fourth example illustrates the last option in the syntax. Again, since the distribution specifies two scalable distributions, $N$ is the square root of $NPETS$ rounded down to the nearest integer. The source distribution is exactly the same as in the third example, but destination distribution has a new entry $D2=+ 1$. The first dimension of the destination distribution is set to $2N$ by the entry $D1=* 2$. the second dimension is first set to $1/2N$ by the entry $D2=* 0.5$, but then modified further to $(1/2)(N) +1$ by the entry $D2=+ 1$. The resulting destination distribution is $2N \times (1/2)(N) +1$.

The syntax for modifying the size of the distribution space combines according to the order of the operations. The entries $D2=* 0.5$ and $D2=+ 1$, are not identical to $D2=+ 1$ and $D2=* 0.5$, which would result in a dimension of size $(1/2)(N+1)$.

Three operations are supported:

Distribution specification operations  
D# == specify a fixed value
D# =* multiply a base value by a constant
D# =+ add a constant to the base value

6.5.7 Class Specification

The class specific specifier file is current unused, but is made available for future test expansion.

6.6 Reporting test results

The test harness offers the option of producing a human readable report on the test results. The report consists of a concise summary of the test configuration along with the test results. The test configuration is described in terms of the Field Taxonomy syntax and user provided strings. The intent is not to provide a exhaustive description of the test, but rather to provide a useful description of the failed tests.

Consider a problem descriptor string consisting of two descriptor strings describing an ensemble of remapping tests.

[ B1 G1; B2 G2 ] =C=> [ B1 G1; B2 G2 ] @{+,+}
[ B1 G1; B2 G2 ] =B=> [ B1 G1; B2 G2 ] @{+,+}

Suppose the associated specifier files indicate that the source grid is rectilinear and is 100 X 50 in size. The destination grid is also rectilinear and is 80 X 20 in size. The remapping is conducted from the A-grid position of the source grid to the B-grid stagger of the destination grid. Both grids are block distributed in two ways, 1 X NPETS and NPETS X 1. And suppose that the first dimension of both the source and destination grids are periodic. If the test succeeds for the conservative remapping, but fails for one of the first order bilinear remapping configurations, the reported results could look something like

SUCCESS: [B1 G1; B2 G2 ] =C=> [B1 G1; B2 G2 ] @{+,+}
FAILURE: [B1{1} G1{100}+P; B2{npets} G2{50} ] =B=> 
                         [B1{1} G1{80}+P; B2{npets} G2{20} ] @{+,+}
     failure at line 101 of test.F90
SUCCESS: [ B1{npets} G1{100} +P; B2{1} G2{50} ] =B=> 
                         [ B1{npets} G1{80}+P; B2{1} G2{20} ] @{+,+}
Notice that the problem descriptor string differs from that of the configuration files. This is because it represents specific realizations of ensemble. For example
[ B1{npets} G1{80}+P; B2{1} G2{20} ] @{+,+}
indicates that the 2D block of memory is periodic in the first dimension by the addition of the $+P$ to the first grid key. The size of the grid is indicated as $80 \times 20$ by the size arguments appended to the grid indicators $G1 \{80 \}$ and $G2 \{ 20 \}$. The size of the distribution is indicated in the same way as $npets \times 1$ by the block distribution indicators $B1 \{ npets \}$ and $B2 \{ 1 \}$.

The report indicates that all the test configurations for the conservative remapping are successful. This is indicated by the key word SUCCESS which is followed by the successful problem descriptor string. Since all of the tests in the first case pass,there is no need to include any of the specifier information. For the second ensemble of tests, one configuration passed, while the other failed. In this case, since there is a mixture of successes and failures, the report includes specifier information for all the configurations to help indicate the source of the test failure.

The supplemental information, while not a complete problem description, since it lacks items such as the physical coordinates of the grid and the nature of the test field, includes information crucial to isolating the failed test.

esmf_support@ucar.edu