diff --git a/CIME/Tools/get_case_env b/CIME/Tools/get_case_env
index 3a67d06961d..83e2ce5c132 100755
--- a/CIME/Tools/get_case_env
+++ b/CIME/Tools/get_case_env
@@ -60,8 +60,9 @@ def _main_func(description):
###############################################################################
casename = parse_command_line(sys.argv, description)
- compiler = parse_test_name(casename)[5]
- machine = CIME.get_tests.infer_machine_name_from_tests([casename])
+ machine, compiler = CIME.get_tests.infer_arch_from_tests([casename])
+ expect(len(compiler) <= 1, "How did we get multiple compilers from one test case?")
+ compiler = compiler[0] if len(compiler) == 1 else None
mach_obj = Machines(machine=machine)
compiler = mach_obj.get_default_compiler() if compiler is None else compiler
full_test_name = CIME.get_tests.get_full_test_names(
diff --git a/CIME/get_tests.py b/CIME/get_tests.py
index 21220cf6165..857fa974d3e 100644
--- a/CIME/get_tests.py
+++ b/CIME/get_tests.py
@@ -300,27 +300,39 @@ def get_build_groups(tests):
###############################################################################
-def infer_machine_name_from_tests(testargs):
+def infer_arch_from_tests(testargs):
###############################################################################
"""
- >>> infer_machine_name_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu"])
- 'melvin'
- >>> infer_machine_name_from_tests(["NCK.f19_g16_rx1.A"])
- >>> infer_machine_name_from_tests(["NCK.f19_g16_rx1.A", "NCK.f19_g16_rx1.A.melvin_gnu"])
- 'melvin'
- >>> infer_machine_name_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu", "NCK.f19_g16_rx1.A.melvin_gnu"])
- 'melvin'
+ Return a tuple (machine, [compilers]) that can be inferred from the test args
+
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu"])
+ ('melvin', ['gnu'])
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A"])
+ (None, [])
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A", "NCK.f19_g16_rx1.A.melvin_gnu"])
+ ('melvin', ['gnu'])
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu", "NCK.f19_g16_rx1.A.melvin_gnu"])
+ ('melvin', ['gnu'])
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu9", "NCK.f19_g16_rx1.A.melvin_gnu"])
+ ('melvin', ['gnu9', 'gnu'])
+ >>> infer_arch_from_tests(["NCK.f19_g16_rx1.A.melvin_gnu", "NCK.f19_g16_rx1.A.mappy_gnu"])
+ Traceback (most recent call last):
+ ...
+ CIME.utils.CIMEError: ERROR: Must have consistent machine 'melvin' != 'mappy'
"""
e3sm_test_suites = get_test_suites()
machine = None
+ compilers = []
for testarg in testargs:
testarg = testarg.strip()
if testarg.startswith("^"):
testarg = testarg[1:]
if testarg not in e3sm_test_suites:
- machine_for_this_test = parse_test_name(testarg)[4]
+ machine_for_this_test, compiler_for_this_test = parse_test_name(testarg)[
+ 4:6
+ ]
if machine_for_this_test is not None:
if machine is None:
machine = machine_for_this_test
@@ -331,7 +343,13 @@ def infer_machine_name_from_tests(testargs):
% (machine, machine_for_this_test),
)
- return machine
+ if (
+ compiler_for_this_test is not None
+ and compiler_for_this_test not in compilers
+ ):
+ compilers.append(compiler_for_this_test)
+
+ return machine, compilers
###############################################################################
diff --git a/CIME/scripts/create_test.py b/CIME/scripts/create_test.py
index 53ee90f170d..753e627b24b 100755
--- a/CIME/scripts/create_test.py
+++ b/CIME/scripts/create_test.py
@@ -631,13 +631,25 @@ def parse_command_line(args, description):
logger.info("Testnames: %s" % test_names)
else:
+ inf_machine, inf_compilers = get_tests.infer_arch_from_tests(args.testargs)
if args.machine is None:
- args.machine = get_tests.infer_machine_name_from_tests(args.testargs)
+ args.machine = inf_machine
mach_obj = Machines(machine=args.machine)
- args.compiler = (
- mach_obj.get_default_compiler() if args.compiler is None else args.compiler
- )
+ if args.compiler is None:
+ if len(inf_compilers) == 0:
+ args.compiler = mach_obj.get_default_compiler()
+ elif len(inf_compilers) == 1:
+ args.compiler = inf_compilers[0]
+ else:
+ # User has multiple compiler specifications in their testargs
+ args.compiler = inf_compilers[0]
+ expect(
+ not args.compare and not args.generate,
+ "It is not safe to do baseline operations with heterogenous compiler set: {}".format(
+ inf_compilers
+ ),
+ )
test_names = get_tests.get_full_test_names(
args.testargs, mach_obj.get_machine_name(), args.compiler
diff --git a/CIME/tests/base.py b/CIME/tests/base.py
index 8280736ea1c..1b5f5094eba 100644
--- a/CIME/tests/base.py
+++ b/CIME/tests/base.py
@@ -62,6 +62,9 @@ def setUp(self):
self._do_teardown = not self.NO_TEARDOWN
self._root_dir = os.getcwd()
+ customize_path = os.path.join(utils.get_src_root(), "cime_config", "customize")
+ config = Config.load(customize_path)
+
def tearDown(self):
self.kill_subprocesses()
@@ -192,7 +195,14 @@ def kill_subprocesses(
def kill_python_subprocesses(self, sig=signal.SIGKILL, expected_num_killed=None):
self.kill_subprocesses("[Pp]ython", sig, expected_num_killed)
- def _create_test(self, extra_args, test_id=None, run_errors=False, env_changes=""):
+ def _create_test(
+ self,
+ extra_args,
+ test_id=None,
+ run_errors=False,
+ env_changes="",
+ default_baseline_area=False,
+ ):
"""
Convenience wrapper around create_test. Returns list of full paths to created cases. If multiple cases,
the order of the returned list is not guaranteed to match the order of the arguments.
@@ -210,7 +220,8 @@ def _create_test(self, extra_args, test_id=None, run_errors=False, env_changes="
else test_id
)
extra_args.append("-t {}".format(test_id))
- extra_args.append("--baseline-root {}".format(self._baseline_area))
+ if not default_baseline_area:
+ extra_args.append("--baseline-root {}".format(self._baseline_area))
if self.NO_BATCH:
extra_args.append("--no-batch")
if self.TEST_COMPILER and (
diff --git a/CIME/tests/test_sys_test_scheduler.py b/CIME/tests/test_sys_test_scheduler.py
index 2e56f96a786..8ab3414f4a2 100755
--- a/CIME/tests/test_sys_test_scheduler.py
+++ b/CIME/tests/test_sys_test_scheduler.py
@@ -450,6 +450,18 @@ def test_d_retry(self):
self._create_test(args)
+ def test_e_test_inferred_compiler(self):
+ if Config.instance().test_mode != "e3sm" or self._machine != "docker":
+ self.skipTest("Skipping create_test test. Depends on E3SM settings")
+
+ args = ["SMS.f19_g16_rx1.A.docker_gnuX", "--no-setup"]
+
+ case = self._create_test(args, default_baseline_area=True)
+ result = self.run_cmd_assert_result(
+ "./xmlquery --value BASELINE_ROOT", from_dir=case
+ )
+ self.assertEqual(os.path.split(result)[1], "gnuX")
+
if __name__ == "__main__":
unittest.main()
diff --git a/docker/config_machines.xml b/docker/config_machines.xml
index 16a9a3dd460..a2842d55945 100644
--- a/docker/config_machines.xml
+++ b/docker/config_machines.xml
@@ -6,7 +6,7 @@
docker
LINUX
- gnu
+ gnu,gnuX
openmpi
CIME
/storage/timings
@@ -15,7 +15,7 @@
/storage/inputdata
/storage/inputdata-clmforc
/storage/archive/$CASE
- /storage/baselines
+ /storage/baselines/$COMPILER
/storage/tools/cprnc
make
4