Fix stale-partial reuse and n_chunks mismatch in analysis condor pipeline
- prep() now clears reduced_partial/ and reduced/ on every (re-)run. Partial files carry no record of what context (n_chunks, bin edges, group sets) they were computed under, so re-prepping the same run_dir with a different --chunks/--bins/--top-pdg (or after the rollout was regenerated) previously left old partials on disk that merge_one would silently merge against the new shared.json — producing a wrong-but-plausible reduced/*.json with no error. - write_submit() now checks SubmitConfig.n_chunks against the run directory's own RunMeta.n_chunks (fixed at prep time, and what rows_per_chunk is sized against) and raises a clear error on mismatch, instead of an uncaught IndexError deep in _job_walltimes. Each fix has a regression test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,26 @@ def test_prep_splits_rows_per_chunk(tmp_path: Path):
|
||||
assert sum(meta.rows_per_chunk) == meta.total_rows == 8
|
||||
|
||||
|
||||
def test_reprep_clears_stale_partials_from_a_different_chunk_count(tmp_path: Path):
|
||||
"""Re-prepping with a different n_chunks must not leave old chunk
|
||||
partials on disk for merge_one to silently merge against the new
|
||||
context (they'd be keyed/sized for the old n_chunks)."""
|
||||
yaml_path = _write_inputs(tmp_path)
|
||||
run_dir = _prep(yaml_path, chunks=2)
|
||||
compute_one("marginal_edep", run_dir, chunk_index=0)
|
||||
compute_one("marginal_edep", run_dir, chunk_index=1)
|
||||
stale = run_dir / "reduced_partial" / "marginal_edep__0.json"
|
||||
assert stale.exists()
|
||||
(run_dir / "reduced").mkdir(exist_ok=True)
|
||||
(run_dir / "reduced" / "marginal_edep.json").write_text("{}")
|
||||
|
||||
_prep(yaml_path, run_dir, chunks=1)
|
||||
|
||||
assert not stale.exists()
|
||||
assert not (run_dir / "reduced" / "marginal_edep.json").exists()
|
||||
assert (run_dir / "shared.json").exists() # prep's own fresh output untouched
|
||||
|
||||
|
||||
def test_compute_one_from_run_dir(tmp_path: Path):
|
||||
run_dir = _prep(_write_inputs(tmp_path))
|
||||
out = compute_one("marginal_edep", run_dir)
|
||||
@@ -237,6 +257,20 @@ def test_write_submit_chunks_respect_chunkable(tmp_path: Path):
|
||||
assert counts["router_gating"] == 1 # chunkable=False, ignores n_chunks
|
||||
|
||||
|
||||
def test_write_submit_rejects_n_chunks_mismatch_with_run_meta(tmp_path: Path):
|
||||
"""cfg.n_chunks must match the n_chunks the run_dir was actually prepped
|
||||
with — RunMeta.rows_per_chunk is sized to the prepped value, so a
|
||||
mismatch would otherwise surface as a confusing IndexError deep inside
|
||||
_job_walltimes instead of a clear error here."""
|
||||
run_dir = _prep(_write_inputs(tmp_path), chunks=2)
|
||||
_fake_venv(tmp_path)
|
||||
cfg = SubmitConfig(
|
||||
run_dir=run_dir, accounting_group="cms", repo_dir=tmp_path, n_chunks=4
|
||||
)
|
||||
with pytest.raises(ValueError, match="n_chunks"):
|
||||
write_submit(cfg)
|
||||
|
||||
|
||||
def test_estimate_runtime_s_scales_with_rows_and_margin():
|
||||
from giant.analysis import RUNTIME_SAFETY_MARGIN, estimate_runtime_s
|
||||
from giant.analysis.runtime_estimate import _FIXED_OVERHEAD_S
|
||||
|
||||
Reference in New Issue
Block a user