aeolus1d run, end to end¶
What the command line does between aeolus1d run case.toml and the exit code:
argument parsing, the pre-flight refusals, the optional resume, the run, the
result file with its manifest, and which exit code each failure becomes. The
chart is the command's seams. What happens inside the stages has charts of
its own: the load, the pre-flight, the choice of driver and the write are in
Case load, build, run, write; the resume in
Resume from a checkpoint. The contract of every function below is
in its docstring (the standard is Function contracts and flow
charts).
What enters: argv. What leaves: an exit code, log lines (INFO and below on
stdout, warnings and errors on stderr), and with --out an HDF5 result plus
<out stem>.manifest.json, with --cgns a CGNS file.
flowchart TD
A["argv: [-q | -v] run CASE flags"] --> P{"build_parser().parse_args"}
P -- "bad type, bad choice, -q with -v, missing CASE" --> E2["SystemExit 2, usage on stderr"]
P --> V["_apply_global_verbosity: -q WARNING, -v DEBUG"]
V --> R["_cmd_run"]
R --> UC{"--allow-user-code?"}
UC -- yes --> ENV1["AEOLUS_ALLOW_USER_CODE = 1, never cleared"]
UC -- no --> LG
ENV1 --> LG["_configure_run_logging: level, run id, case digest; --log-json also sets AEOLUS_QUIET_SETTINGS, never cleared"]
LG --> LP{"_load_and_preflight: load_case"}
LP -- "missing file, bad TOML, unknown key, invalid case" --> M2["main prints the curated message: exit 2"]
LP --> OV["--chem-every-n / -rtol / -atol written into the case"]
OV --> PF{"validate_case_pre_run, then _refuse_bad_run_args"}
PF -- "ValueError" --> X2["ERROR: aeolus1d: refusing to run - reason; exit 2, nothing written"]
PF --> RS{"_read_resume (only with --resume)"}
RS -- "ResumeError, naming the file" --> X1["ERROR: resume failed: ...; exit 1"]
RS --> SG["_build_live_control, _install_stop_signal_handlers: SIGINT / SIGTERM ask for a clean stop"]
SG --> EG{"--trace-dt, a resume or controllers?"}
EG -- yes --> AE["_advance_eager: _build_eager_network (resume seeds), _build_tracer, dispatch_advance"]
EG -- no --> AP["_advance_plain: run_case"]
AE --> ADV{"advance"}
AP --> ADV
ADV -- "max_steps watchdog, NonAdvancingStepError" --> M1["main prints one line: exit 1, no result file"]
ADV -- "any other exception" --> TB["traceback"]
ADV -- "t_end reached, or a stop was requested" --> FR["_finish_run: stop note, flush-failure count, _print_run_summary"]
FR --> WO{"_write_run_outputs"}
WO -- "--out" --> H5["write_hdf5, then the manifest (resume_sha256 from _read_resume)"]
WO -- "--cgns" --> CG["write_cgns"]
WO -- "a write fails" --> M3["missing directory: main prints it, exit 2; any other OSError: traceback"]
H5 --> OK["exit 0"]
CG --> OK
WO -- "neither" --> OK
The signal handlers are put back in a finally whichever way the advance and
the write end.
Exit codes¶
| Code | When | Message |
|---|---|---|
| 0 | the run finished, or stopped cleanly on SIGINT / SIGTERM, and the outputs were written | the summary on stdout |
| 1 | --resume file unreadable or not a checkpoint |
resume failed: <file>: ... (stderr) |
| 1 | the --max-steps cap was reached; a driver assembled a non-advancing dt |
one line from main; no result file is written |
| 2 | a flag the pre-flight refuses | aeolus1d: refusing to run - <reason> (stderr) |
| 2 | the case file is missing, unparsable or invalid | the curated message of load_case, naming the file |
| 2 | a write hits a missing directory (FileNotFoundError) |
error: <message> |
| 2 | argparse refuses the arguments | usage and the reason (stderr) |
| traceback | any other exception (KeyError, another RuntimeError, a permission error) |
not mapped |
What the pre-flight refuses¶
_refuse_bad_run_args (after validate_case_pre_run), each with the flag and
the value in the message, before anything is built or written:
--info-every-nbelow 1;--trace-dtnot above 0 (NaN included).--progress-dtor--live-flush-intervalnegative or NaN (0 keeps its meaning: the default cadence, flush at every new sample).--trace-max-snapshotsnegative or 1 (0 means unbounded, 2 and up is a cap).--cgnswith--live-flush-interval,--outand--trace-dt(the CGNS file would get no time series)._refuse_bad_output_paths: an--outor--cgnswhose directory does not exist (it used to fail after the whole run), an output that is the case file, and--cgnsequal to--out.
--out equal to --resume is not refused. It is the documented way to
extend a result in place; the manifest keeps the digest of the file that was
read, and a failed write loses the checkpoint (write_hdf5 truncates its
target first).
State the command leaves behind¶
aeolus1d run is a one-shot process, so none of this matters from the shell.
It does when main is called in-process (the test suite, an embedding):
AEOLUS_ALLOW_USER_CODE=1after--allow-user-code, never cleared (a maintainer decision,BACKLOG.md: "Two security-relevant findings in the user-code loader").AEOLUS_QUIET_SETTINGS=1after--log-json(and afterwarmup, which sets it when unset), never cleared.- The
aeolus1dlogger's handlers, level and run id (-q/-vand--log-levelset the level). - Matplotlib's backend after
turbo-map(notrun).
Functions¶
src/aeolus1d/cli/main.py::build_parsersrc/aeolus1d/cli/main.py::_apply_global_verbositysrc/aeolus1d/cli/main.py::mainsrc/aeolus1d/cli/commands/run.py::_add_run_argssrc/aeolus1d/cli/commands/run.py::_cmd_runsrc/aeolus1d/cli/commands/run.py::_configure_run_loggingsrc/aeolus1d/cli/commands/run.py::_case_file_hashsrc/aeolus1d/cli/commands/run.py::_load_and_preflightsrc/aeolus1d/cli/commands/run.py::_refuse_bad_run_argssrc/aeolus1d/cli/commands/run.py::_refuse_bad_output_pathssrc/aeolus1d/cli/commands/run.py::_read_resumesrc/aeolus1d/cli/commands/run.py::_build_live_controlsrc/aeolus1d/cli/commands/run.py::_install_stop_signal_handlerssrc/aeolus1d/cli/commands/run.py::_advance_eagersrc/aeolus1d/cli/commands/run.py::_advance_plainsrc/aeolus1d/cli/commands/run.py::_build_eager_networksrc/aeolus1d/cli/commands/run.py::_build_tracersrc/aeolus1d/cli/commands/run.py::_StepHooks._maybe_live_flushsrc/aeolus1d/cli/commands/run.py::_finish_runsrc/aeolus1d/cli/commands/run.py::_print_run_summarysrc/aeolus1d/cli/commands/run.py::_write_run_outputssrc/aeolus1d/cli/commands/run.py::_manifest_overridessrc/aeolus1d/cli/_shared.py::_max_steps_messagesrc/aeolus1d/cli/_shared.py::_same_filesrc/aeolus1d/io/case.py::validate_case_pre_runsrc/aeolus1d/io/case.py::run_casesrc/aeolus1d/io/case.py::dispatch_advancesrc/aeolus1d/io/writer.py::write_hdf5src/aeolus1d/io/manifest.py::write_manifest