116 lines
6.2 KiB
Python
116 lines
6.2 KiB
Python
"""Separately admitted full uniform DFG qualification after the pinned sparse pilot."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import math
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import time
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(HERE))
|
|
import run_dfg as pilot
|
|
|
|
OBSERVATION = 'uniform_standard_full_v1'
|
|
|
|
|
|
def configuration(source):
|
|
cfg, body, parameters, pilot_manifest = pilot.configuration(source)
|
|
_, _, _, full_manifest = pilot.diagnostic.source_config(source, HERE / 'dfg_full_source_manifest.json')
|
|
return cfg, body, parameters, pilot_manifest, full_manifest
|
|
|
|
|
|
def admit_pilot(path, cfg, body, parameters, manifest):
|
|
import run_refined_dfg as runner
|
|
expected = pilot.identity(manifest)
|
|
result = runner.read_finite_json(path / 'result.json')
|
|
preflight = runner.read_finite_json(path / 'preflight.json')
|
|
ready = runner.read_finite_json(path / 'uniform/ready.json')
|
|
pilot.verify_pilot(result, expected)
|
|
for name, document in [('preflight', preflight), ('ready', ready)]:
|
|
if any(document.get(k) != v for k, v in expected.items()):
|
|
raise ValueError('Pilot ' + name + ' identity mismatch')
|
|
if (preflight.get('config') != cfg or preflight.get('body') != body
|
|
or preflight.get('parameters') != parameters or preflight.get('source') != manifest
|
|
or preflight.get('max_steps') != 40000 or preflight.get('cap_tstar') != 5.
|
|
or preflight.get('observation_width_tstar') != .5
|
|
or preflight.get('gates') != runner.helpers(pilot.ROOT)[1].GATES
|
|
or preflight.get('reference_gates') != runner.helpers(pilot.ROOT)[1].REFERENCE_GATES):
|
|
raise ValueError('Pilot physical plan or gates mismatch')
|
|
if (ready.get('case') != 'uniform' or ready.get('mode') != 'pilot'
|
|
or ready.get('step') != 4000 or ready.get('tstar') != .5
|
|
or ready.get('runner_sha256') != runner.runner_hash()
|
|
or ready.get('all_runtime_and_observation_paths_exercised') is not True
|
|
or ready.get('calibration_batches_seconds') != result.get('calibration_batches_seconds')):
|
|
raise ValueError('Pilot READY mismatch')
|
|
checkout = result.get('checkout')
|
|
if (checkout != preflight.get('checkout') or checkout != ready.get('checkout')
|
|
or not isinstance(checkout, dict) or checkout.get('checkout_dirty') is not False
|
|
or checkout.get('checkout_revision') != 'c0be841b2e6e1ccba3b8343cecd3cee2fe0ed14f'):
|
|
raise ValueError('Pilot checkout provenance mismatch')
|
|
for key in ['startup_seconds', 'step_seconds', 'wall_seconds']:
|
|
value = result.get(key)
|
|
if isinstance(value, bool) or not isinstance(value, (float, int)) or value <= 0:
|
|
raise ValueError('Invalid pilot timing')
|
|
return dict(result_sha256=hashlib.sha256((path/'result.json').read_bytes()).hexdigest(),
|
|
checkout=checkout, startup_seconds=result['startup_seconds'],
|
|
step_seconds=result['step_seconds'], wall_seconds=result['wall_seconds'],
|
|
step_force_scaled_seconds=60 * result['step_seconds'])
|
|
|
|
|
|
def qualified(result):
|
|
return (result.get('mode') == 'full' and result.get('case') == 'uniform'
|
|
and result.get('steps') == 2400000 and result.get('executed_steps') == 2400000
|
|
and pilot.accuracy_pass(result))
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--source', type=Path, default=pilot.ROOT)
|
|
parser.add_argument('--output', type=Path, required=True)
|
|
parser.add_argument('--pilot-results', type=Path, required=True)
|
|
parser.add_argument('--execute', action='store_true')
|
|
parser.add_argument('--gpu-admitted', action='store_true')
|
|
parser.add_argument('--wall-seconds', type=float, default=720.)
|
|
a = parser.parse_args(); a.source = a.source.resolve()
|
|
cfg, body, parameters, pilot_manifest, full_manifest = configuration(a.source)
|
|
import run_refined_dfg as runner
|
|
from source_provenance import checkout_provenance
|
|
h, periodic = runner.helpers(a.source)
|
|
admission = admit_pilot(a.pilot_results, cfg, body, parameters, pilot_manifest)
|
|
if not math.isfinite(a.wall_seconds) or not 0 < a.wall_seconds <= 720:
|
|
raise ValueError('Full-run internal ceiling must be positive and at most720 seconds')
|
|
if a.execute and (not a.gpu_admitted or not os.environ.get('CUDA_VISIBLE_DEVICES')):
|
|
raise ValueError('Explicit GPU admission and device selection required')
|
|
if a.output.exists() and any(a.output.iterdir()):
|
|
raise ValueError('Use new/empty output directory')
|
|
a.output.mkdir(parents=True, exist_ok=True)
|
|
receipt = dict(experimental_variant=pilot.VARIANT, collision='SRT', control='with_cylinder',
|
|
observation_mode=OBSERVATION, numerical_source_commit=full_manifest['commit'],
|
|
manifest_sha256=hashlib.sha256((HERE/'dfg_full_source_manifest.json').read_bytes()).hexdigest(),
|
|
checkout=checkout_provenance(pilot.ROOT), pilot_admission=admission)
|
|
pilot.diagnostic.dump(a.output/'preflight.json', dict(**receipt, config=cfg, body=body,
|
|
parameters=parameters, source=full_manifest, max_steps=2400000, cap_tstar=300.,
|
|
observations='t*=.5 before240; .02 thereafter; forces at interval midpoint, pressure at endpoint',
|
|
initialization='Original production initialization; restart, no pilot continuation',
|
|
gates=periodic.GATES, reference_gates=periodic.REFERENCE_GATES,
|
|
wall_seconds=a.wall_seconds, executed=False, accuracy_qualified=False))
|
|
if not a.execute: return 0
|
|
a.mode = 'full'; a.deadline = time.monotonic() + a.wall_seconds
|
|
progress = {}
|
|
try:
|
|
result = runner.run_case(a, h, periodic, 'uniform', inlet_scheme=pilot.VARIANT,
|
|
sparse_pilot=True, receipt_identity=receipt, progress=progress)
|
|
except TimeoutError:
|
|
pilot.diagnostic.dump(a.output/'result.json', dict(**receipt, status='wall_time_limit',
|
|
healthy=False, accuracy_qualified=False, **progress))
|
|
return 3
|
|
passed = qualified(result)
|
|
pilot.diagnostic.dump(a.output/'result.json', dict(**result, accuracy_qualified=passed))
|
|
return 0 if passed else 2
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|