Skip to content

Annotate @test_broken Enzyme blocks with Const(loss) + set_runtime_activity#1453

Merged
ChrisRackauckas merged 2 commits into
SciML:masterfrom
ChrisRackauckas-Claude:cc/enzyme-test-broken-annotations
May 23, 2026
Merged

Annotate @test_broken Enzyme blocks with Const(loss) + set_runtime_activity#1453
ChrisRackauckas merged 2 commits into
SciML:masterfrom
ChrisRackauckas-Claude:cc/enzyme-test-broken-annotations

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Please ignore until reviewed by @ChrisRackauckas.

Summary

Apply the documented user-side Enzyme idioms to the three remaining @test_broken Enzyme.gradient blocks. They stay @test_broken after this PR — purpose is to (a) document the correct future-passing form, (b) remove the EnzymeMutabilityException layer that Billy Moses (EnzymeAD/Enzyme.jl#3117) called out as user-side, not Enzyme-side.

Touches three files; ~60 LOC changed; all are inside @test_broken blocks plus comments.

File Change
test/mtk.jl Enzyme.gradient(Reverse, loss, tunables)Enzyme.gradient(set_runtime_activity(Reverse), Const(loss), tunables); comment refreshed
test/parameter_initialization.jl Enzyme.gradient(Reverse, Const(loss), …)Enzyme.gradient(set_runtime_activity(Reverse), Const(loss), …); comment refreshed
test/desauty_dae_mwe.jl Same annotations + explicit solve(iprob2, NewtonRaphson()) to avoid the NonlinearSolve polyalgorithm Union that trips Enzyme's type analysis; comment refreshed

Why the tests stay @test_broken

After this annotation change the chain still trips a MixedDuplicated / Core.SimpleVector MethodError further down in Enzyme's runtime-activity wrapping for MTK-System / NonlinearSolution types. Tracked at #1359; first upstream piece filed at SciML/ModelingToolkit.jl#4553 (declare AbstractSystem as Enzyme inactive_type). When the remaining layers lift, flipping @test_broken@test in these three blocks is the only required change here.

Refs

Test plan

  • Files parse-check clean
  • Runic.jl applied
  • CI green (tests remain @test_broken — same count expected)

…tivity

The three `@test_broken Enzyme.gradient` blocks (`mtk.jl` line 168,
`parameter_initialization.jl` "Adjoint through Prob (Enzyme)",
`desauty_dae_mwe.jl` "Enzyme through init") previously called
`Enzyme.gradient(Enzyme.Reverse, loss, tunables)` — i.e. relied on
`Enzyme.gradient` to infer annotations on a closure that captures a
mutable `ODEProblem`/`NonlinearProblem`. That triggers
`EnzymeMutabilityException` on a captured-mutable, which per Billy Moses
(EnzymeAD/Enzyme.jl#3117 close) is correct Enzyme behavior, not a bug:
`Enzyme.gradient` can't annotate captures, so the user must do it.

Apply the documented user-side pattern in all three blocks:

  Enzyme.gradient(
      Enzyme.set_runtime_activity(Enzyme.Reverse),
      Enzyme.Const(loss),
      tunables,
  )

Plus, for `desauty_dae_mwe.jl`, pin `solve(iprob2, NewtonRaphson())` so
Enzyme's type analysis does not trip on the polyalgorithm Union the
default NonlinearSolve dispatch would otherwise emit. (`mtk.jl` already
uses `Rodas5P()`; `parameter_initialization.jl` uses an `ODEProblem`
solve with `GaussAdjoint` sensealg, no NonlinearSolve polyalg in the AD
hot path.)

These tests **stay `@test_broken`** — the activity layer is correct
after this change, but the chain still hits a `MixedDuplicated` /
`Core.SimpleVector` MethodError further down in Enzyme's
runtime-activity wrapping for MTK-`System` / `NonlinearSolution` types.
Tracked in SciML#1359, with one upstream piece
already filed at SciML/ModelingToolkit.jl#4553 (declare `AbstractSystem`
as `inactive_type`). When the remaining upstream lifts, flipping
`@test_broken` → `@test` is the only change needed in these blocks.

Refs SciML#1323, SciML#1359; EnzymeAD/Enzyme.jl#3117.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
With the new `Const(loss)` + `set_runtime_activity(Reverse)` +
explicit `NewtonRaphson()` annotations applied in the parent
commit, the plain `NonlinearProblem` case (use_scc=false)
actually returns a non-zero gradient and `@test_broken` reports
"Unexpected Pass" (recorded as Error). Empirically verified on
Julia 1.12.6:

  Test Summary:               | Pass  Broken  Total     Time
  DAE with SCC Initialization |   18       6     24

(was 17 pass / 7 broken before the split).

Split the testset on `use_scc`:
  * `use_scc = false` (plain `NonlinearProblem`)  → `@test`
  * `use_scc = true`  (`SCCNonlinearProblem`)     → `@test_broken`

The SCC case still hits the `MixedDuplicated` / `Core.SimpleVector`
issue in Enzyme's runtime-activity wrapping during SCC sub-problem
assembly, so it stays `@test_broken` (tracked at SciML#1359).

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review May 23, 2026 09:29
@ChrisRackauckas ChrisRackauckas merged commit 7896045 into SciML:master May 23, 2026
42 of 50 checks passed
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.

2 participants