Skip to content

Repeated optimization (differentiation?) of a System keeps incurring type inference / compilation time #4351

@cstjean

Description

@cstjean

The foo() calls below optimize an MTK model's parameters via Optimization.jl, ForwardDiff.jl and remake. The (compilation?) time and allocation varies roughly on an odd/even pattern (I've plotted 100 such calls and it was clear). foo() itself builds a System in a fairly vanilla way --- I do not use eval or staged function or anything particularly exotic.

Why do I keep seeing compilation time, and such fluctuating allocation patterns?

julia> @time foo();
 10.598025 seconds (329.36 M allocations: 6.384 GiB, 16.52% gc time, 99.43% compilation time: <1% of which was recompilation)

julia> @time foo();
 96.695468 seconds (383.82 M allocations: 18.683 GiB, 6.77% gc time, 195.60% compilation time: <1% of which was recompilation)

julia> @time foo();
 10.885435 seconds (332.19 M allocations: 6.768 GiB, 17.51% gc time, 82.27% compilation time: <1% of which was recompilation)

julia> @time foo();
 11.131420 seconds (335.78 M allocations: 6.774 GiB, 16.02% gc time, 94.54% compilation time: <1% of which was recompilation)

julia> @time foo();
 13.010147 seconds (333.03 M allocations: 6.633 GiB, 14.73% gc time, 95.50% compilation time: <1% of which was recompilation)

julia> @time foo();
  0.724270 seconds (9.34 M allocations: 353.154 MiB, 108.19% compilation time: <1% of which was recompilation)

julia> @time foo();
  0.786725 seconds (9.03 M allocations: 337.088 MiB, 23.32% gc time, 98.37% compilation time: <1% of which was recompilation)

julia> @time foo();
 11.860633 seconds (332.62 M allocations: 6.766 GiB, 15.40% gc time, 84.53% compilation time: <1% of which was recompilation)

julia> @time foo();
  0.625859 seconds (9.15 M allocations: 347.657 MiB, 91.62% compilation time: <1% of which was recompilation)

julia> @time foo();
 10.476637 seconds (322.76 M allocations: 6.061 GiB, 11.95% gc time, 0.00% compilation time: 100% of which was recompilation)

I've tried using --trace-compile, and indeed I've seen new methods pop up at each foo() call, stuff like

precompile(Tuple{typeof(Base.ntupleany), Base.var"#fieldtypes##0#fieldtypes##1"{Type{OrdinaryDiffEqRosenbrock.GRK4T{CS, AD, F, P, FDT, ST, CJ} where CJ where ST where FDT where P where F where AD where CS}}, Int64})
precompile(Tuple{typeof(Base.get!), Revise.var"#fieldtypes_cached##0#fieldtypes_cached##1"{Type{OrdinaryDiffEqRosenbrock.ROK4a{CS, AD, F, P, FDT, ST, CJ} where CJ where ST where FDT where P where F where AD where CS}}, Base.IdDict{Type, Union{Nothing, Array{Any, 1}}}, Any})
precompile(Tuple{typeof(Base.ntupleany), Base.var"#fieldtypes##0#fieldtypes##1"{Type{OrdinaryDiffEqRosenbrock.ROK4a{CS, AD, F, P, FDT, ST, CJ} where CJ where ST where FDT where P where F where AD where CS}}, Int64})

(this is with Revise, but I'm not touching anything, and I've reproduced it without Revise).

ProfileView.jl on the fast runs looks like this:
Image

Slow runs look like this, with the topmost red bars being solve_up calls, that trigger type inference and abstract interpretation.
Image

On MTK11, Julia 1.12.2.

Is this a known issue? Has anyone seen something like this? I can provide an MWE if it helps, but this looks like several hours of work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions