Skip to content

Commit

Permalink
Merge branch 'sarich/scripts/feature-charge-account' into master (PR #…
Browse files Browse the repository at this point in the history
…1718)

add option CHARGE_ACCOUNT to charge compute time if different from PROJECT

This option can be set by environment variable, in config_machines.xml, or
with xmlchange.
Helpful because PROJECT can be used for directory names that don't match
the name of the charge account.

Addresses issue #1588

* origin/sarich/scripts/feature-charge-account:
  unset CHARGE_ACCOUNT environment variable in tests
  Add simple doctests to get_charge_account
  whitespace edits
  add option CHARGE_ACCOUNT to charge compute time to if different from PROJECT
  • Loading branch information
jgfouca committed Aug 28, 2017
2 parents ec5366b + a8d4242 commit bffbbeb
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 8 deletions.
8 changes: 4 additions & 4 deletions cime/config/acme/machines/config_batch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<jobid_pattern>(\d+)</jobid_pattern>
<depend_string> --dependencies</depend_string>
<submit_args>
<arg flag="-A" name="PROJECT"/>
<arg flag="-A" name="$CHARGE_ACCOUNT"/>
<arg flag="-t" name="JOB_WALLCLOCK_TIME"/>
<arg flag="-n" name=" $TOTALPES/$PES_PER_NODE"/>
<arg flag="-q" name="JOB_QUEUE"/>
Expand All @@ -76,7 +76,7 @@
<submit_args>
<arg flag="-q" name="$JOB_QUEUE"/>
<arg flag="-W" name="$JOB_WALLCLOCK_TIME"/>
<arg flag="-P" name="$PROJECT"/>
<arg flag="-P" name="$CHARGE_ACCOUNT"/>
</submit_args>
<directives>
<directive > -n {{ total_tasks }} </directive>
Expand All @@ -101,7 +101,7 @@
<submit_args>
<arg flag="-q" name="$JOB_QUEUE"/>
<arg flag="-l walltime=" name="$JOB_WALLCLOCK_TIME"/>
<arg flag="-A" name="$PROJECT"/>
<arg flag="-A" name="$CHARGE_ACCOUNT"/>
</submit_args>
<directives>
<directive> -N {{ job_id }}</directive>
Expand All @@ -122,7 +122,7 @@
<walltime_format>%H:%M:%S</walltime_format>
<submit_args>
<arg flag="-l walltime=" name="$JOB_WALLCLOCK_TIME"/>
<arg flag="-A" name="$PROJECT"/>
<arg flag="-A" name="$CHARGE_ACCOUNT"/>
</submit_args>
<directives>
<directive> -N {{ job_id }}</directive>
Expand Down
4 changes: 4 additions & 0 deletions cime/config/xml_schemas/config_machines.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<xs:element name="PROXY" type="xs:string"/>
<xs:element name="SAVE_TIMING_DIR" type="xs:string" />
<xs:element name="PROJECT" type="xs:NCName" />
<xs:element name="CHARGE_ACCOUNT" type="xs:NCName" />
<xs:element name="COMPILERS" type="xs:string"/>
<xs:element name="MPILIBS" type="xs:string"/>
<xs:element name="CIME_OUTPUT_ROOT" type="xs:string"/>
Expand Down Expand Up @@ -72,6 +73,9 @@
<!-- PROJECT: A project or account number used for batch jobs
can be overridden in environment or $HOME/.cime/config -->
<xs:element ref="PROJECT" minOccurs="0" maxOccurs="1"/>
<!-- CHARGE_ACCOUNT: The name of the account to charge for batch jobs
can be overridden in environment or $HOME/.cime/config -->
<xs:element ref="SUBPROJECT" minOccurs="0" maxOccurs="1"/>
<!-- SAVE_TIMING_DIR: (Acme only) directory to write timing output to -->
<xs:element ref="SAVE_TIMING_DIR" minOccurs="0" maxOccurs="1"/>
<!-- CIME_OUTPUT_ROOT: Base directory for case output,
Expand Down
9 changes: 9 additions & 0 deletions cime/config/xml_schemas/config_machines_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@
<MPILIBS>mpt,openmpi,impi</MPILIBS>

<!-- PROJECT: A project or account number used for batch jobs
This value is used for directory names. If different from
actual accounting project id, use CHARGE_ACCOUNT
can be overridden in environment or $HOME/.cime/config -->
<PROJECT>couldbethis</PROJECT>

<!-- CHARGE_ACCOUNT: A project or account number used for batch jobs
This is the actual project used for cost accounting set in
the batch script (ex. #PBS -A charge_account). Will default
to PROJECT if not set.
can be overridden in environment or $HOME/.cime/config -->
<CHARGE_ACCOUNT></CHARGE_ACCOUNT>

<!-- SAVE_TIMING_DIR: (Acme only) directory to write timing output to -->
<SAVE_TIMING_DIR> </SAVE_TIMING_DIR>

Expand Down
6 changes: 5 additions & 1 deletion cime/scripts/create_test
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,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

Expand All @@ -369,6 +370,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
#
Expand Down Expand Up @@ -437,6 +440,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)

Expand Down
4 changes: 2 additions & 2 deletions cime/scripts/lib/CIME/XML/env_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 7 additions & 1 deletion cime/scripts/lib/CIME/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
42 changes: 42 additions & 0 deletions cime/scripts/lib/CIME/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,48 @@ 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
>>> 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'
>>> del os.environ["CHARGE_ACCOUNT"]
"""
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))
Expand Down
8 changes: 8 additions & 0 deletions cime/src/drivers/mct/cime_config/config_component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2608,6 +2608,14 @@
<desc>project for project-sensitive build and run paths, and job scripts</desc>
</entry>

<entry id="CHARGE_ACCOUNT">
<type>char</type>
<default_value></default_value>
<group>job_submission</group>
<file>env_batch.xml</file>
<desc>project to charge in scripts if different from PROJECT</desc>
</entry>

<entry id="MODEL_VERSION">
<type>char</type>
<default_value>unknown</default_value>
Expand Down

0 comments on commit bffbbeb

Please sign in to comment.