Skip to content

Commit

Permalink
Slightly refactored the Grackle tests to integrate them with the new …
Browse files Browse the repository at this point in the history
…CTest infrastructure
  • Loading branch information
mabruzzo committed Jun 10, 2022
1 parent e0d9ddf commit fe5e530
Show file tree
Hide file tree
Showing 7 changed files with 379 additions and 218 deletions.
18 changes: 16 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ commands:
echo 'export HDF5_LIB=/usr/lib/x86_64-linux-gnu' >> $BASH_ENV
echo 'export CHARM_ROOT=$HOME/local/charm-v$CHARM_VER' >> $BASH_ENV
echo 'export Grackle_ROOT=$HOME/local' >> $BASH_ENV
echo 'export GRACKLE_INPUT_DATA_DIR=$HOME/grackle/grackle_data_files/input/' >> $BASH_ENV
# tag the tip so we can go back to it
git tag tip
Expand Down Expand Up @@ -125,9 +124,24 @@ commands:
# convert boolean parameter to an env var storing 0 or 1
SKIP_TEST=$(( 0 <<# parameters.skiptest >> + 1 <</ parameters.skiptest >> ))
USE_DOUBLE=$(( 0 <<# parameters.usedouble >> + 1 <</ parameters.usedouble >> ))
USE_GRACKLE=$(( 0 <<# parameters.usegrackle >> + 1 <</ parameters.usegrackle >> ))
# this is used for tests involving Grackle
if [[ $USE_GRACKLE == 1 ]]; then
GRACKLE_INPUT_DATA_DIR="$HOME/grackle/grackle_data_files/input/"
else
GRACKLE_INPUT_DATA_DIR=""
fi
if [ ! -f << parameters.skipfile >> ]; then
cmake -DEnzo-E_CONFIG=linux_gcc -GNinja -DUSE_DOUBLE_PREC=<< parameters.usedouble >> -DUSE_GRACKLE=<< parameters.usegrackle >> -Bbuild -DPARALLEL_LAUNCHER_NPROC_ARG="++local;+p" -DPython3_FIND_VIRTUALENV=ONLY
cmake -DEnzo-E_CONFIG=linux_gcc \
-GNinja \
-DUSE_DOUBLE_PREC=<< parameters.usedouble >> \
-DUSE_GRACKLE=<< parameters.usegrackle >> \
-DGRACKLE_INPUT_DATA_DIR="$GRACKLE_INPUT_DATA_DIR" \
-Bbuild \
-DPARALLEL_LAUNCHER_NPROC_ARG="++local;+p" \
-DPython3_FIND_VIRTUALENV=ONLY
cmake --build build -j 4
source $HOME/venv/bin/activate
if [[ $SKIP_TEST != 1 ]]; then
Expand Down
144 changes: 144 additions & 0 deletions input/Grackle/run_endtime_grackle_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import argparse
import os.path
import sys

_LOCAL_DIR = os.path.dirname(os.path.realpath(__file__))
_TOOLS_DIR = os.path.join(_LOCAL_DIR, "../../tools")
if os.path.isdir(_TOOLS_DIR):
sys.path.insert(0, _TOOLS_DIR)
from gen_grackle_testing_file import generate_grackle_input_file
from run_cpp_test import run_test_and_check_success

else:
raise RuntimeError(
f"expected testing utilities to be defined in {_TOOLS_DIR}, but that "
"directory does not exist"
)

parent_parser = argparse.ArgumentParser(add_help=False)

parent_parser.add_argument(
"--grackle-data-file", required = True, type = str,
help = ("Specifies the path to the grackle data file that is to be used in "
"the simultaion.")
)
parent_parser.add_argument(
"--generate-config-path", required = True, type = str,
help = ("Specifies the path to the configuration file that is generated by "
"this program. The generated file includes the contents of "
"--nominal-config-path and overwrites path to the grackle data "
"file based on --grackle-data-path")
)
parent_parser.add_argument(
'--launch_cmd', required = True, type = str,
help = "Specifies the commands used to launch the Enzo-E simulation"
)
parent_parser.add_argument(
"--output-dump", action = "store", default = None,
help = ("Specifies the path where a copy of the standard output stream "
"from the execution of the program should optionally be dumped "
"(the data is still written to the standard output stream). The "
"contents of this file may be used to determine the outcome of "
"the tests.")
)

_description = '''\
Runs a test Grackle-related test that succeeds or fails based on the completion
time of the test. The success/failure of the test is reflected by the return
code of this program (an exit code of 0 indicates the test was entirely
successful).
'''

_epilog = '''\
In more detail, this function expects most of the test problem's parameters to
be specified by the file at the location given by --nominal_config_path.
The program will generate a new configuration file that uses all of the
parameters from the --nominal-config-path file but overwrites the parameter
used to specify the grackle data file with the value specified by
--grackle-data-file. The generated config file is written to the path given by
--generate-config-path.
Finally, the program executes Enzo-E with this generated configuration
file and reports whether the tests have passed.
'''

parser = argparse.ArgumentParser(description = _description, epilog = _epilog,
parents = [parent_parser])
parser.add_argument(
"--nominal-config-path", required = True, type = str,
help = ("Specifies the path to the configuration file that specifies most "
"parameters for the test problem.")
)



def run_grackle_test(launcher, nominal_config_path, generate_config_path,
grackle_data_file, dump_path = None):
"""
Runs an enzo-e simulation test problem involving Grackle.
In detail, this function:
- expects most of the test problem's parameters to be specified by the
file at the location given by `nominal_config_path`.
- generates a new configuration file at the path given by
`generate_config_path`. This file includes all of the parameters from
the `nominal_config_path`, but overwrites the parameter used to specify
the grackle data file with the value specified by `grackle_data_dir`.
- the function then executes enzo-e with this generated configuration
file and reports whether all tests built into the simulation (e.g. an
expected completion time) have passed, if there are any.
Parameters
----------
launcher: str
Specifies the command used to launch enzo-e.
nominal_config_path: str
Specifies the path to the config file that specifies the bulk of the
generate_config_path: str
Specifies the path where the temporary input file should be written.
grackle_data_file: str
Specifies the path to the grackle data file that is to be used by the
test problem.
dump_path: str, optional
Path to a file where the output of the simulation should be written.
If this is None (the default), the output is written to a temporary
file.
Returns
-------
tests_pass: bool
Specifies whether the simulation ran successfully and whether all tests
that are built into the simulation have passed (if there are any).
"""

print("generating config file at {} that uses the grackle data file at {}"\
.format(generate_config_path, grackle_data_file))
generate_grackle_input_file(
include_path = nominal_config_path,
data_path = grackle_data_file,
use_abs_paths = True,
output_fname = generate_config_path
)

print("Executing Enzo-E")
test_passes = run_test_and_check_success(
command = launcher, args_for_command = [generate_config_path],
dump_path = "cooling-test.in"
)
return test_passes

if __name__ == '__main__':
args = parser.parse_args()

test_passes = run_grackle_test(
launcher = args.launch_cmd,
nominal_config_path = args.nominal_config_path,
generate_config_path = args.generate_config_path,
grackle_data_file = args.grackle_data_file,
dump_path = args.output_dump
)
if test_passes:
sys.exit(0)
else:
sys.exit(1)
79 changes: 79 additions & 0 deletions input/Grackle/run_general_grackle_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/python

# runs a generic Grackle test where we compare summary statistics about the
# fields at the final snapshot

import argparse
import os.path
import sys

from run_endtime_grackle_test import run_grackle_test, parent_parser

_LOCAL_DIR = os.path.dirname(os.path.realpath(__file__))
_TOOLS_DIR = os.path.join(_LOCAL_DIR, "../../tools")
if os.path.isdir(_TOOLS_DIR):
sys.path.insert(0, _TOOLS_DIR)
from field_summary import compare_against_reference

else:
raise RuntimeError(
f"expected testing utilities to be defined in {_TOOLS_DIR}, but that "
"directory does not exist"
)




parser = argparse.ArgumentParser(
description = ("Runs a general Grackle test that compares summary "
"statistics at a completion time with some reference "
"values."),
parents = [parent_parser]
)

parser.add_argument(
"--prec", required = True, type = str, choices = ["single", "double"],
help = "Specifies the precision of Enzo-E."
)

if __name__ == '__main__':
args = parser.parse_args()

test_passes = run_grackle_test(
launcher = args.launch_cmd,
nominal_config_path = os.path.join(_LOCAL_DIR,
'method_grackle_general.in'),
generate_config_path = args.generate_config_path,
grackle_data_file = args.grackle_data_file,
dump_path = args.output_dump
)
# note that there aren't actually any built-in tests in this test problem.
# Thus, if test_passes is False, that means that Enzo-E crashed
if not test_passes:
raise RuntimeError("Enzo-E crashed")


# now check field values against the reference values
if args.prec == 'double':
_ref_tab = os.path.join(_LOCAL_DIR, 'ref_general_grackle-double.csv')
atol = 0
# these should be flexible for different compiler versions
rtol = {"min" : 5e-15, "max" : 5e-6, "mean" : 5e-8,
"standard_deviation" : 5e-8}
else:
_ref_tab = os.path.join(_LOCAL_DIR, 'ref_general_grackle-single.csv')
atol = 0
# the following may need to be relaxed for different compiler versions
rtol = dict((k, 1e-7) for k in ["min","max","mean",
"standard_deviation"])

test_passes = compare_against_reference(
'./GeneralGrackle-500.00/GeneralGrackle-500.00.block_list',
ref_summary_file_path = _ref_tab,
atol = atol, rtol = rtol, report_path = None
)

if test_passes:
sys.exit(0)
else:
sys.exit(1)
40 changes: 40 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,46 @@ if (USE_YT_BASED_TESTS)
setup_test_parallel_python(merge_sinks_stationary_parallel merge_sinks/stationary/parallel "input/merge_sinks/run_merge_sinks_test.py" "--prec=${PREC_STRING}" "--ics_type=stationary")
setup_test_serial_python(merge_sinks_drift_serial merge_sinks/drift/serial "input/merge_sinks/run_merge_sinks_test.py" "--prec=${PREC_STRING}" "--ics_type=drift")
setup_test_parallel_python(merge_sinks_drift_parallel merge_sinks/drift/parallel "input/merge_sinks/run_merge_sinks_test.py" "--prec=${PREC_STRING}" "--ics_type=drift")

endif()

# Grackle tests
#
# because Grackle is a separate library, the user needs to specify the path
# to the data directory where the grackle data files are installed. if this is
# not specified, the Grackle tests are skipped

if(NOT (DEFINED GRACKLE_INPUT_DATA_DIR))
set(GRACKLE_INPUT_DATA_DIR "")
endif()

if(USE_GRACKLE AND (GRACKLE_INPUT_DATA_DIR STREQUAL ""))
message(STATUS
" IMPORTANT: No tests involving Grackle have been defined (even though Grackle is being used). To enable these tests, try `-DGRACKLE_INPUT_DATA_DIR=/path/to/grackle/data/dir`."
)
elseif(USE_GRACKLE)
# (non-yt-based test)
setup_test_parallel_python(grackle_cooling_dt grackle
"input/Grackle/run_endtime_grackle_test.py"
"--grackle-data-file=${GRACKLE_INPUT_DATA_DIR}/CloudyData_UVB=HM2012_shielded.h5"
"--nominal-config-path=input/Grackle/method_grackle_cooling_dt.in"
# by using relative paths in the following 2 arguments, we effectively
# specify output files in the testing directory
"--generate-config-path=./temp_grackle_cooling_dt.in"
"--output-dump=./grackle_cooling_dt.log"
)

if (USE_YT_BASED_TESTS)
setup_test_parallel_python(grackle_general grackle
"input/Grackle/run_general_grackle_test.py"
"--prec=${PREC_STRING}"
"--grackle-data-file=${GRACKLE_INPUT_DATA_DIR}/CloudyData_UVB=HM2012_shielded.h5"
# by using relative paths in the following 2 arguments, we effectively
# specify output files in the testing directory
"--generate-config-path=./temp_grackle_general.in"
"--output-dump=./grackle_general_test.log"
)
endif()
endif()

# Convert markdown file to html file for more flexible viewing
Expand Down
Loading

0 comments on commit fe5e530

Please sign in to comment.