Annotate @test_broken Enzyme blocks with Const(loss) + set_runtime_activity#1453
Merged
ChrisRackauckas merged 2 commits intoMay 23, 2026
Conversation
…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>
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.
Please ignore until reviewed by @ChrisRackauckas.
Summary
Apply the documented user-side Enzyme idioms to the three remaining
@test_broken Enzyme.gradientblocks. They stay@test_brokenafter this PR — purpose is to (a) document the correct future-passing form, (b) remove theEnzymeMutabilityExceptionlayer 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_brokenblocks plus comments.test/mtk.jlEnzyme.gradient(Reverse, loss, tunables)→Enzyme.gradient(set_runtime_activity(Reverse), Const(loss), tunables); comment refreshedtest/parameter_initialization.jlEnzyme.gradient(Reverse, Const(loss), …)→Enzyme.gradient(set_runtime_activity(Reverse), Const(loss), …); comment refreshedtest/desauty_dae_mwe.jlsolve(iprob2, NewtonRaphson())to avoid the NonlinearSolve polyalgorithm Union that trips Enzyme's type analysis; comment refreshedWhy the tests stay
@test_brokenAfter this annotation change the chain still trips a
MixedDuplicated/Core.SimpleVectorMethodErrorfurther down in Enzyme's runtime-activity wrapping for MTK-System/NonlinearSolutiontypes. Tracked at #1359; first upstream piece filed at SciML/ModelingToolkit.jl#4553 (declareAbstractSystemas Enzymeinactive_type). When the remaining layers lift, flipping@test_broken→@testin these three blocks is the only required change here.Refs
EnzymeMutabilityExceptionon captured mutable is correct behavior)inactive_type)Test plan
@test_broken— same count expected)