From 3ec85f6227bcbd8b2ca8fe22f9aee78d1e39456d Mon Sep 17 00:00:00 2001 From: Jason Sarich Date: Tue, 15 Aug 2017 10:19:18 -0500 Subject: [PATCH 1/4] add option CHARGE_ACCOUNT to charge compute time to if different from PROJECT This option can be set by environment variable or in config_machines.xml Helpful because PROJECT can be used for directory names that don't match the name of the charge account. --- cime/config/acme/machines/config_batch.xml | 8 ++--- cime/config/xml_schemas/config_machines.xsd | 4 +++ .../xml_schemas/config_machines_template.xml | 9 ++++++ cime/scripts/create_newcase | 1 + cime/scripts/create_test | 7 ++++- cime/scripts/lib/CIME/XML/env_batch.py | 4 +-- cime/scripts/lib/CIME/case.py | 8 ++++- cime/scripts/lib/CIME/utils.py | 30 +++++++++++++++++++ .../mct/cime_config/config_component.xml | 8 +++++ 9 files changed, 71 insertions(+), 8 deletions(-) diff --git a/cime/config/acme/machines/config_batch.xml b/cime/config/acme/machines/config_batch.xml index 76ec9506d09f..4808fec736d5 100644 --- a/cime/config/acme/machines/config_batch.xml +++ b/cime/config/acme/machines/config_batch.xml @@ -57,7 +57,7 @@ (\d+) --dependencies - + @@ -76,7 +76,7 @@ - + -n {{ total_tasks }} @@ -101,7 +101,7 @@ - + -N {{ job_id }} @@ -122,7 +122,7 @@ %H:%M:%S - + -N {{ job_id }} diff --git a/cime/config/xml_schemas/config_machines.xsd b/cime/config/xml_schemas/config_machines.xsd index bad0fb386dc6..7b3fa6787c34 100644 --- a/cime/config/xml_schemas/config_machines.xsd +++ b/cime/config/xml_schemas/config_machines.xsd @@ -19,6 +19,7 @@ + @@ -72,6 +73,9 @@ + + couldbethis + + + diff --git a/cime/scripts/create_newcase b/cime/scripts/create_newcase index 627c0b60f42f..2196f85e82db 100755 --- a/cime/scripts/create_newcase +++ b/cime/scripts/create_newcase @@ -59,6 +59,7 @@ OR parser.add_argument("--project", "-project", help="Specify a project id") + parser.add_argument("--pecount", "-pecount", default="M", help="Specify a target size description for the number of cores" "Allowed options are ('S','M','L','X1','X2','[0-9]x[0-9]','[0-9]')") diff --git a/cime/scripts/create_test b/cime/scripts/create_test index 356545789548..218ff21f39ce 100755 --- a/cime/scripts/create_test +++ b/cime/scripts/create_test @@ -183,6 +183,7 @@ OR "Used for accounting when on a batch system." "The default is user-specified environment variable PROJECT") + parser.add_argument("-t", "--test-id", help="Specify an 'id' for the test. This is simply a" "string that is appended to the end of a test name." @@ -352,7 +353,8 @@ OR return test_names, test_extra_data, args.compiler, mach_obj.get_machine_name(), args.no_run, args.no_build, args.no_setup, args.no_batch,\ args.test_root, args.baseline_root, args.clean, baseline_cmp_name, baseline_gen_name, \ - args.namelists_only, args.project, args.test_id, args.parallel_jobs, args.walltime, \ + args.namelists_only, args.project, \ + args.test_id, args.parallel_jobs, args.walltime, \ args.single_submit, args.proc_pool, args.use_existing, args.save_timing, args.queue, \ args.allow_baseline_overwrite, args.output_root, args.wait, args.force_procs, args.force_threads, args.mpilib, args.input_dir @@ -369,6 +371,8 @@ def single_submit_impl(machine_name, test_id, proc_pool, project, args, job_cost if project is None: project = mach.get_value("PROJECT") + charge_account = CIME.utils.get_charge_account(mach) + # # Compute arg list for second call to create_test # @@ -437,6 +441,7 @@ def single_submit_impl(machine_name, test_id, proc_pool, project, args, job_cost directives = directives.replace("{{ job_queue }}", queue) if project is not None: directives = directives.replace("{{ project }}", project) + directives = directives.replace("{{ charge_account }}", charge_account) expect("{{" not in directives, "Could not resolve all items in directives:\n%s" % directives) diff --git a/cime/scripts/lib/CIME/XML/env_batch.py b/cime/scripts/lib/CIME/XML/env_batch.py index 25dbc772cb3a..58bcd9fac22c 100644 --- a/cime/scripts/lib/CIME/XML/env_batch.py +++ b/cime/scripts/lib/CIME/XML/env_batch.py @@ -503,8 +503,8 @@ def get_all_queues(self): return self.get_nodes("queue") def get_nodes(self, nodename, attributes=None, root=None, xpath=None): - if nodename in ("JOB_WALLCLOCK_TIME", "PROJECT", "PROJECT_REQUIRED", - "JOB_QUEUE", "BATCH_COMMAND_FLAGS"): + if nodename in ("JOB_WALLCLOCK_TIME", "PROJECT", "CHARGE_ACCOUNT", + "PROJECT_REQUIRED", "JOB_QUEUE", "BATCH_COMMAND_FLAGS"): nodes = EnvBase.get_nodes(self, "entry", attributes={"id":nodename}, root=root, xpath=xpath) else: diff --git a/cime/scripts/lib/CIME/case.py b/cime/scripts/lib/CIME/case.py index 81ac7911a3e2..12ed8091f43f 100644 --- a/cime/scripts/lib/CIME/case.py +++ b/cime/scripts/lib/CIME/case.py @@ -9,7 +9,8 @@ from CIME.XML.standard_module_setup import * from CIME.utils import expect, get_cime_root, append_status -from CIME.utils import convert_to_type, get_model, get_project +from CIME.utils import convert_to_type, get_model +from CIME.utils import get_project, get_charge_account from CIME.utils import get_current_commit from CIME.check_lockedfiles import LOCKED_DIR, lock_file from CIME.XML.machines import Machines @@ -775,6 +776,11 @@ def configure(self, compset_name, grid_name, machine_name=None, self.set_value("PROJECT", project) elif machobj.get_value("PROJECT_REQUIRED"): expect(project is not None, "PROJECT_REQUIRED is true but no project found") + # Get charge_account id if it exists + charge_account = get_charge_account(machobj) + if charge_account is not None: + self.set_value("CHARGE_ACCOUNT", charge_account) + # Resolve the CIME_OUTPUT_ROOT variable, other than this # we don't want to resolve variables until we need them diff --git a/cime/scripts/lib/CIME/utils.py b/cime/scripts/lib/CIME/utils.py index 06cf1e14dc29..755a6c200d0f 100644 --- a/cime/scripts/lib/CIME/utils.py +++ b/cime/scripts/lib/CIME/utils.py @@ -618,6 +618,36 @@ def get_project(machobj=None): logger.info("No project info available") return None +def get_charge_account(machobj=None): + """ + Hierarchy for choosing CHARGE_ACCOUNT: + 1. Environment variable CHARGE_ACCOUNT + 2. File $HOME/.cime/config + 3. config_machines.xml (if machobj provided) + 4. default to same value as PROJECT + """ + charge_account = os.environ.get("CHARGE_ACCOUNT") + if (charge_account is not None): + logger.info("Using charge_account from env CHARGE_ACCOUNT: " + charge_account) + return charge_account + + cime_config = get_cime_config() + if (cime_config.has_option('main','CHARGE_ACCOUNT')): + charge_account = cime_config.get('main','CHARGE_ACCOUNT') + if (charge_account is not None): + logger.info("Using charge_account from .cime/config: " + charge_account) + return charge_account + + if machobj is not None: + charge_account = machobj.get_value("CHARGE_ACCOUNT") + if charge_account is not None: + logger.info("Using charge_account from config_machines.xml: " + charge_account) + return charge_account + + logger.info("No charge_account info available, using value from PROJECT") + return get_project(machobj) + + def setup_standard_logging_options(parser): helpfile = "%s.log"%sys.argv[0] helpfile = os.path.join(os.getcwd(),os.path.basename(helpfile)) diff --git a/cime/src/drivers/mct/cime_config/config_component.xml b/cime/src/drivers/mct/cime_config/config_component.xml index 687564833680..0ac48b371bec 100644 --- a/cime/src/drivers/mct/cime_config/config_component.xml +++ b/cime/src/drivers/mct/cime_config/config_component.xml @@ -2608,6 +2608,14 @@ project for project-sensitive build and run paths, and job scripts + + char + + job_submission + env_batch.xml + project to charge in scripts if different from PROJECT + + char unknown From af58e62219aa083e1f696428e3d4d548c15c39b7 Mon Sep 17 00:00:00 2001 From: Jason Sarich Date: Tue, 15 Aug 2017 13:30:27 -0500 Subject: [PATCH 2/4] whitespace edits --- cime/scripts/create_newcase | 1 - cime/scripts/create_test | 1 - 2 files changed, 2 deletions(-) diff --git a/cime/scripts/create_newcase b/cime/scripts/create_newcase index 2196f85e82db..627c0b60f42f 100755 --- a/cime/scripts/create_newcase +++ b/cime/scripts/create_newcase @@ -59,7 +59,6 @@ OR parser.add_argument("--project", "-project", help="Specify a project id") - parser.add_argument("--pecount", "-pecount", default="M", help="Specify a target size description for the number of cores" "Allowed options are ('S','M','L','X1','X2','[0-9]x[0-9]','[0-9]')") diff --git a/cime/scripts/create_test b/cime/scripts/create_test index 218ff21f39ce..9a5d01ee2402 100755 --- a/cime/scripts/create_test +++ b/cime/scripts/create_test @@ -183,7 +183,6 @@ OR "Used for accounting when on a batch system." "The default is user-specified environment variable PROJECT") - parser.add_argument("-t", "--test-id", help="Specify an 'id' for the test. This is simply a" "string that is appended to the end of a test name." From a75aa60c0203cce15a9e544b0358b4b57d8375f6 Mon Sep 17 00:00:00 2001 From: Jason Sarich Date: Wed, 16 Aug 2017 10:11:30 -0500 Subject: [PATCH 3/4] Add simple doctests to get_charge_account --- cime/scripts/lib/CIME/utils.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cime/scripts/lib/CIME/utils.py b/cime/scripts/lib/CIME/utils.py index 755a6c200d0f..81c8d48b892e 100644 --- a/cime/scripts/lib/CIME/utils.py +++ b/cime/scripts/lib/CIME/utils.py @@ -625,6 +625,18 @@ def get_charge_account(machobj=None): 2. File $HOME/.cime/config 3. config_machines.xml (if machobj provided) 4. default to same value as PROJECT + + >>> import CIME + >>> import CIME.XML.machines + >>> machobj = CIME.XML.machines.Machines(machine="theta") + >>> project = get_project(machobj) + >>> charge_account = get_charge_account(machobj) + >>> project == charge_account + True + >>> os.environ["CHARGE_ACCOUNT"] = "ChargeAccount" + >>> get_charge_account(machobj) + 'ChargeAccount' + >>> reset_cime_config() """ charge_account = os.environ.get("CHARGE_ACCOUNT") if (charge_account is not None): From a8d4242bf41e53405aaeaa8163406816042a34ab Mon Sep 17 00:00:00 2001 From: Jason Sarich Date: Fri, 18 Aug 2017 09:27:39 -0500 Subject: [PATCH 4/4] unset CHARGE_ACCOUNT environment variable in tests --- cime/scripts/lib/CIME/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime/scripts/lib/CIME/utils.py b/cime/scripts/lib/CIME/utils.py index 81c8d48b892e..5f28b061b563 100644 --- a/cime/scripts/lib/CIME/utils.py +++ b/cime/scripts/lib/CIME/utils.py @@ -636,7 +636,7 @@ def get_charge_account(machobj=None): >>> os.environ["CHARGE_ACCOUNT"] = "ChargeAccount" >>> get_charge_account(machobj) 'ChargeAccount' - >>> reset_cime_config() + >>> del os.environ["CHARGE_ACCOUNT"] """ charge_account = os.environ.get("CHARGE_ACCOUNT") if (charge_account is not None):