Skip to content

Commit

Permalink
Merge Pull Request #2868 from E3SM-Project/scream/bartgol/eamxx/check…
Browse files Browse the repository at this point in the history
…-nlev-consistency-with-IC-file-at-buildnml-time

Automatically Merged using E3SM Pull Request AutoTester
PR Title: EAMxx: add buildnml-time check for IC file and cmake option compatibility
PR Author: bartgol
PR LABELS: AT: AUTOMERGE, scripts, CIME, AT: Skip weaver, AT: Skip Stand-Alone Testing, code usability
  • Loading branch information
E3SM-Autotester authored Jun 18, 2024
2 parents aeb08b7 + ad551e0 commit 02526e1
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 9 deletions.
41 changes: 40 additions & 1 deletion components/eamxx/cime_config/eamxx_buildnml.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
import xml.dom.minidom as md

# Add path to scream libs
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "scripts"))
EAMXXROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(EAMXXROOT, "scripts"))

# SCREAM imports
from eamxx_buildnml_impl import get_valid_selectors, get_child, refine_type, \
resolve_all_inheritances, gen_atm_proc_group, check_all_values, find_node
from atm_manip import apply_atm_procs_list_changes_from_buffer, apply_non_atm_procs_list_changes_from_buffer
from utils import run_cmd_no_fail

from utils import ensure_yaml # pylint: disable=no-name-in-module
ensure_yaml()
Expand Down Expand Up @@ -163,6 +165,22 @@ def perform_consistency_checks(case, xml):
CIME.utils.CIMEError: ERROR: rrtmgp::rad_frequency incompatible with restart frequency.
Please, ensure restart happens on a step when rad is ON
For daily (or less frequent) restart, rad_frequency must divide ATM_NCPL
>>> case = MockCase({'SCREAM_CMAKE_OPTIONS':'SCREAM_NUM_VERTICAL_LEV 15'})
>>> xml_str = '''
... <params>
... <initial_conditions>
... <Filename>{}/eamxx_buildnml_unittest.nc</Filename>
... </initial_conditions>
... </params>
... '''.format(os.path.join(EAMXXROOT,'cime_config/tests'))
>>> xml = ET.fromstring(xml_str)
>>> perform_consistency_checks(case,xml)
>>> case = MockCase({'SCREAM_CMAKE_OPTIONS':'SCREAM_NUM_VERTICAL_LEV 20'})
>>> perform_consistency_checks(case,xml)
Traceback (most recent call last):
CIME.utils.CIMEError: ERROR: Error! IC file contains a number of levels different from the cmake option SCREAM_NUM_VERTICAL_LEV
ic file, lev: 15
SCREAM_NUM_VERTICAL_LEV: 20
"""

# RRTMGP can be supercycled. Restarts cannot fall in the middle
Expand Down Expand Up @@ -205,6 +223,27 @@ def perform_consistency_checks(case, xml):
" Please, ensure restart happens on a step when rad is ON\n"
" For daily (or less frequent) restart, rad_frequency must divide ATM_NCPL")

# Check that SCREAM_NUM_VERTICAL_LEV matches nlev in the IC file
scream_opts = case.get_value("SCREAM_CMAKE_OPTIONS")
tokens = scream_opts.split()
expect (len(tokens) % 2 == 0, "Error! SCREAM_CMAKE_OPTIONS should contain a string of the form 'option1 value1 option2 value2 ...'\n")
it = iter(tokens)
cmake_args_dict = {}
for item in it:
cmake_args_dict[item] = next(it)

nlevs_cmake = int(cmake_args_dict['SCREAM_NUM_VERTICAL_LEV'])
ic_xml = find_node(xml,"initial_conditions")
if ic_xml is not None:
ic_fname = get_child(ic_xml,"Filename")
cmd = f"ncdump -h {ic_fname.text}" + r" | sed '/variables:/q' | awk '/\<lev/{ print $3 }'"
nlevs_ic = int(run_cmd_no_fail(cmd))
expect (nlevs_cmake == nlevs_ic,
"Error! IC file contains a number of levels different from the cmake option SCREAM_NUM_VERTICAL_LEV\n"
f" ic file, lev: {nlevs_ic}\n"
f" SCREAM_NUM_VERTICAL_LEV: {nlevs_cmake}")


###############################################################################
def ordered_dump(data, item, Dumper=yaml.SafeDumper, **kwds):
###############################################################################
Expand Down
2 changes: 2 additions & 0 deletions components/eamxx/cime_config/eamxx_buildnml_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class MockCase(object):

def __init__(self, kv_dict):
self._kv_dict = dict(kv_dict)
if 'SCREAM_CMAKE_OPTIONS' not in self._kv_dict.keys():
self._kv_dict['SCREAM_CMAKE_OPTIONS'] = "SCREAM_NUM_VERTICAL_LEV 10"

def get_value(self, key):
if key in self._kv_dict:
Expand Down
10 changes: 6 additions & 4 deletions components/eamxx/cime_config/namelist_defaults_scream.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ be lost if SCREAM_HACK_XML is not enabled.
<selector name="hgrid" case_env="ATM_GRID"/>
<selector name="dyn" case_env="CAM_TARGET"/>
<selector name="nlev" case_env="SCREAM_CMAKE_OPTIONS" regex=".*SCREAM_NUM_VERTICAL_LEV ([0-9]+).*"/>
<!-- For intenal testing only -->
<selector name="test_sel" case_env="SCREAM_CMAKE_OPTIONS" regex=".*SCREAM_NUM_TRACERS ([0-9]+).*"/>
</selectors>

<!-- List of scream grids for a given compset. I/O can only happen on these grids -->
Expand Down Expand Up @@ -301,10 +303,10 @@ be lost if SCREAM_HACK_XML is not enabled.
<!-- For internal testing only -->
<testOnly inherit="atm_proc_base">
<my_param type="array(integer)">1,2</my_param>
<my_param nlev="1" append="base">3,4</my_param>
<my_param nlev="1" append="last">5,6</my_param>
<my_param nlev="2" append="last">3,4</my_param>
<my_param nlev="2" append="base">5,6</my_param>
<my_param test_sel="1" append="base">3,4</my_param>
<my_param test_sel="1" append="last">5,6</my_param>
<my_param test_sel="2" append="last">3,4</my_param>
<my_param test_sel="2" append="base">5,6</my_param>
</testOnly>

<!-- Simple Prescribed Aerosols (SPA) -->
Expand Down
Binary file not shown.
7 changes: 4 additions & 3 deletions components/eamxx/scripts/cime-nml-tests
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ from utils import check_minimum_python_version, expect, ensure_pylint, get_times

check_minimum_python_version(3, 6)

from machines_specs import is_machine_supported
from machines_specs import is_machine_supported, setup_mach_env

import unittest, argparse, sys, os, shutil
from pathlib import Path
Expand Down Expand Up @@ -202,12 +202,12 @@ class TestBuildnml(unittest.TestCase):
self._chg_atmconfig([("mac_aero_mic::atm_procs_list", "shoc,cldFraction,spa,p3,testOnly")], case)

# Test case 1: append to base, then to last. Should give all 3 entries stacked
run_cmd_no_fail(f"./xmlchange --append SCREAM_CMAKE_OPTIONS='SCREAM_NUM_VERTICAL_LEV 1'", from_dir=case)
run_cmd_no_fail(f"./xmlchange --append SCREAM_CMAKE_OPTIONS='SCREAM_NUM_TRACERS 1'", from_dir=case)
run_cmd_no_fail("./case.setup", from_dir=case)
self._get_values(case,"my_param","1,2,3,4,5,6")

# Test case 2: append to last, then to base. Should give 1st and 3rd entry
run_cmd_no_fail(f"./xmlchange --append SCREAM_CMAKE_OPTIONS='SCREAM_NUM_VERTICAL_LEV 2'", from_dir=case)
run_cmd_no_fail(f"./xmlchange --append SCREAM_CMAKE_OPTIONS='SCREAM_NUM_TRACERS 2'", from_dir=case)
run_cmd_no_fail("./case.setup", from_dir=case)
self._get_values(case,"my_param","1,2,5,6")

Expand Down Expand Up @@ -429,6 +429,7 @@ def scripts_tests(machine=None):
if machine:
expect(is_machine_supported(machine), "Machine {} is not supported".format(machine))
CONFIG["machine"] = machine
setup_mach_env(machine)

unittest.main(verbosity=2)

Expand Down
2 changes: 1 addition & 1 deletion components/eamxx/scripts/jenkins/jenkins_common_impl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ if [ $skip_testing -eq 0 ]; then
scripts_fail=1
fi

./scripts/cime-nml-tests
./scripts/cime-nml-tests -m mappy
if [[ $? != 0 ]]; then
fails=$fails+1;
scripts_fail=1
Expand Down

0 comments on commit 02526e1

Please sign in to comment.