Skip to content

reinit! dominates runtime and allocations in integrator update loop #4409

@jClugstor

Description

@jClugstor

Not exactly a bug per se ...
In an example of a function that reinitializes, updates the state of, and solves an integrator that was created with an MTK system, reinit! takes up all of the allocations, and more than half of the runtime, when reinit_dae = true and reset_dt = true.

Code example:

using ModelingToolkit, OrdinaryDiffEq, Setfield
using ModelingToolkit: t_nounits as t, D_nounits as D
using SymbolicIndexingInterface
using BenchmarkTools
using Test
function Pin(; name)
    @variables v(t) i(t) [connect = Flow]
    sys = System(Equation[], t, [v, i], []; name)
    sys = @set sys.connector_type = ModelingToolkit.connector_type(sys)
    return sys
end
function Ground(; name)
    @named g = Pin()
    eqs = [g.v ~ 0]
    System(eqs, t, [], []; systems=[g], name)
end
function OnePort(; name)
    @named p = Pin()
    @named n = Pin()
    @variables v(t) i(t)
    eqs = [
        v ~ p.v - n.v
        0 ~ p.i + n.i
        i ~ p.i
    ]
    System(eqs, t, [v, i], []; systems=[p, n], name)
end
function Resistor(; name, R=1.0)
    @named oneport = OnePort()
    @unpack v, i = oneport
    @parameters R = R # Sets the default resistance
    eqs = [v ~ i * R]
    extend(System(eqs, t, [], [R]; name), oneport)
end
function Capacitor(; name, C=1.0)
    @named oneport = OnePort()
    @unpack v, i = oneport
    @parameters C = C
    eqs = [D(v) ~ i / C]
    extend(System(eqs, t, [], [C]; name), oneport)
end
function ConstantVoltage(; name, V=1.0)
    @named oneport = OnePort()
    @unpack v = oneport
    @parameters V = V
    eqs = [V ~ v]
    extend(System(eqs, t, [], [V]; name), oneport)
end
function Circuit(; name)
    @named C1 = Capacitor(C=1e-3)
    @named C2 = Capacitor(C=2e-3)
    @named C3 = Capacitor(C=3e-3)
    @named R1 = Resistor(R=1.)
    @named R2 = Resistor(R=2.)
    @named R3 = Resistor(R=3.)
    @named source = ConstantVoltage(V=5.0)
    @named ground = Ground()
    eqs = [
        connect(source.n, ground.g)
        connect(source.p, R1.p)
        connect(R1.n, C1.p, R2.p)
        connect(C1.n, ground.g)
        connect(R2.n, C2.p, R3.p)
        connect(C2.n, ground.g)
        connect(R3.n, C3.p)
        connect(C3.n, ground.g)
    ]
    System(eqs, t; systems=[C1, C2, C3, R1, R2, R3, source, ground], name)
end
@named circuit = Circuit()
circuit = mtkcompile(circuit)
u0 = [circuit.C1.v => 0.; circuit.C2.v => 0.; circuit.C3.v => 0.]
set_u0! = setsym(circuit, [circuit.C1.v; circuit.C2.v; circuit.C3.v])
prob = ODEProblem(circuit, u0, (0., 1e-2))
integrator = init(prob, Trapezoid())
v = [1.; 2.; 3.]
function update!(integrator, u0, set_u0!)
    reinit!(integrator; erase_sol=false, reset_dt=true, reinit_dae=true)
    set_u0!(integrator, u0)
    integrator.saveiter = 0
    integrator.saveiter_dense = 0
    savevalues!(integrator)
    solve!(integrator)
    return
end

Allocations from reset_dt = true:
These are an OrdinaryDiffEq issue, SciML/OrdinaryDiffEq.jl#3231

Allocations from reinit_dae:
Many of these are from late_binding_u0_p

  • OOPSetter, from the setp_oop in late_binding_u0_p
  • all_symbols, which has allocations from parameters and all_variable_symbols.

The rest of the allocations are from initialize_dae!, which calls get_initial_values, which then calls update_initializeprob! and initprobpmap_split. Both of these call a RuntimeGenerated function which allocates.

We can see these allocations in this flamegraph:

Image

As for the performance implications, profiling shows that over half of the run time is taken up by the reinit! call, and most of the time in reinit! is taken up by the functions that allocate.

Image

I would like to try to see how many of these allocations we can eliminate, and especially see if we can make reinit! faster.

Environment (please complete the following information):

  • Output of using Pkg; Pkg.status()
(initialization_allocations) pkg> st
Status `~/Documents/Work/dev/ErrorCorp/initialization_allocations/Project.toml`
  [6e4b80f9] BenchmarkTools v1.6.3
  [0ca39b1e] Chairmarks v1.3.1
  [961ee093] ModelingToolkit v11.17.0
  [7771a370] ModelingToolkitBase v1.24.0 `~/.julia/dev/ModelingToolkit/lib/ModelingToolkitBase`
  [1dea7af3] OrdinaryDiffEq v6.108.0
  [bbf590c4] OrdinaryDiffEqCore v3.22.0 `~/Documents/Work/dev/OrdinaryDiffEq.jl/lib/OrdinaryDiffEqCore`
  [efcf1570] Setfield v1.1.2
  [2efcf032] SymbolicIndexingInterface v0.3.46
  • Output of using Pkg; Pkg.status(; mode = PKGMODE_MANIFEST)
Status `~/Documents/Work/dev/ErrorCorp/initialization_allocations/Manifest.toml`
  [47edcb42] ADTypes v1.21.0
  [6e696c72] AbstractPlutoDingetjes v1.3.2
  [1520ce14] AbstractTrees v0.4.5
  [7d9f7c33] Accessors v0.1.44
  [79e6a3ab] Adapt v4.5.0
  [ec485272] ArnoldiMethod v0.4.0
  [4fba245c] ArrayInterface v7.23.0
  [4c555306] ArrayLayouts v1.12.2
  [aae01518] BandedMatrices v1.11.0
  [6e4b80f9] BenchmarkTools v1.6.3
  [e2ed5e7c] Bijections v0.2.2
  [caf10ac8] BipartiteGraphs v0.1.7
  [62783981] BitTwiddlingConvenienceFunctions v0.1.6
  [8e7c35d0] BlockArrays v1.9.3
  [70df07ce] BracketingNonlinearSolve v1.11.0
  [2a0fbf3d] CPUSummary v0.2.7
  [d360d2e6] ChainRulesCore v1.26.0
  [0ca39b1e] Chairmarks v1.3.1
  [fb6a15b2] CloseOpenIntervals v0.1.13
⌅ [861a8166] Combinatorics v1.0.2
  [38540f10] CommonSolve v0.2.6
  [bbf7d656] CommonSubexpressions v0.3.1
  [f70d9fcc] CommonWorldInvalidations v1.0.0
  [34da2185] Compat v4.18.1
  [b152e2b5] CompositeTypes v0.1.4
  [a33af91c] CompositionsBase v0.1.2
  [2569d6c7] ConcreteStructs v0.2.3
  [187b0558] ConstructionBase v1.6.0
  [adafc99b] CpuId v0.3.1
  [864edb3b] DataStructures v0.19.3
  [2b5f629d] DiffEqBase v6.211.0
  [459566f4] DiffEqCallbacks v4.12.0
  [163ba53b] DiffResults v1.1.0
  [b552c78f] DiffRules v1.15.1
  [a0c0ee7d] DifferentiationInterface v0.7.16
  [ffbed154] DocStringExtensions v0.9.5
  [5b8099bc] DomainSets v0.7.16
  [7c1d4256] DynamicPolynomials v0.6.4
  [4e289a0a] EnumX v1.0.7
  [f151be2c] EnzymeCore v0.8.18
  [d4d017d3] ExponentialUtilities v1.30.0
  [e2ba6199] ExprTools v0.1.10
  [55351af7] ExproniconLite v0.10.14
  [7034ab61] FastBroadcast v0.3.5
  [9aa1b823] FastClosures v0.3.2
  [442a2c76] FastGaussQuadrature v1.1.0
  [a4df4552] FastPower v1.3.1
  [1a297f60] FillArrays v1.16.0
  [64ca27bc] FindFirstFunctions v1.8.0
  [6a86dc24] FiniteDiff v2.29.0
  [f6369f11] ForwardDiff v1.3.2
  [069b7b12] FunctionWrappers v1.1.3
  [77dc65aa] FunctionWrappersWrappers v0.1.3
  [46192b85] GPUArraysCore v0.2.0
  [c145ed77] GenericSchur v0.5.6
  [86223c79] Graphs v1.14.0
  [615f187c] IfElse v0.1.1
  [3263718b] ImplicitDiscreteSolve v1.8.0
  [d25df0c9] Inflate v0.1.5
  [18e54dd8] IntegerMathUtils v0.1.3
  [8197267c] IntervalSets v0.7.13
  [3587e190] InverseFunctions v0.1.17
  [92d709cd] IrrationalConstants v0.2.6
  [82899510] IteratorInterfaceExtensions v1.0.0
  [692b3bcd] JLLWrappers v1.7.1
  [682c06a0] JSON v1.4.0
  [ae98c720] Jieko v0.2.1
  [ccbc3e58] JumpProcesses v9.23.2
  [ba0b0d4f] Krylov v0.10.6
  [10f19ff3] LayoutPointers v0.1.17
  [87fe0de2] LineSearch v0.1.6
  [d3d80556] LineSearches v7.6.0
  [7ed4a6bd] LinearSolve v3.67.0
  [2ab3a3ac] LogExpFunctions v0.3.29
  [e6f89c97] LoggingExtras v1.2.0
  [1914dd2f] MacroTools v0.5.16
  [d125e4d3] ManualMemory v0.1.8
  [bb5d69b7] MaybeInplace v0.1.4
  [961ee093] ModelingToolkit v11.17.0
  [7771a370] ModelingToolkitBase v1.24.0 `~/.julia/dev/ModelingToolkit/lib/ModelingToolkitBase`
  [6bb917b9] ModelingToolkitTearing v1.10.0
  [2e0e35c7] Moshi v0.3.7
  [46d2c3a1] MuladdMacro v0.2.4
  [102ac46a] MultivariatePolynomials v0.5.14
  [d8a4904e] MutableArithmetics v1.6.7
  [d41bc354] NLSolversBase v8.0.0
  [77ba4419] NaNMath v1.1.3
  [8913a72c] NonlinearSolve v4.16.0
  [be0214bd] NonlinearSolveBase v2.15.0
  [5959db7a] NonlinearSolveFirstOrder v2.0.0
  [9a2c21bd] NonlinearSolveQuasiNewton v1.12.0
  [26075421] NonlinearSolveSpectralMethods v1.6.0
  [6fe1bfb0] OffsetArrays v1.17.0
  [bac558e1] OrderedCollections v1.8.1
  [1dea7af3] OrdinaryDiffEq v6.108.0
  [89bda076] OrdinaryDiffEqAdamsBashforthMoulton v1.9.0
  [6ad6398a] OrdinaryDiffEqBDF v1.22.0
  [bbf590c4] OrdinaryDiffEqCore v3.22.0 `~/Documents/Work/dev/OrdinaryDiffEq.jl/lib/OrdinaryDiffEqCore`
  [50262376] OrdinaryDiffEqDefault v1.13.0
  [4302a76b] OrdinaryDiffEqDifferentiation v2.2.1
  [9286f039] OrdinaryDiffEqExplicitRK v1.9.0
  [e0540318] OrdinaryDiffEqExponentialRK v1.13.0
  [becaefa8] OrdinaryDiffEqExtrapolation v1.16.0
  [5960d6e9] OrdinaryDiffEqFIRK v1.23.0
  [101fe9f7] OrdinaryDiffEqFeagin v1.8.0
  [d3585ca7] OrdinaryDiffEqFunctionMap v1.9.0
  [d28bc4f8] OrdinaryDiffEqHighOrderRK v1.9.0
  [9f002381] OrdinaryDiffEqIMEXMultistep v1.12.0
  [521117fe] OrdinaryDiffEqLinear v1.10.0
  [1344f307] OrdinaryDiffEqLowOrderRK v1.10.0
  [b0944070] OrdinaryDiffEqLowStorageRK v1.12.0
  [127b3ac7] OrdinaryDiffEqNonlinearSolve v1.23.0
  [c9986a66] OrdinaryDiffEqNordsieck v1.9.0
  [5dd0a6cf] OrdinaryDiffEqPDIRK v1.11.0
  [5b33eab2] OrdinaryDiffEqPRK v1.8.0
  [04162be5] OrdinaryDiffEqQPRK v1.8.0
  [af6ede74] OrdinaryDiffEqRKN v1.10.0
  [43230ef6] OrdinaryDiffEqRosenbrock v1.25.0
  [2d112036] OrdinaryDiffEqSDIRK v1.12.0
  [669c94d9] OrdinaryDiffEqSSPRK v1.11.0
  [e3e12d00] OrdinaryDiffEqStabilizedIRK v1.11.0
  [358294b1] OrdinaryDiffEqStabilizedRK v1.8.0
  [fa646aed] OrdinaryDiffEqSymplecticRK v1.11.0
  [b1df2697] OrdinaryDiffEqTsit5 v1.9.0
  [79d7bb75] OrdinaryDiffEqVerner v1.11.0
  [69de0a69] Parsers v2.8.3
  [e409e4f3] PoissonRandom v0.4.7
  [f517fe37] Polyester v0.7.19
  [1d0040c9] PolyesterWeave v0.2.2
  [d236fae5] PreallocationTools v1.1.2
  [aea7be01] PrecompileTools v1.3.3
  [21216c6a] Preferences v1.5.2
  [27ebfcd6] Primes v0.5.7
  [988b38a3] ReadOnlyArrays v0.2.0
  [795d4caa] ReadOnlyDicts v1.0.1
  [3cdcf5f2] RecipesBase v1.3.4
  [731186ca] RecursiveArrayTools v3.48.0
  [189a3867] Reexport v1.2.2
  [ae029012] Requires v1.3.1
  [7e49a35a] RuntimeGeneratedFunctions v0.5.17
  [9dfe8606] SCCNonlinearSolve v1.11.0
  [94e857df] SIMDTypes v0.1.0
  [0bca4576] SciMLBase v2.151.0
  [19f34311] SciMLJacobianOperators v0.1.12
  [a6db7da4] SciMLLogging v1.9.1
  [c0aeaf25] SciMLOperators v1.15.1
  [431bcebd] SciMLPublic v1.0.1
  [53ae85a6] SciMLStructures v1.10.0
  [efcf1570] Setfield v1.1.2
  [727e6d20] SimpleNonlinearSolve v2.11.0
  [699a6c99] SimpleTraits v0.9.5
  [0a514795] SparseMatrixColorings v0.4.26
  [276daf66] SpecialFunctions v2.7.1
  [64909d44] StateSelection v1.6.0
  [aedffcd0] Static v1.3.1
  [0d7ed370] StaticArrayInterface v1.9.0
  [90137ffa] StaticArrays v1.9.18
  [1e83bf80] StaticArraysCore v1.4.4
  [10745b16] Statistics v1.11.1
  [7792a7ef] StrideArraysCore v0.5.8
  [ec057cc2] StructUtils v2.7.1
  [2efcf032] SymbolicIndexingInterface v0.3.46
  [19f23fe9] SymbolicLimits v1.1.0
  [d1185830] SymbolicUtils v4.20.2
  [0c5d862f] Symbolics v7.16.1
  [ed4db957] TaskLocalValues v0.1.3
  [8ea1fca8] TermInterface v2.0.0
  [8290d209] ThreadingUtilities v0.5.5
  [a759f4b9] TimerOutputs v0.5.29
  [781d530d] TruncatedStacktraces v1.4.0
  [3a884ed6] UnPack v1.0.2
  [d30d5f5c] WeakCacheSets v0.1.0
  [1d5cc7b8] IntelOpenMP_jll v2025.2.0+0
  [856f044c] MKL_jll v2025.2.0+0
  [efe28fd5] OpenSpecFun_jll v0.5.6+0
  [1317d2d5] oneTBB_jll v2022.0.0+1
  [0dad84c5] ArgTools v1.1.2
  [56f22d72] Artifacts v1.11.0
  [2a0f44e3] Base64 v1.11.0
  [ade2ca70] Dates v1.11.0
  [8ba89e20] Distributed v1.11.0
  [f43a241f] Downloads v1.7.0
  [7b1f6079] FileWatching v1.11.0
  [9fa8497b] Future v1.11.0
  [b77e0a4c] InteractiveUtils v1.11.0
  [ac6e5ff7] JuliaSyntaxHighlighting v1.12.0
  [4af54fe1] LazyArtifacts v1.11.0
  [b27032c2] LibCURL v0.6.4
  [76f85450] LibGit2 v1.11.0
  [8f399da3] Libdl v1.11.0
  [37e2e46d] LinearAlgebra v1.12.0
  [56ddb016] Logging v1.11.0
  [d6f4376e] Markdown v1.11.0
  [ca575930] NetworkOptions v1.3.0
  [44cfe95a] Pkg v1.12.1
  [de0858da] Printf v1.11.0
  [9abbd945] Profile v1.11.0
  [3fa0cd96] REPL v1.11.0
  [9a3f8284] Random v1.11.0
  [ea8e919c] SHA v0.7.0
  [9e88b42a] Serialization v1.11.0
  [6462fe0b] Sockets v1.11.0
  [2f01184e] SparseArrays v1.12.0
  [f489334b] StyledStrings v1.11.0
  [fa267f1f] TOML v1.0.3
  [a4e569a6] Tar v1.10.0
  [8dfed614] Test v1.11.0
  [cf7118a7] UUIDs v1.11.0
  [4ec0a83e] Unicode v1.11.0
  [e66e0078] CompilerSupportLibraries_jll v1.3.0+1
  [deac9b47] LibCURL_jll v8.15.0+0
  [e37daf67] LibGit2_jll v1.9.0+0
  [29816b5a] LibSSH2_jll v1.11.3+1
  [14a3606d] MozillaCACerts_jll v2025.11.4
  [4536629a] OpenBLAS_jll v0.3.29+0
  [05823500] OpenLibm_jll v0.8.7+0
  [458c3c95] OpenSSL_jll v3.5.4+0
  [bea87d4a] SuiteSparse_jll v7.8.3+2
  [83775a58] Zlib_jll v1.3.1+2
  [8e850b90] libblastrampoline_jll v5.15.0+0
  [8e850ede] nghttp2_jll v1.64.0+1
  [3f19e933] p7zip_jll v17.7.0+0
Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`
  • Output of versioninfo()
julia> versioninfo()
Julia Version 1.12.5
Commit 5fe89b8ddc1 (2026-02-09 16:05 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 16 × AMD Ryzen 7 6800U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-18.1.7 (ORCJIT, znver3)
  GC: Built with stock GC
Threads: 16 default, 1 interactive, 16 GC (on 16 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_VSCODE_REPL = 1
  JULIA_PKG_SERVER = https://juliahub.com

Additional context

Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions