RadCluster
Graph-based cluster dynamics for irradiated materials
Loading...
Searching...
No Matches
Functions | Variables
campaign_ops Namespace Reference

Functions

Path|None find_solver ()
 
str sha256_file (p)
 
float _newest_source_mtime ()
 
dict solver_info ()
 
dict ensure_solver (bool force=False, bool verbose=True)
 
dict environment ()
 
Path request_stop (str reason="user requested")
 
None clear_stop ()
 
dict|None stop_requested ()
 
 _git (*args, check=True)
 
dict sync_results (int|None machine=None, str|None design_stem=None, bool push=True, bool verbose=True)
 
dict load_targets (Path|None path=None)
 
tuple[list[dict], dict] read_design (Path design)
 
bool _same_design (row_sha, design_sha)
 
dict[int, dict] load_results (Path results_dir, str|None design_sha=None)
 
dict campaign_status (Path design, Path results_dir, int n_machines=4, int|None workers_per_machine=None)
 
 _fmt_hms (s)
 
list[dict] observable_summary (list[dict] admis, dict targets)
 
None render_status (dict st, dict|None targets=None)
 
dict watch (Path design, Path results_dir, int n_machines=4, int|None workers_per_machine=None, float interval=60.0, int iterations=10_000, dict|None targets=None)
 

Variables

 HERE = Path(__file__).resolve().parent
 
 REPO = HERE.parent.parent
 
str MODULE = REPO / "radcluster_code"
 
str STOP_FILE = HERE / "CAMPAIGN_STOP"
 

Detailed Description

campaign_ops - build, monitor and stop control for the digital-twin campaign.

Everything the control notebook drives lives here so the notebook cells stay
thin and this logic stays testable from a shell.

Three groups:

  BUILD        ensure_solver()    - verify or compile the C++ solver for THIS
                                    machine.  The binary is not in git, so each
                                    machine must build its own.

  STOP CONTROL request_stop()     - graceful halt.  Writes a sentinel that
                                    run_ensemble checks between rows: it stops
                                    submitting new work, lets in-flight rows
                                    finish and be written, then exits cleanly.
                                    Nothing is lost and the campaign resumes
                                    from where it stopped.

  STATUS       campaign_status()  - coverage, per-machine progress, timing and
                                    remaining-compute estimate, observables
                                    against the experimental bands, and the
                                    reasons rows were rejected.

Function Documentation

◆ _fmt_hms()

campaign_ops._fmt_hms (   s)
protected

Definition at line 431 of file campaign_ops.py.

◆ _git()

campaign_ops._git ( *  args,
  check = True 
)
protected

Definition at line 200 of file campaign_ops.py.

◆ _newest_source_mtime()

float campaign_ops._newest_source_mtime ( )
protected

Definition at line 60 of file campaign_ops.py.

◆ _same_design()

bool campaign_ops._same_design (   row_sha,
  design_sha 
)
protected
Compare design hashes that may be stored at different lengths.

The rows carry a 16-char prefix (run_ensemble truncates for compactness)
while design/<name>.meta.json holds the full 64-char digest.  A naive ==
is therefore always False, which silently rejects EVERY row -- the
filter's failure mode is to discard the whole campaign rather than to let
a stale one through, so it must be prefix-aware.

Definition at line 308 of file campaign_ops.py.

◆ campaign_status()

dict campaign_ops.campaign_status ( Path  design,
Path  results_dir,
int   n_machines = 4,
int | None   workers_per_machine = None 
)

Definition at line 352 of file campaign_ops.py.

◆ clear_stop()

None campaign_ops.clear_stop ( )

Definition at line 171 of file campaign_ops.py.

◆ ensure_solver()

dict campaign_ops.ensure_solver ( bool   force = False,
bool   verbose = True 
)
Verify the solver, and build it if missing, stale, or force=True.

'Stale' means a .cpp/.h/CMakeLists is newer than the binary -- the exact
situation that silently produces results from code you think you replaced.

Definition at line 82 of file campaign_ops.py.

◆ environment()

dict campaign_ops.environment ( )

Definition at line 136 of file campaign_ops.py.

◆ find_solver()

Path | None campaign_ops.find_solver ( )

Definition at line 44 of file campaign_ops.py.

◆ load_results()

dict[int, dict] campaign_ops.load_results ( Path  results_dir,
str | None   design_sha = None 
)
Rows from results/*.jsonl, optionally restricted to ONE design.

design_sha matters more than it looks.  row_id is unique within a design
but not across designs, so pooling every .jsonl in the directory lets a
superseded campaign's row 25 overwrite the current one's -- silently, and
with a plausible-looking value.  Before this filter, T2_design_v2_* rows
left in results/ made the T3 campaign report 234 of 480 rows done on
machine 0 when 4 existed.

Definition at line 323 of file campaign_ops.py.

◆ load_targets()

dict campaign_ops.load_targets ( Path | None   path = None)

Definition at line 289 of file campaign_ops.py.

◆ observable_summary()

list[dict] campaign_ops.observable_summary ( list[dict]  admis,
dict  targets 
)
Where the ensemble sits relative to each experimental band.

Definition at line 438 of file campaign_ops.py.

◆ read_design()

tuple[list[dict], dict] campaign_ops.read_design ( Path  design)

Definition at line 294 of file campaign_ops.py.

◆ render_status()

None campaign_ops.render_status ( dict  st,
dict | None   targets = None 
)
Human-readable campaign report.

Definition at line 463 of file campaign_ops.py.

◆ request_stop()

Path campaign_ops.request_stop ( str   reason = "user requested")
Ask every running worker on THIS machine to stop gracefully.

Workers finish the rows already in flight, write them, and exit 0.  No row
is lost and no partial row is written, so a later restart resumes cleanly.

Definition at line 155 of file campaign_ops.py.

◆ sha256_file()

str campaign_ops.sha256_file (   p)

Definition at line 53 of file campaign_ops.py.

◆ solver_info()

dict campaign_ops.solver_info ( )

Definition at line 71 of file campaign_ops.py.

◆ stop_requested()

dict | None campaign_ops.stop_requested ( )

Definition at line 179 of file campaign_ops.py.

◆ sync_results()

dict campaign_ops.sync_results ( int | None   machine = None,
str | None   design_stem = None,
bool   push = True,
bool   verbose = True 
)
Commit this machine's result files and exchange them with the remote.

Safe to call while the campaign is running: run_ensemble appends to the
.jsonl, so the worst case is that the newest row lands in the next sync.
Returns a dict rather than printing only, so the notebook can assert on it.

Definition at line 207 of file campaign_ops.py.

◆ watch()

dict campaign_ops.watch ( Path  design,
Path  results_dir,
int   n_machines = 4,
int | None   workers_per_machine = None,
float   interval = 60.0,
int   iterations = 10_000,
dict | None   targets = None 
)
Live monitor. Interrupt the cell (kernel stop) to leave it.

Definition at line 526 of file campaign_ops.py.

Variable Documentation

◆ HERE

campaign_ops.HERE = Path(__file__).resolve().parent

Definition at line 37 of file campaign_ops.py.

◆ MODULE

str campaign_ops.MODULE = REPO / "radcluster_code"

Definition at line 39 of file campaign_ops.py.

◆ REPO

campaign_ops.REPO = HERE.parent.parent

Definition at line 38 of file campaign_ops.py.

◆ STOP_FILE

str campaign_ops.STOP_FILE = HERE / "CAMPAIGN_STOP"

Definition at line 40 of file campaign_ops.py.