From 996fb83a522175aa263c98374e8d9165c5621028 Mon Sep 17 00:00:00 2001 From: Bill Hlavacek Date: Mon, 27 Jul 2026 18:45:50 -0600 Subject: [PATCH] ci(mir): run the Michaelis-Menten sensitivity tests, and correct the Windows note Two follow-ups to #87 and #88, both confined to mir.yml. test_codegen_mm_sens.py lands in the run list. #87 added the other three analytic-sensitivity files; #55's MM stage merged after it, so its 17 tests were covered only by the pre-push hook. It needs no #85 quarantine, and the reason is recorded in the header rather than left to be rediscovered: #85 fires on bngsim_codegen_output_sens, which generate_output_sens_from_model emits only for a model with at least one *function*. The MM fixtures declare none, so the symbol is absent even with emit_output_sens forced on, and the Simulator-with-sensitivity_params cases compile. Verified locally on both fixtures. c2mir already handles the arithmetic: mm_tqssa.net goes through test_mir_equivalence and test_codegen_jacobian on this job today, and the MM sensitivity block is the same closed form as the Jacobian block, emitted by the same builder. The Windows paragraph was factually wrong. It said the needs_cc cc-baseline tests skip on windows-latest and that the compiler-free MIR-vs-ExprTk check was therefore the whole of the Windows verification. Neither holds: the runner ships MinGW gcc on PATH, so `_CC = which("cc") or which("clang") or which("gcc")` resolves, nothing skips (0 skipped on every leg, measured), and test_mir_matches_cc runs and passes there. All four legs assert cc-vs-MIR bit-identity, so the job covers more than the comment claimed, not less. Replaced with what is true, plus the consequence that matters: because the runner has compilers, this job does not exercise the no-compiler-at-all path that motivates MIR in the first place. Guarding that needs a leg with the compilers taken off PATH. --- .github/workflows/mir.yml | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mir.yml b/.github/workflows/mir.yml index 9750088..40da236 100644 --- a/.github/workflows/mir.yml +++ b/.github/workflows/mir.yml @@ -22,12 +22,21 @@ name: mir-jit # from-source SuiteSparse build. The KLU-gated codegen tests (sparse Jacobian) # skip cleanly on a KLU-off core. # -# On Windows the default cc+dlopen codegen path is not the story — a bare -# Windows box is the case with no C compiler, which is exactly why MIR exists -# (#3) — so the cc-baseline tests (marked needs_cc: cc/clang/gcc) skip there and -# test_mir_equivalence's compiler-free MIR-vs-ExprTk check is the end-to-end -# Windows verification. On Linux/macOS cc is present, so cc-vs-MIR bit-identity -# is asserted too. +# Why Windows is in the matrix: a bare Windows box is the case with no C +# compiler, which is exactly why MIR exists (#3). +# +# The GitHub `windows-latest` *runner* is not that box, though. It ships MinGW +# gcc on PATH, so `_CC = which("cc") or which("clang") or which("gcc")` resolves +# and the `needs_cc` cc-baseline tests do NOT skip there — measured, 0 skipped on +# every leg. All four legs therefore assert the strong property, cc-vs-MIR +# bit-identity on the same generated source, not just the compiler-free +# MIR-vs-ExprTk comparison. (An earlier version of this comment claimed the +# cc-baseline tests skip on Windows and that MIR-vs-ExprTk was the whole of the +# Windows verification. Both were wrong, and they understated the coverage.) +# +# The consequence worth remembering: this job does not exercise the +# no-compiler-at-all path that motivates MIR. If that path needs guarding, it +# needs a leg with the compilers taken off PATH, not this one. # # The three Functional analytic-sensitivity files (#66's ∂f/∂p, #67's fused J·yS, # #68's clock-conditional laws) are in the list below, but their end-to-end half @@ -41,6 +50,16 @@ name: mir-jit # the quarantine removes itself: fixing #85 turns them XPASS and this job red # until the markers come out. They are the coverage that found #85, and #67's # first attempt at this list is what surfaced it. +# +# The Michaelis-Menten file (#55's MM stage) needs no such marker, and the reason +# is worth stating rather than rediscovering: #85 fires on +# bngsim_codegen_output_sens, which generate_output_sens_from_model only emits +# when the model has at least one *function*. The MM fixtures declare none, so +# the symbol is absent even with emit_output_sens forced on, and their +# Simulator-with-sensitivity_params cases compile here. c2mir already handles the +# arithmetic: mm_tqssa.net goes through test_mir_equivalence and +# test_codegen_jacobian on this job today, and the MM sensitivity block is the +# same closed form as the Jacobian block, from the same builder. on: workflow_dispatch: @@ -133,6 +152,7 @@ jobs: python/tests/test_codegen_functional_dfdp.py \ python/tests/test_codegen_functional_sens_rhs.py \ python/tests/test_codegen_switch_condition_sens.py \ + python/tests/test_codegen_mm_sens.py \ python/tests/test_codegen_determinism.py \ -rA --tb=short ${{ github.event.inputs.pytest_args }} \ 2>&1 | tee mir-${{ matrix.os }}.log