Repository navigation
Conversation
… models (lanl#1309) A DIFF says two paths disagree, not which is wrong, and a small own drift does not make an answer uncontested (lanl#1304: KLU on BIOMD0000000338 moved 1e-7 at a tenfold tighter tolerance while dense and libRoadRunner sat 3.5% away). Attribution: every DIFF whose comparison kept its two trajectories (Verdict now carries them, never written out) is put to third arms, run once per model: the base's own route at 100x tighter tolerances, the base on the other linear solver (dense for a KLU base, KLU otherwise), and libRoadRunner for SBML (concentrations as [id], as rr_parity selects). Each arm sides with the comparison's reference, its path, both or neither; the row's extra["attribution"] says which, and its verdict is the one side every arm took, or split. Branch stability: a stable check reruns the base at n_points -1 and +1 (read at the last point, which every grid shares), twice the points (read at the base's), and rtol x0.5 and x2. A jump past the bound is a DIFF marked contested. The report's meta lists every contested model: a stable DIFF, or a DIFF whose arms split (D.contested). lanl#1304's two models read contested with each arm's side named: 338 split (KLU tighter with KLU; dense and libRoadRunner with dense), 339 split (libRoadRunner gives up there and is left out). Over the corpus with every check: 13 contested; of 7 attributed DIFFs, 4 split and 3 with the reference; stable reads 10 DIFF, among them BIOMD0000000620 and 621, whose answer at t = 10 depends on the grid (Anakinrasc 14,222 at 101 points, the largest species 107 at 100 or 102: an event that fires on a sample). Controls: arms that split mark the model contested and arms that agree attribute the DIFF; a planted cc_vs_interp DIFF is attributed by real arms to the reference; an answer that jumps at rtol x2, or at n_points+1, is contested; lanl#1304's model reads split (skip-if-absent). Mutations caught: attribution always the reference, none in check_all, stable without either jitter, contested ignoring a split, no other-solver arm.
… cap (lanl#1309) The PR's nightly read 33 regressions, every one a TIMEOUT: the pool kills a model's worker at its 900 s cap, and every row of the model with it. BIOMD0000000810's checks take 8 s, but a jittered stable rerun ground on past the cap; MODEL1006230049, 0053 and 0077 took 716-751 s before stable reran them five times. check_all now takes a deadline, 0.9 of the cap: the existing checks run first, then the attribution's arms, then stable, each run bounded by what is left (run(timeout=)); none starts past it. A stable that does not finish is SKIP, said why, and the model keeps its other rows.
This was referenced Oct 27, 2026
…ution lanl#1321 bounds every run by the model's cap, which replaces the deadline 6357188 threaded through stable and the arms alone. The order stays: main's checks, then the attribution's arms, then stable, each starting only with time left. A stable the cap stops is TIMEOUT, as any check's is under lanl#1321, where it was SKIP.
… fix/1309-attribution
… fix/1309-attribution # Conflicts: # python/tests/test_differential_shapes.py
wshlavacek
pushed a commit
that referenced
this pull request
Oct 27, 2026
…inished The pool kills a model's worker at its cap (900 s on the nightly), and every row of the model with it. MODEL1006230049, 0053 and 0077 take 716-751 s of that on main, so any check a pull request added to every model turned all their rows TIMEOUT: #1315, #1318 and #1319 each read 27-36 regressions, none of them a finding. check_all now takes a deadline, 0.9 of the cap. Every run has until it (run(timeout=)), no run or check starts past it, and a check that does not finish is its own TIMEOUT, said why. Each verdict is written as it is reached, so a worker the pool still kills (one compiling C past the deadline, which no run's timeout bounds) leaves the runner every row it finished; only the rest are TIMEOUT.
…eads its model from the source root (lanl#1309) check_stable judged against base.limit directly. A base whose tenfold tighter run failed has an infinite limit, so an answer doubled at rtol x2 read PASS, 'the answer holds'. Base.compare's no-reference and floor SKIPs now come first; a base past UNJUDGEABLE_DRIFT is still judged. _B338 was relative to the working directory, so the BIOMD0000000338 test skipped wherever pytest ran from another directory (lanl#578): _ROOT now. The cap test compared every row but stable with an uncapped run, which fails once a check lands after main's in another change: it now compares the rows heard up to backend_as_asked and asks the rest be TIMEOUT.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1309.
What it adds
A DIFF says two paths disagree, not which one is wrong, and a small own drift does not make an answer uncontested. On #1304's BIOMD0000000338, KLU moved 1e-7 at a tenfold tighter tolerance while dense and libRoadRunner sat 3.5% away.
Attribution. Every DIFF whose comparison kept its two trajectories goes to third arms.
Verdictnow carries the two trajectories, but they are never written to a report. The arms run once per model, however many DIFFs it has:tighterdense/kluroadrunner[id], concentrations, as rr_parity selects)Each arm sides with the comparison's
reference, itspath,both, orneither, judged against the same bound as the DIFF. The row'sextra["attribution"]records each arm's side and distances. Itsverdictis the one side every arm that took a side took, orsplit. An arm that cannot run (libRoadRunner giving up, KLU declined) is left out.Branch stability. A new
stablecheck reruns the base:n_points − 1and+ 1, read at the last point, which every grid shares;rtol × 0.5and× 2.A jump past the bound is a DIFF with
extra["contested"].The report lists contested models in
meta["contested"]: a model whosestablerow reads DIFF, or one with a DIFF whose arms split (D.contested). The runner prints them.#1304's two models, as the issue asks
klu_vs_densetighter(KLU) → path;dense→ reference;roadrunner→ referencetighter(KLU) → path;dense→ reference; libRoadRunner gives up (CV_TOO_MUCH_WORK) and is left outBoth read contested.
stableitself passes on both: KLU's answer does not move under jitter, as #1304 found. It is the split that marks them.Over the corpus
Every check except
locale, 1,353 models, local run on this commit.13 contested:
7 attributed DIFFs:
stable: 1,284 PASS, 10 DIFF, 54 SKIP, 4 EXCEPTION, 1 TIMEOUT. The DIFFs include:n_points ± 1, by the whole value: at t = 10, 101 points readAnakinrasc14,222, while 100 or 102 points read 107 as the largest species. The model has one event, and whether it fires depends on a sample landing on it: the event-at-a-sample class (A sensitivity run records the row before an event that a plain run records after it (#1133's read-ahead is off with sensitivities) #1182, A pulse schedule whose width an event writes gets no stops: X(240) = 1 for 17, at every tolerance #1244). No other check here sees it.Tests (
python/tests/test_differential_shapes.py, appended)split, and contested;cc_vs_interpDIFF (the path moved 50%) is attributed by real arms to the reference.n_points + 1, read DIFF and contested. All 15 shapes passstable.tighter→ path anddense→ reference. It skips if the corpus is absent, as the repo's other corpus tests do.Mutations, each caught:
check_allnot attributing;stablewithout its tolerance jitter;stablewithout its grid jitter;contestedignoring a split;Suites:
parity_checks/testsand the shapes give 1,105 passed, 28 skipped, 1 xfailed. ruff 0.14.0 is clean. The branch merges cleanly with lanlmain.Cost
stable: 5 more runs per model.Baseline
parity_checks/nightly/baselines/differential.jsonwill be re-recorded from this PR's own nightly run, in a follow-up commit here. It adds thestablerows; the contested list rides in the report's meta.Changes (this PR's commit, less the tests)
No changelog fragment:
parity_checks/and tests only.The nightly's cap
The first nightly on this PR failed Path-agreement check with 33 regressions, every one a TIMEOUT ("cap of 900 s"). The pool kills a model's worker at its cap, and every row of that model goes with it:
stablererun ground on past the cap (CVODE error-test failures, at up to 100,000 steps per output point);stable's five reruns tipped them over.#1315, #1318 and #1320 failed the same way. #1321 bounds every run in the harness by the model's cap, and keeps a killed worker's finished rows. Here (merged into this branch, replacing 6357188's narrower fix) the additions run after every check main runs:
stable.Each starts only with time left, and a
stablethe cap stops is TIMEOUT, its own row only.BIOMD0000000810 end to end through the runner, at a 120 s cap: every row returns in 109 s. Its three baseline DIFFs are attributed (
ajac_vs_fdjac→ reference,klu_vs_dense→ path,grid→ reference), andstableis TIMEOUT, "not finished within the model's cap".Tests:
stableis TIMEOUT and every other row matches a run without a cap;Mutations:
rununbounded: caught;stablestarting without its own check of the time left: an equivalent mutant, since its first run refuses to start past the deadline anyway.Suites: the shapes and the skip audit give 233 passed, 1 xfailed.