Skip to content

Commit

Permalink
Merge tag 'alpha-ctsm5.2.mksrf.04_ctsm5.1.dev090' into mksurfdata_esm…
Browse files Browse the repository at this point in the history
…f_casper

Add mksurfdata_esmf system test to test-suite ESCOMP#1756

Confirms that mksurfdata_esmf builds & generates an fsurdat.
Confirms that the CTSM completes when pointing to the generated fsurdat.
Remove mksurfdata_map test from tools testing (if not done already).

Contributors other than @slevisconsulting: @ekluzek @billsacks
CTSM Issues Fixed: ESCOMP#1717
Answers expected to change? No, this is a new test.
User Interface Changes? New test will be added to test-suite.

Testing performed:
pymod testing PASS.
python testing OK. Two lilac sys tests fail due to:
> git describe
alpha-ctsm5.2.mksrf.03_ctsm5.1.dev090-33-gde3fb92b6

Resolved Conflicts:
tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py
tools/mksurfdata_esmf/gen_mksurfdata_namelist.py
  • Loading branch information
slevis-lmwg committed Jul 1, 2022
2 parents 7bf0bcc + 4dca577 commit e060ae6
Show file tree
Hide file tree
Showing 8 changed files with 400 additions and 132 deletions.
131 changes: 131 additions & 0 deletions cime_config/SystemTests/mksurfdataesmf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""
This test passes if mksurfdata_esmf generates an fsurdat (surface dataset)
and the CTSM completes a simulation with this fsurdat file.
We test res = '10x15' because it uses a lower-res topography file instead of
the 1-km topography raw dataset. The 1-km file causes the test to run out of
memory on cheyenne.
Currently casper complains that `git -C` is not a valid option.
I added -C to the `git describe` in gen_mksurfdata_namelist.py for this
system test to work.
"""
import os
import sys
import subprocess
from datetime import datetime
from CIME.SystemTests.system_tests_common import SystemTestsCommon
from CIME.XML.standard_module_setup import *
from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files

logger = logging.getLogger(__name__)

class MKSURFDATAESMF(SystemTestsCommon):

def __init__(self, case):
"""
initialize an object interface to the SMS system test
"""
SystemTestsCommon.__init__(self, case)

# Paths and strings needed throughout
ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND')
self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf')
self._tool_bld = os.path.join(self._get_caseroot(), 'tool_bld')
time_stamp = datetime.today().strftime("%y%m%d")
self._res = '10x15' # see important comment in script's docstring
self._model_yr = '1850'
self._jobscript = os.path.join(self._get_caseroot(),
'mksurfdata_jobscript_single')
self._fsurdat_namelist = os.path.join(self._get_caseroot(),
f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist')
self._fsurdat_nc = os.path.join(self._get_caseroot(),
f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc')
self._TestStatus_log_path = os.path.join(self._get_caseroot(),
'TestStatus.log')

def build_phase(self, sharedlib_only=False, model_only=False):
"""
Build executable that will generate fsurdat
Generate namelist for generating fsurdat
Generate jobscript that runs executable
Modify user_nl_clm to point to the generated fsurdat
"""
# build_phase gets called twice:
# - once with sharedlib_only = True and
# - once with model_only = True
# Call the following steps only once during the test but do not skip
# if the test stops and gets restarted.
if sharedlib_only:
# Paths and strings
build_script_path = os.path.join(self._tool_path,
'gen_mksurfdata_build.sh')
nml_script_path = os.path.join(self._tool_path,
'gen_mksurfdata_namelist.py')
gen_jobscript_path = os.path.join(self._tool_path,
'gen_mksurfdata_jobscript_single.py')
gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}'
gen_mksurfdata_jobscript = f'{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}'

# Rm tool_bld and build executable that will generate fsurdat
try:
subprocess.check_call(f'rm -rf {self._tool_bld}', shell=True)
except subprocess.CalledProcessError as e:
sys.exit(f'{e} ERROR REMOVING {self._tool_bld}. DETAILS IN {self._TestStatus_log_path}')
try:
subprocess.check_call(f'{build_script_path} --blddir {self._tool_bld}', shell=True)
except subprocess.CalledProcessError as e:
sys.exit(f'{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}')

# Generate namelist for generating fsurdat (rm namelist if exists)
if os.path.exists(self._fsurdat_namelist):
os.remove(self._fsurdat_namelist)
try:
subprocess.check_call(gen_mksurfdata_namelist, shell=True)
except subprocess.CalledProcessError as e:
sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}')

# Generate jobscript that will run the executable
if os.path.exists(self._jobscript):
os.remove(self._jobscript)
try:
subprocess.check_call(gen_mksurfdata_jobscript, shell=True)
except subprocess.CalledProcessError as e:
sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_jobscript}. DETAILS IN {self._TestStatus_log_path}')
# Change self._jobscript to an executable file
subprocess.check_call(f'chmod a+x {self._jobscript}', shell=True)

# Call this step only once even if the test stops and gets restarted.
if not os.path.exists(os.path.join(self._get_caseroot(),
'done_MKSURFDATAESMF_setup.txt')):
# Modify user_nl_clm to point to the generated fsurdat
self._modify_user_nl()
with open('done_MKSURFDATAESMF_setup.txt', 'w') as fp:
pass

self.build_indv(sharedlib_only=sharedlib_only, model_only=model_only)

def run_phase(self):
"""
Run executable to generate fsurdat
Submit CTSM run that uses fsurdat just generated
"""

# Run executable to generate fsurdat (rm fsurdat if exists)
if os.path.exists(self._fsurdat_nc):
os.remove(self._fsurdat_nc)
try:
subprocess.check_call(self._jobscript, shell=True)
except subprocess.CalledProcessError as e:
sys.exit(f'{e} ERROR RUNNING {self._jobscript}; details in {self._TestStatus_log_path}')

# Submit CTSM run that uses fsurdat just generated
self.run_indv()

def _modify_user_nl(self):
"""
Modify user_nl_clm to point to the generated fsurdat
"""
append_to_user_nl_files(caseroot = self._get_caseroot(),
component = "clm",
contents = "fsurdat = '{}'".format(self._fsurdat_nc))
10 changes: 10 additions & 0 deletions cime_config/config_tests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ This defines various CTSM-specific system tests
<DOUT_S>FALSE</DOUT_S>
</test>

<test NAME="MKSURFDATAESMF">
<DESC>Build and run the mksurfdata_esmf tool to generate a new fsurdat; then run the CTSM with this fsurdat</DESC>
<INFO_DBUG>1</INFO_DBUG>
<DOUT_S>FALSE</DOUT_S>
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
<REST_OPTION>never</REST_OPTION>
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="FSURDATMODIFYCTSM">
<DESC>Run the CTSM with an fsurdat generated by the fsurdat_modify tool</DESC>
<INFO_DBUG>1</INFO_DBUG>
Expand Down
17 changes: 17 additions & 0 deletions cime_config/testdefs/testlist_clm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,23 @@
</machines>
</test>

<test name="MKSURFDATAESMF_P144x1" grid="f10_f10_mg37" compset="I1850Clm50BgcCrop">
<machines>
<machine name="cheyenne" compiler="intel" category="aux_clm">
<options>
<option name="wallclock">00:40:00</option>
<option name="comment">Smoke test that first runs the mksurfdata_esmf tool and then ensures that the CTSM does not fail using the just-generated fsurdat file. Global BGC CROP case.</option>
</options>
</machine>
<machine name="cheyenne" compiler="intel" category="clm_pymods">
<options>
<option name="wallclock">00:40:00</option>
<option name="comment">This test invokes python code, so it should be run whenever changing python code (in addition to being run as part of aux_clm).</option>
</options>
</machine>
</machines>
</test>

<test name="FSURDATMODIFYCTSM_D_Mmpi-serial_Ld1" grid="5x5_amazon" compset="I2000Clm50SpRs">
<machines>
<machine name="cheyenne" compiler="intel" category="aux_clm">
Expand Down
6 changes: 2 additions & 4 deletions tools/mksurfdata_esmf/README
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ on your machine you will be able to build the tool there.

To get a list of the machines that have been ported to cime:

cd ../../cime/scripts
cd ../../cime/scripts # assumes we are in tools/mksurfdata_esmf
./query_config --machines

NOTE:
Expand All @@ -41,16 +41,14 @@ to be referenced with the env variable PIO which will need to be in the porting
for the machine. Currently an independent PIO library is not available on cime ported machines.

=======================
building the executable
building the executable (working in tools/mksurfdata_esmf)
=======================

> cd tools/mksurfdata_esmf
> ./gen_mksurfdata_build.sh # For machines with a cime build

=======================
running for a single submission:
=======================
> cd ../
# to generate your target namelist:
> ./gen_mksurfdata_namelist.py --help
# for example try --res 1.9x2.5 --start-year 1850 --end-year 1850:
Expand Down
77 changes: 65 additions & 12 deletions tools/mksurfdata_esmf/gen_mksurfdata_build.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
#! /bin/bash -f

hostname=`hostname --short`
#----------------------------------------------------------------------
# Usage subroutine
usage() {
echo ""
echo "***********************************************************************"
echo "usage:"
echo "./gen_mksurfdata_build.sh"
echo ""
echo "valid arguments: "
echo "[-h|--help] "
echo " Displays this help message"
echo "[-v|--verbose] "
echo " Run in verbose mode"
echo "[-b|--blddir <blddir>] "
echo " Overwrites default, which is /bld in the same directory as ./gen_mksurfdata_build.sh"
echo "[-m|--machine <machine>] "
echo " Overwrites default MACH"
echo "***********************************************************************"
}


# Current working directory: the location of ./gen_mksurfdata_build.sh
cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# Default settings
verbose="No"
blddir=$cwd/tool_bld # may overwrite this default with command-line option (below)

# Define what machine to use that's been ported to cime
# May overwrite this default with command-line option --machine
hostname=`hostname --short`
case $hostname in
##cheyenne
cheyenne* | r* )
Expand All @@ -21,16 +49,41 @@ case $hostname in
;;
esac

# Create /bld directory
# Parse command-line options
while [ $# -gt 0 ]; do
case $1 in
-h|--help )
usage
exit 0
;;
-v|--verbose )
verbose="Yes"
;;
-b|--blddir )
blddir=$2
shift
;;
-m|--machine )
MACH=$2
shift
;;
* )
echo "ERROR:: invalid argument sent in: $2"
usage
exit 1
;;
esac
shift
done

# Create /tool_bld directory
echo "cime Machine is: $MACH..."
if [ -d "bld" ]; then
echo "A /bld directory exists; remove it to do a clean build..."
if [ -d "$blddir" ]; then
echo "A /tool_bld directory exists; remove it to do a clean build..."
exit 1
fi
cwd=`pwd`
rm -rf bld
mkdir bld
cd bld
mkdir $blddir
cd $blddir

# Write pio_iotype to file with name pio_iotype.txt
echo $pio_iotype > $cwd/pio_iotype.txt
Expand All @@ -40,17 +93,17 @@ echo "Run cime configure for machine $MACH..."
# You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings
if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then
echo "configure for the default MPI-library and compiler..."
../../../cime/tools/configure --macros-format CMake --machine $MACH
$cwd/../../cime/tools/configure --macros-format CMake --machine $MACH
else
echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..."
../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB
$cwd/../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB
fi

if [ $? != 0 ]; then
echo "Error doing configure for machine name: $MACH"
exit 1
fi
. .env_mach_specific.sh
. ./.env_mach_specific.sh
echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS"
if [ -z "$PIO" ]; then
echo "The PIO directory for the PIO build is required and was not set in the configure"
Expand All @@ -60,7 +113,7 @@ fi

# Build the cmake files
echo "Do the cmake build..."
CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src
CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug $cwd/src
if [ $? != 0 ]; then
echo "Error doing cmake for $MACH $MPILIB $COMPILER"
exit 1
Expand Down
Loading

0 comments on commit e060ae6

Please sign in to comment.