Skip to content

parity: start a model's later sensitivity methods after its first (#1386) - #1390

Open
Montana wants to merge 1 commit into
lanl:mainfrom
Montana:fix/1386-sens-method-after-first
Open

Montana wants to merge 1 commit into
lanl:mainfrom
Montana:fix/1386-sens-method-after-first

Conversation

@Montana

@Montana Montana commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Closes #1386.

What was wrong

The nightly amici_sens leg's wall alert went red on nights when BIOMD0000000457's generated code was compiled twice.

make_specs orders the jobs method-major, every model's staggered run before any simultaneous one, so that a model's second method would load the code its first had built. Order alone does not keep them apart, though:

  • 457's compile takes 150-220 s;
  • on some nights the other two workers finished the remaining short jobs first, so 457 (simultaneous) started while 457 (staggered) was still compiling, and compiled the same library again;
  • the two compiles then slowed each other, giving PR amici_sens: judge each sensitivity parameter on its own scale (#1261) #1303's run 302 s → 654 s (x2.17) with every outcome and work counter unchanged.

The fix

This is the issue's option 1, the dispatch dependency. It is deterministic and confined to the harness. Option 2, a build lock in bngsim's codegen cache across processes, would help every suite but touches python/bngsim with platform-specific locking, so it is not in this PR.

  • _rr_common.schedule(..., depends_on=None): depends_on(spec) gives the key of a spec that must finish, with any result, before this one starts.
    • A free worker takes the first pending spec that is ready, so a wait never idles a worker while something else can run.
    • A dependency on a key no spec has holds nothing back.
    • Where nothing runs and nothing is ready (a cycle, say), the first pending spec starts, so a dependency only orders the work and cannot wedge a sweep.
    • Every other caller passes nothing and runs exactly as before.
  • amici_sens_run: first_method_key(spec, methods) makes each later method wait on its own model's first, and main() passes it as depends_on. It is computed from the spec rather than stored on it, so result rows and reports are unchanged.

Measured

A simulation of the nightly's dispatch with timed_worker: 48 models × 2 methods, 3 workers, 0.15 s jobs, and one model's first method taking 15 s and dispatched last in its pass.

second method starts first ends overlap sweep
order only (main) +7.83 s +15.00 s yes: a second compile 19.27 s
depends_on (this PR) +15.12 s +15.00 s no 19.51 s

The wait cost the sweep 0.24 s here (about 1%). On the nightly it saves the second compile of 150-220 s and the contention that slowed the first one.

Tests

test on main
test_schedule_starts_a_dependent_spec_only_after_the_one_it_waits_on: and the jobs it does not wait on run meanwhile fail (no depends_on)
test_schedule_without_depends_on_starts_the_second_spec_alongside: control, the race itself pass
test_schedule_runs_a_spec_whose_dependency_times_out fail
test_schedule_does_not_hold_back_a_spec_waiting_on_no_spec: it starts beside a long job, not after it fail
test_schedule_runs_every_spec_of_a_dependency_cycle fail
test_each_later_method_waits_on_its_own_models_first fail (no first_method_key)
test_the_sweep_hands_schedule_the_dependency fail

Mutations

mutant fails
S1: readiness ignored the dependent-spec test
S2: a missing dependency waits the no-spec test
S3: only the head of the queue may start the dependent-spec test
S4: the wrong model's key the per-model test
S5: main() does not pass depends_on the wiring test
S6: a timed-out spec does not count as finished the timeout test, and the existing kill test
S7: no guard for nothing ready the cycle test hangs (killed at 120 s)

Checked

  • parity_checks/tests: 964 passed, 24 skipped, and 2 failed. The same 2 fail on main without this change (test_bngsim_provenance, test_bng_reference_archive, an import path in my local environment).
  • pre-commit run --all-files and ci/changelog.py check are clean.
  • Not run here: the AMICI leg itself (AMICI is not installed locally). A nightly run should show 457's simultaneous codegen_sec near 0, as every other model's is.

…nl#1386)

Method-major order let BIOMD0000000457's second corrector method start
while its first was still compiling the code both load, so it compiled it
again alongside and the doubled codegen tripped the nightly wall alert.
schedule() takes depends_on: a spec starts once the one it names has
finished, a free worker takes the first ready spec, and with nothing
running and nothing ready the first pending starts, so a dependency only
orders the work. amici_sens_run makes each later method wait on its own
model's first.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

amici_sens nightly: BIOMD0000000457 compiles twice on some nights, tripping the wall alert

1 participant