Skip to content

tests: declare what a forced-JIT run cannot pass, so the run is a signal (#1217) - #1350

Open
Montana wants to merge 3 commits into
lanl:mainfrom
Montana:fix/1217-forced-mir-clean
Open

Montana wants to merge 3 commits into
lanl:mainfrom
Montana:fix/1217-forced-mir-clean

Conversation

@Montana

@Montana Montana commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1217 (with #1348, which fixes its #1212 group).

What was wrong

Running the whole suite with every model forced through the MIR JIT (BNGSIM_CODEGEN_JIT=mir BNGSIM_CODEGEN_THRESHOLD=1) is the check that found #1208 and #1212. It is only a signal if it passes. On main 9a26f5b with #1348 merged in, 53 tests fail under it. That matches #1217's accounting once #1212's 38 are gone:

group tests why it cannot pass under a forced JIT
cc's compiled artifact 32 the test is about the .so, its cache key, the redirected cache dir, or the output-sensitivity and sens-RHS notes written beside it. The JIT compiles in process and writes none of them.
cc by name 7 the test asserts codegen_backend == "cc", and the JIT reports "mir"
a forced threshold 13 the test needs a 2-species model to run interpreted (exprtk, analytical, no .so, the interpreter's RHS counters), and THRESHOLD=1 compiles it. They fail under forced cc too.
engine-dependent answers 2 below

The 32 artifact tests are in test_output_sens_support_note.py (22), test_sens_rhs_decline_note.py (5), test_hpc_contract.py (2), and one each in test_codegen_cache_key.py, test_ar_species_output_sensitivities.py and test_sens_numerically_zero_base.py. The 7 cc-by-name tests are in test_engine_choice_accessors.py (4), test_tfun_analytical_jacobian.py (2) and test_lu_fill_routing.py (1). The 13 threshold tests are in test_engine_choice_accessors.py (3), test_rhs_obs_func_gate.py (3), test_steady_state_polish_jacobian.py (3), test_jacobian_discontinuous_fallback.py, test_lazy_jacobian.py, test_model_codegen_sensitivity.py, and test_steady_state_scaled_criterion.py's MODEL1712050008 retry test. That last one pins the arm64 interpreter's route (solver_jacobian_retried); compiled, the march reaches the same root, within 1.6e-6, without a retry.

The change

python/tests/_codegen_backend.py. A new helper, imported the way _fd_sens.py and _ci_workflow.py are. It provides three skipifs and one xfail:

  • under_jit_no_cc_artifact and under_jit_engine_name read the JIT selection through bngsim._codegen._codegen_jit_backend(), the library's own reading of BNGSIM_CODEGEN_JIT.
  • threshold_forced applies when BNGSIM_CODEGEN_THRESHOLD is set below the default of 256.
  • xfail_when_threshold_forced(issue, why) is a strict xfail under the same condition.

Each skip reason is declared in conftest.py's _DECLARED_SKIPS (tier ANYWHERE), so BNGSIM_SKIP_AUDIT=strict accepts them.

+    @threshold_forced
     def test_small_model_uses_exprtk(self):
 ...
+    @under_jit_engine_name
     def test_explicit_codegen_uses_cc(self):

The two engine-dependent tests are not skipped. A forced run shows each gives a different answer on the compiled path. Both findings are filed, as #1357 and #1358. Each test carries a strict xfail under a lowered threshold, naming its issue, so the mark has to go when the fix lands:

  1. Steady-state refusal (steady_state(method='integration') on the compiled RHS and Jacobian refuses a state at residual 2e-39 and does not retry on difference quotients #1357). steady_state(method="integration") on the compiled RHS refuses glioblastoma_egfrviii_seed.net's steady state at residual 2.1e-39, with continued_run_distance = inf, because its run test is never retried on difference quotients. That affects test_a_march_whose_integrator_fails_returns_the_state_it_passed[integration]. Fixed in steady state: take a run test the closed form cannot take once more on differences (#1357) #1370.
  2. Stale get_param (get_param on an assignment-rule parameter after a compiled run returns its load-time value, not the rule's #1358). After a compiled run, get_param on a parameter an assignment rule sets returns its load-time value: q reads 1.0, where an interpreted run reads the rule's end-of-run 0.0183. The trajectory is unaffected. This is test_a_write_after_a_run_does_not_move_it_to_the_rules_current_value, whose precondition reads the slot.

Verified

On this branch with #1348 merged in, macOS arm64 MIR build, --max-worker-restart=500, BNGSIM_SKIP_AUDIT=strict:

run passed skipped xfailed failed
BNGSIM_CODEGEN_JIT=mir BNGSIM_CODEGEN_THRESHOLD=1 16,476 185 4 0 (53 before)
BNGSIM_CODEGEN_THRESHOLD=1 (forced cc) 16,512 149 4 0 (15 before)
default 16,527 137 1 0, the same skips as main

The suite's existing xfail is the 1 in each count; the forced runs added three. That was measured when MODEL1712050008's retry test still carried an xfail. It is now a forced-threshold skip, so a forced run reports 3 xfailed and one more skip. Rerun after that change, test_steady_state_scaled_criterion.py under BNGSIM_CODEGEN_THRESHOLD=1 with the strict audit gives 222 passed, 3 skipped and 1 xfailed (glioblastoma, #1357), and 224 passed by default. The strict audit accepts every new skip.

Negative control: with the artifact reason removed from _DECLARED_SKIPS, the strict audit reports 1 undeclared skip reason(s).

Not in this PR

…nal (lanl#1217)

Run with every model forced through the MIR JIT
(BNGSIM_CODEGEN_JIT=mir BNGSIM_CODEGEN_THRESHOLD=1), 53 tests fail on main
with lanl#1348's codegen fix in. 39 test the cc backend's own artifact or name.
12 more fail under a forced threshold alone, because they need a small model
to run interpreted. Each now carries a skipif from _codegen_backend.py, with
a reason conftest declares.

Three expose engine-dependent answers, filed separately. They get strict
xfails under a lowered threshold, not skips.

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

1 participant