114 lines
5.2 KiB
Python
114 lines
5.2 KiB
Python
"""Uniform experimental full9 DFG pilot; CPU preflight unless explicitly admitted."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import math
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import time
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parents[2]
|
|
sys.path.insert(0, str(HERE.parent / 'uniform_srt_diagnostic'))
|
|
import diagnose_uniform_srt as diagnostic
|
|
|
|
VARIANT = 'experimental_regularized_full9'
|
|
OBSERVATION = 'uniform_sparse_pilot_v1'
|
|
|
|
|
|
def configuration(source):
|
|
if source.resolve() != ROOT.resolve():
|
|
raise ValueError('Source must equal executing harness checkout')
|
|
cfg, body, p, manifest = diagnostic.source_config(source, HERE / 'dfg_source_manifest.json')
|
|
cfg['method']['inlet']['scheme'] = VARIANT
|
|
return cfg, body, p, manifest
|
|
|
|
|
|
def accuracy_pass(result):
|
|
"""Standard later qualification predicate; pilot never qualifies accuracy."""
|
|
return (result.get('healthy') is True and result.get('periodic') is True
|
|
and result.get('reference_comparison', {}).get('reference_agreement') is True)
|
|
|
|
|
|
def identity(manifest):
|
|
return dict(experimental_variant=VARIANT, collision='SRT', control='with_cylinder',
|
|
observation_mode=OBSERVATION, numerical_source_commit=manifest['commit'],
|
|
manifest_sha256=hashlib.sha256((HERE / 'dfg_source_manifest.json').read_bytes()).hexdigest())
|
|
|
|
|
|
def verify_pilot(result, expected):
|
|
import run_refined_dfg as runner
|
|
runner.ensure_finite(result)
|
|
if any(result.get(k) != v for k, v in expected.items()):
|
|
raise ValueError('Pilot identity mismatch')
|
|
if (result.get('case') != 'uniform' or result.get('mode') != 'pilot'
|
|
or result.get('status') != 'pilot_complete' or result.get('healthy') is not True
|
|
or result.get('steps') != 40000 or result.get('executed_steps') != 40000):
|
|
raise ValueError('Incomplete or mislabeled pilot')
|
|
timings = result.get('calibration_batches_seconds', [])
|
|
if len(timings) != 5 or any(isinstance(v, bool) or not isinstance(v, (int, float)) or v <= 0 for v in timings):
|
|
raise ValueError('Missing positive calibration timings')
|
|
rows = result.get('history', [])
|
|
if len(rows) != 10:
|
|
raise ValueError('Incomplete sparse pilot history')
|
|
for i, row in enumerate(rows, 1):
|
|
for key in ('cd', 'cl', 'mass', 'flux_in', 'flux_out', 'dp'):
|
|
if isinstance(row.get(key), bool) or not isinstance(row.get(key), (int, float)):
|
|
raise ValueError('Missing numeric pilot observation')
|
|
if (row.get('step') != i * 4000 or row.get('tstar') != i * .5
|
|
or row.get('tstar_force') != i * .5 - .25
|
|
or not .5 <= row.get('rho_min', 0) <= row.get('rho_max', 2) <= 1.5
|
|
or not 0 <= row.get('max_mach', 1) <= .2):
|
|
raise ValueError('Invalid sparse pilot observation')
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--source', type=Path, default=ROOT)
|
|
parser.add_argument('--output', 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=180.)
|
|
a = parser.parse_args()
|
|
a.source = a.source.resolve()
|
|
cfg, body, p, manifest = configuration(a.source)
|
|
import run_refined_dfg as runner
|
|
from source_provenance import checkout_provenance
|
|
h, periodic = runner.helpers(a.source)
|
|
if not math.isfinite(a.wall_seconds) or a.wall_seconds <= 0:
|
|
raise ValueError('Finite positive wall ceiling required')
|
|
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 = identity(manifest)
|
|
receipt['checkout'] = checkout_provenance(ROOT)
|
|
diagnostic.dump(a.output / 'preflight.json', dict(**receipt, config=cfg, body=body,
|
|
parameters=p, source=manifest, max_steps=40000, cap_tstar=5.,
|
|
observation_width_tstar=.5, force_batch_steps=100,
|
|
calibration='First 100 steps warmup; next 400 timed, counted in physical trajectory',
|
|
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 = 'pilot'
|
|
a.deadline = time.monotonic() + a.wall_seconds
|
|
progress = {}
|
|
try:
|
|
result = runner.run_case(a, h, periodic, 'uniform', inlet_scheme=VARIANT,
|
|
sparse_pilot=True, receipt_identity=receipt, progress=progress)
|
|
except TimeoutError:
|
|
diagnostic.dump(a.output / 'result.json', dict(**receipt, status='wall_time_limit',
|
|
healthy=False, accuracy_qualified=False, **progress))
|
|
return 3
|
|
if result['healthy']:
|
|
verify_pilot(result, receipt)
|
|
diagnostic.dump(a.output / 'result.json', dict(**result, accuracy_qualified=False))
|
|
return 0 if result['healthy'] else 2
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|