# Exporting a \`RuntimeGeneratedFunction\`

**URL:** https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628
**Category:** General Usage
**Tags:** question, package, runtimegeneratedfunc
**Created:** [June 27, 2021, 4:13am UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628 "2021-06-27T04:13:32Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![cadojo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadojo/32/25328_2.png) [@cadojo](https://discourse.julialang.org/u/cadojo)
#### Post date: [June 27, 2021, 4:13am UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628/1 "2021-06-27T04:13:32Z")

</div>

I have a `ModelingToolkit.ODESystem` in a package called `AstrodynamicalModels`. I want to export an `ODEFunction`, which uses `RuntimeGeneratedFunctions` to avoid world-age issues.

When I `import AstrodynamicalModels`, and try to call one of the exported `ODEFunction`s, I get errors like…

```julia
ERROR: KeyError: key (0x0f45875b, 0xbf13700d, 0x6254b25f, 0x472f60fd, 0x500c018f) not found
Stacktrace:
  [1] getindex(h::Dict{Any, Any}, key::NTuple{5, UInt32})
    @ Base ./dict.jl:482
  [2] (::RuntimeGeneratedFunctions.var"#8#9"{DataType, NTuple{5, UInt32}})()
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/3SZ1T/src/RuntimeGeneratedFunctions.jl:177
  [3] lock(f::RuntimeGeneratedFunctions.var"#8#9"{DataType, NTuple{5, UInt32}}, l::Base.Threads.SpinLock)
    @ Base ./lock.jl:187
  [4] _lookup_body(cache_tag::Type, id::NTuple{5, UInt32})
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/3SZ1T/src/RuntimeGeneratedFunctions.jl:175
  [5] generated_callfunc_body(argnames::Tuple{Symbol, Symbol, Symbol}, cache_tag::Type, id::NTuple{5, UInt32}, __args::Tuple{DataType, DataType, DataType})
    @ RuntimeGeneratedFunctions ~/.julia/packages/RuntimeGeneratedFunctions/3SZ1T/src/RuntimeGeneratedFunctions.jl:120
  [6] #s1#1
    @ ~/.julia/packages/RuntimeGeneratedFunctions/3SZ1T/src/RuntimeGeneratedFunctions.jl:208 [inlined]
  [7] var"#s1#1"(argnames::Any, cache_tag::Any, id::Any, ::Any, f::Any, __args::Any)
    @ ModelingToolkit ./none:0
  [8] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:571
  [9] RuntimeGeneratedFunction
    @ ~/.julia/packages/RuntimeGeneratedFunctions/3SZ1T/src/RuntimeGeneratedFunctions.jl:112 [inlined]
 [10] WARNING: both BipartiteGraphs and Symbolics export "degree"; uses of it in module ModelingToolkit must be qualified
(::ModelingToolkit.var"#f#154"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##arg#257"), Symbol("##arg#258"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x0f45875b, 0xbf13700d, 0x6254b25f, 0x472f60fd, 0x500c018f)}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##out#259"), Symbol("##arg#257"), Symbol("##arg#258"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x05b84fb3, 0x7fd909c0, 0xe2ea4e2e, 0xd451c079, 0xdb963cd2)}})(u::Vector{Float64}, p::Vector{Float64}, t::Int64)
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/MuQfD/src/systems/diffeqs/abstractodesystem.jl:172
 [11] (::SciMLBase.ODEFunction{true, ModelingToolkit.var"#f#154"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##arg#257"), Symbol("##arg#258"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x0f45875b, 0xbf13700d, 0x6254b25f, 0x472f60fd, 0x500c018f)}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##out#259"), Symbol("##arg#257"), Symbol("##arg#258"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x05b84fb3, 0x7fd909c0, 0xe2ea4e2e, 0xd451c079, 0xdb963cd2)}}, LinearAlgebra.UniformScaling{Bool}, Nothing, ModelingToolkit.var"#_tgrad#156"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##arg#260"), Symbol("##arg#261"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x5a70bcaf, 0x1cb7174b, 0x74cbb369, 0x6301c195, 0xec003f66)}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##out#262"), Symbol("##arg#260"), Symbol("##arg#261"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x88bc7821, 0xa7965577, 0x7753fb47, 0x26894a1e, 0xdbcb458b)}}, ModelingToolkit.var"#_jac#158"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##arg#263"), Symbol("##arg#264"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x41408862, 0x8ffcdf82, 0x4bb2beb5, 0x0e4f95da, 0xee6c5722)}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol("##out#265"), Symbol("##arg#263"), Symbol("##arg#264"), :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x07b2ef70, 0xd8ac1b87, 0x913b9755, 0x3da83bbe, 0xde306d03)}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Symbol}, Symbol, ModelingToolkit.var"#159#generated_observed#161"{Bool, ModelingToolkit.ODESystem, Dict{Any, Any}}, Nothing})(::Vector{Float64}, ::Vararg{Any, N} where N)
    @ SciMLBase ~/.julia/packages/SciMLBase/kCcpg/src/scimlfunctions.jl:334
 [12] top-level scope
    @ REPL[2]:1

```

The following MWE is illustrative of what I’m trying to do, but because `MyModule` is defined directly in `Main`, this example **actually works without error**.

Is what I’m trying to do (export an `ODEFunction` to users) possible?

```julia
module MyModule

using StaticArrays
using LinearAlgebra
using ModelingToolkit
using RuntimeGeneratedFunctions
RuntimeGeneratedFunctions.init(@ __MODULE__ )

"""
A `ModelingToolkit.ODESystem` for the Restricted Two-body Problem. 

The Restricted Two-body Problem is a simplified dynamical model 
describing one small body (spacecraft, etc.) and one celestial 
body. The gravity of the celestial body exhibits a force on the 
small body. This model is commonly used as a simplification to 
descibe our solar systems' planets orbiting our sun, or a 
spacecraft orbiting Earth. 
"""
R2BP = let

    @parameters t μ 
    @variables x(t) y(t) z(t) ẋ(t) ẏ(t) ż(t)
    δ = Differential(t)
    r = @SVector [x,y,z]
    v = @SVector [ẋ,ẏ,ż]

    eqs = vcat(
        δ.(r) .~ v,
        δ.(v) .~ -μ .* (r ./ norm(r)^3)
    )

    @named R2BP = ODESystem(eqs, t, vcat(r,v), [μ])

end

"""
A `DifferentialEquations`-compatible `ODEFunction` for R2BP dynamics.
Note that this function has several methods, including an in-place 
method! Function signatures follow `ModelingToolkit` and `DifferentialEquations`
conventions.
"""
R2BPVectorField = ODEFunction(R2BP; jac = true, tgrad = true)

end # module

```

But when I try to call `R2BPVectorField` outside of `MyModule`, I get an error. I’m sure this is a user error, since my understanding of world age issues and `RuntimeGeneratedFunction` usage is a bit incomplete. Is there a way to return a "compiled’ or “runtime-generated” function to a user, from a module?

```julia
import MyModule
MyModule.R2BPVectorField(
  randn(6), # state
  randn(1), # params
  0.0 # time
)

```

---

<div class="post-metadata">

### Author: ![cadojo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadojo/32/25328_2.png) [@cadojo](https://discourse.julialang.org/u/cadojo)
#### Post date: [June 27, 2021, 11:11pm UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628/2 "2021-06-27T23:11:02Z")

</div>

I [understand](https://github.com/SciML/RuntimeGeneratedFunctions.jl#precompilation-and-setting-the-function-expression-cache) that I can export a function with _returns_ a compiled `ODEFunction`, but I’d prefer to avoid that if I can.

Is there any way to generate a symbolic (`eval_expression = false`) `ODEFunction` in a module, and then provide a function to “compile” each symbolic `ODEFunction` so the user can call them?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [June 28, 2021, 12:23am UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628/3 "2021-06-28T00:23:31Z")

</div>

The problem is likely the mix with precompilation, where you need to do something like this:

> <https://github.com/SciML/ModelingToolkit.jl/blob/master/test/precompile_test/ODEPrecompileTest.jl>

---

<div class="post-metadata">

### Author: ![cadojo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadojo/32/25328_2.png) [@cadojo](https://discourse.julialang.org/u/cadojo)
#### Post date: [June 28, 2021, 4:10pm UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628/4 "2021-06-28T16:10:31Z")

</div>

> [@ChrisRackauckas](#):
>
> The problem is likely the mix with precompilation, where you need to do something like this:

Thank you for this, the package now works. Even if I use the keyword arguments ` eval_expression=false, eval_module=@ __MODULE__ `, if I **don’t** use `const` for the function I’d like to export, I get `key not found` errors.

Not sure why that’s the case, but like I said, I only have a cursory understanding for how world age issues and runtime generated functions work. Thank you for the help!

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [June 28, 2021, 10:34pm UTC](https://discourse.julialang.org/t/exporting-a-runtimegeneratedfunction/63628/5 "2021-06-28T22:34:11Z")

</div>

> [@cadojo](#):
>
> Thank you for this, the package now works. Even if I use the keyword arguments ` eval_expression=false, eval_module=@ __MODULE__ ` , if I **don’t** use `const` for the function I’d like to export, I get `key not found` errors.

open an issue on RGFs
