Skip to content

build_rrule hangs on MTK-generated ODEProblem types (DynamicDerivedRule infinite type inference) #1097

@ChrisRackauckas-Claude

Description

@ChrisRackauckas-Claude

Summary

Mooncake.build_rrule succeeds for the top-level function, but execution hangs indefinitely during lazy sub-rule compilation (DynamicDerivedRule) when Mooncake encounters ModelingToolkit-generated ODEProblem types. The hang is in abstract_call_gf_by_typetypeinf_edge cycles in Mooncake's abstract interpretation.

This blocks using Mooncake as the outer AD for MTK-based models in SciMLSensitivity.jl (see SciML/SciMLSensitivity.jl#1358).

MWE

# Mooncake v0.5.23, ModelingToolkit v11.17.0, OrdinaryDiffEq v6.108.0, Julia 1.11.9

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using OrdinaryDiffEq
using SciMLStructures: Tunable, replace
using Mooncake

@parameters k
@variables X(t)
@named sys = System([D(X) ~ -k * X], t)
sys = mtkcompile(sys)

prob = ODEProblem(sys, [X => 1.0], (0.0, 1.0), [k => 0.5])

function loss(pval)
    new_p = replace(Tunable(), prob.p, pval)
    sol = solve(prob, Tsit5(); p = new_p, saveat = 0.1)
    return sum(reduce(hcat, sol.u))
end

println("Primal: ", loss([0.5]))  # works

# build_rrule succeeds (~15s):
rule = Mooncake.build_rrule(loss, [0.5])

# But execution hangs here during DynamicDerivedRule lazy compilation:
Mooncake.value_and_pullback!!(rule, 1.0, loss, [0.5])  # hangs

Behavior

  • Without MTK (plain ODEProblem{true}(f!, u0, tspan, p)): Works correctly, gradients match ForwardDiff.
  • With MTK (even simple D(X) ~ -k*X): build_rrule succeeds in ~15s, but value_and_pullback!! hangs.
  • With MTK + DAE initialization (algebraic constraints + guesses): Same hang, but the types are even more complex.

Stack trace (from SIGTERM)

The hang is in deeply nested abstract_call_gf_by_typetypeinf_edgeabstract_call_method cycles:

DynamicDerivedRule → build_rrule → generate_ir → lookup_ir → typeinf_ircode →
  typeinf → typeinf_edge → abstract_call_method → abstract_call_gf_by_type →
    abstract_call_gf_by_type (Mooncake override) → abstract_call_known →
      abstract_call → typeinf_edge → ... (repeats)

This suggests Mooncake's abstract interpretation doesn't terminate for the complex parameterized types used by MTK (RuntimeGeneratedFunctions, GeneratedFunctionWrapper, ObservedFunctionCache, etc.).

Versions

  • Mooncake v0.5.23
  • ModelingToolkit v11.17.0
  • OrdinaryDiffEq v6.108.0
  • Julia 1.11.9

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions