Skip to content

How to preserve compilation of observed runtime generated function? #1312

@bradcarman

Description

@bradcarman

I'm afraid my knowledge of RuntimeGeneratedFunction.jl and Julia may not be sufficient to properly ask this question, but let me try my best...

If I run the following code in a fresh Julia session, obviously it will take some time for Julia to compile all the parts needed. If I run it a 2nd time it all runs very quickly, except the sol[] call which always runs slower because of compilation

using ModelingToolkit, OrdinaryDiffEq
include("../examples/rc_model.jl")
sys = structural_simplify(rc_model)
u0 = [
      capacitor.v => 0.0
      capacitor.p.i => 0.0
      resistor.v => 0.0
     ]
prob = ODEProblem(sys, u0, (0, 10.0));
sol = solve(prob, Rodas4());
@time x = sol[resistor.p.i];
@time x = sol[resistor.p.i];

As can be seen, the result of calling sol[resistor.p.i] will always compile the first time if the prob value is newly constructed.

julia> @time x = sol[resistor.p.i];
  0.008358 seconds (9.14 k allocations: 570.337 KiB, 89.54% compilation time)

julia> @time x = sol[resistor.p.i];
  0.000198 seconds (312 allocations: 15.797 KiB)

Why this matters? In my model I have an enormous amount of observed variables thanks to the amazing job of structural_simplify() and this gets my model a very fast run time. But, this efficiency is lost when I extract the solution due to the compilation of the runtime generated observed function. And, if I'm not mistaken, this problem cannot be solved with PackageCompiler.jl because the runtime generated functions are always completely new when an ODEProblem is constructed as far as the compiler understands.

So my question: is there a solution to this problem?

Potential solution 1: If I serialize the prob object, then I can deserialize it and use remake to adjust parameters and tspan. This seems to keep the runtime generated function in the Julia compilation memory which would be stored in the system image by PackageCompiler.jl.

Potential solution 2: Maybe a keyword argument to be supplied to the ODEProblem to store the runtime generated functions to a specified *.jl file. In this way I think the functions would remain more static, even if the ODEProblem is reconstructed. The functions would only need to be recompiled if they change, which I think Julia could keep track of if they are defined in files.

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