From 8c6b8249aed97f18a6de471cb5544689befd58e4 Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Thu, 3 Dec 2020 18:01:00 +0900 Subject: [PATCH 1/9] Add example of failing precompilation test. --- test/precompile_test.jl | 21 +++++++++++++++++++++ test/precompile_test/ODEPrecompileTest.jl | 22 ++++++++++++++++++++++ test/runtests.jl | 1 + 3 files changed, 44 insertions(+) create mode 100644 test/precompile_test.jl create mode 100644 test/precompile_test/ODEPrecompileTest.jl diff --git a/test/precompile_test.jl b/test/precompile_test.jl new file mode 100644 index 0000000000..1c4d504a71 --- /dev/null +++ b/test/precompile_test.jl @@ -0,0 +1,21 @@ +using Test +using ModelingToolkit + +# Test that the precompiled ODE system works +push!(LOAD_PATH, joinpath(@__DIR__, "precompile_test")) +using ODEPrecompileTest + +du = zeros(3) +u = collect(1:3) +p = collect(4:6) + +# This case does not work, because the function gets defined in ModelingToolkit +# instead of in the compiled module! +@test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_iip).parameters[2]) == ModelingToolkit +@test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_oop).parameters[2]) == ModelingToolkit +@test_throws KeyError ODEPrecompileTest.f_bad(du, u, p, 0.1) + +# This case works, because the function gets defined in the compiled module. +# @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_iip).parameters[2]) == ODEPrecompileTest +# @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_oop).parameters[2]) == ODEPrecompileTest +# @test ODEPrecompileTest.f_good(du, u, p, 0.1) \ No newline at end of file diff --git a/test/precompile_test/ODEPrecompileTest.jl b/test/precompile_test/ODEPrecompileTest.jl new file mode 100644 index 0000000000..ef5146d228 --- /dev/null +++ b/test/precompile_test/ODEPrecompileTest.jl @@ -0,0 +1,22 @@ +module ODEPrecompileTest + using ModelingToolkit + + function system(; kwargs...) + # Define some variables + @parameters t σ ρ β + @variables x(t) y(t) z(t) + @derivatives D'~t + + # Define a differential equation + eqs = [D(x) ~ σ*(y-x), + D(y) ~ x*(ρ-z)-y, + D(z) ~ x*y - β*z] + + de = ODESystem(eqs) + return ODEFunction(de, [x,y,z], [σ,ρ,β]; kwargs...) + end + + # Build a simple ODEFunction as part of the module's precompilation. + const f_bad = system() + # const f_good = system(; eval_module=@__MODULE__) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 5ad02512c9..0049c05ec1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -33,3 +33,4 @@ using SafeTestsets, Test println("Last test requires gcc available in the path!") @safetestset "C Compilation Test" begin include("ccompile.jl") end @safetestset "Latexify recipes Test" begin include("latexify.jl") end +@safetestset "Precompiled Modules Test" begin include("precompile_test.jl") end From 1b14febb4c642268cf9a2d448af24ee2503fd88b Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Thu, 3 Dec 2020 18:16:11 +0900 Subject: [PATCH 2/9] Add "eval_module" option to specify which module to use for RGF caching. --- src/build_function.jl | 5 +++-- src/systems/diffeqs/abstractodesystem.jl | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/build_function.jl b/src/build_function.jl index 752f7e69ac..2d8787e23e 100644 --- a/src/build_function.jl +++ b/src/build_function.jl @@ -100,6 +100,7 @@ end # Scalar output function _build_function(target::JuliaTarget, op, args...; conv = toexpr, expression = Val{true}, + expression_module = @__MODULE__, checkbounds = false, linenumbers = true, headerfun=addheader) @@ -127,12 +128,12 @@ function _build_function(target::JuliaTarget, op, args...; if expression == Val{true} return ModelingToolkit.inject_registered_module_functions(oop_ex) else - _build_and_inject_function(@__MODULE__, oop_ex) + _build_and_inject_function(expression_module, oop_ex) end end function _build_and_inject_function(mod::Module, ex) - @RuntimeGeneratedFunction(ModelingToolkit.inject_registered_module_functions(ex)) + @RuntimeGeneratedFunction(mod, ModelingToolkit.inject_registered_module_functions(ex)) end # Detect heterogeneous element types of "arrays of matrices/sparce matrices" diff --git a/src/systems/diffeqs/abstractodesystem.jl b/src/systems/diffeqs/abstractodesystem.jl index 388ad9c3de..216a5b7c3b 100644 --- a/src/systems/diffeqs/abstractodesystem.jl +++ b/src/systems/diffeqs/abstractodesystem.jl @@ -124,11 +124,12 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), version = nothing, tgrad=false, jac = false, eval_expression = true, + eval_module = @__MODULE__, sparse = false, simplify = true, kwargs...) where {iip} f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, kwargs...) - f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in f_gen) : f_gen + f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen f(u,p,t) = f_oop(u,p,t) f(du,u,p,t) = f_iip(du,u,p,t) @@ -136,7 +137,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), tgrad_gen = generate_tgrad(sys, dvs, ps; simplify=simplify, expression=Val{eval_expression}, kwargs...) - tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in tgrad_gen) : tgrad_gen + tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen _tgrad(u,p,t) = tgrad_oop(u,p,t) _tgrad(J,u,p,t) = tgrad_iip(J,u,p,t) else @@ -147,7 +148,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), jac_gen = generate_jacobian(sys, dvs, ps; simplify=simplify, sparse = sparse, expression=Val{eval_expression}, kwargs...) - jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in jac_gen) : jac_gen + jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen _jac(u,p,t) = jac_oop(u,p,t) _jac(J,u,p,t) = jac_iip(J,u,p,t) else From 87ec50a135e811e952579610f9b3e37ea7a56038 Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Thu, 3 Dec 2020 18:16:41 +0900 Subject: [PATCH 3/9] Add tests for "f_good" showing that "eval_module" works. --- test/precompile_test.jl | 13 ++++++------- test/precompile_test/ODEPrecompileTest.jl | 10 ++++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/test/precompile_test.jl b/test/precompile_test.jl index 1c4d504a71..d91a85133a 100644 --- a/test/precompile_test.jl +++ b/test/precompile_test.jl @@ -5,17 +5,16 @@ using ModelingToolkit push!(LOAD_PATH, joinpath(@__DIR__, "precompile_test")) using ODEPrecompileTest -du = zeros(3) u = collect(1:3) p = collect(4:6) -# This case does not work, because the function gets defined in ModelingToolkit +# This case does not work, because "f_bad" gets defined in ModelingToolkit # instead of in the compiled module! @test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_iip).parameters[2]) == ModelingToolkit @test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_oop).parameters[2]) == ModelingToolkit -@test_throws KeyError ODEPrecompileTest.f_bad(du, u, p, 0.1) +@test_throws KeyError ODEPrecompileTest.f_bad(u, p, 0.1) -# This case works, because the function gets defined in the compiled module. -# @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_iip).parameters[2]) == ODEPrecompileTest -# @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_oop).parameters[2]) == ODEPrecompileTest -# @test ODEPrecompileTest.f_good(du, u, p, 0.1) \ No newline at end of file +# This case works, because "f_good" gets defined in the precompiled module. +@test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_iip).parameters[2]) == ODEPrecompileTest +@test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_oop).parameters[2]) == ODEPrecompileTest +@test ODEPrecompileTest.f_good(u, p, 0.1) == [4, 0, -16] \ No newline at end of file diff --git a/test/precompile_test/ODEPrecompileTest.jl b/test/precompile_test/ODEPrecompileTest.jl index ef5146d228..ed9ccda7fc 100644 --- a/test/precompile_test/ODEPrecompileTest.jl +++ b/test/precompile_test/ODEPrecompileTest.jl @@ -16,7 +16,13 @@ module ODEPrecompileTest return ODEFunction(de, [x,y,z], [σ,ρ,β]; kwargs...) end - # Build a simple ODEFunction as part of the module's precompilation. + # Build an ODEFunction as part of the module's precompilation. This case + # will not work, because the generated RGFs will be put into + # ModelingToolkit's RGF cache. const f_bad = system() - # const f_good = system(; eval_module=@__MODULE__) + + # This case will work, because it will be put into our own module's cache. + using RuntimeGeneratedFunctions + RuntimeGeneratedFunctions.init(@__MODULE__) + const f_good = system(; eval_module=@__MODULE__) end \ No newline at end of file From c9a183ebba7cf16685350e3ad100a7bd18090e2a Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Thu, 3 Dec 2020 18:37:54 +0900 Subject: [PATCH 4/9] Add expression_module as well. --- src/systems/diffeqs/abstractodesystem.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/systems/diffeqs/abstractodesystem.jl b/src/systems/diffeqs/abstractodesystem.jl index 216a5b7c3b..a38b2a343d 100644 --- a/src/systems/diffeqs/abstractodesystem.jl +++ b/src/systems/diffeqs/abstractodesystem.jl @@ -128,7 +128,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), sparse = false, simplify = true, kwargs...) where {iip} - f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, kwargs...) + f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, expression_module=eval_module, kwargs...) f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen f(u,p,t) = f_oop(u,p,t) f(du,u,p,t) = f_iip(du,u,p,t) @@ -136,7 +136,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), if tgrad tgrad_gen = generate_tgrad(sys, dvs, ps; simplify=simplify, - expression=Val{eval_expression}, kwargs...) + expression=Val{eval_expression}, expression_module=eval_module, kwargs...) tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen _tgrad(u,p,t) = tgrad_oop(u,p,t) _tgrad(J,u,p,t) = tgrad_iip(J,u,p,t) @@ -147,7 +147,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), if jac jac_gen = generate_jacobian(sys, dvs, ps; simplify=simplify, sparse = sparse, - expression=Val{eval_expression}, kwargs...) + expression=Val{eval_expression}, expression_module=eval_module, kwargs...) jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen _jac(u,p,t) = jac_oop(u,p,t) _jac(J,u,p,t) = jac_iip(J,u,p,t) From 5cda7f92f282075a7070213d3cc42a2c554f734b Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Thu, 3 Dec 2020 18:46:19 +0900 Subject: [PATCH 5/9] Also fix eval_expression=false case. --- src/build_function.jl | 3 ++- test/precompile_test.jl | 8 +++++++- test/precompile_test/ODEPrecompileTest.jl | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/build_function.jl b/src/build_function.jl index 2d8787e23e..dc6ff3642b 100644 --- a/src/build_function.jl +++ b/src/build_function.jl @@ -219,6 +219,7 @@ Special Keyword Argumnets: """ function _build_function(target::JuliaTarget, rhss::AbstractArray, args...; conv = toexpr, expression = Val{true}, + expression_module = @__MODULE__, checkbounds = false, linenumbers = false, multithread=nothing, headerfun = addheader, outputidxs=nothing, @@ -458,7 +459,7 @@ function _build_function(target::JuliaTarget, rhss::AbstractArray, args...; if expression == Val{true} return ModelingToolkit.inject_registered_module_functions(oop_ex), ModelingToolkit.inject_registered_module_functions(iip_ex) else - return _build_and_inject_function(@__MODULE__, oop_ex), _build_and_inject_function(@__MODULE__, iip_ex) + return _build_and_inject_function(expression_module, oop_ex), _build_and_inject_function(expression_module, iip_ex) end end diff --git a/test/precompile_test.jl b/test/precompile_test.jl index d91a85133a..61abebe55e 100644 --- a/test/precompile_test.jl +++ b/test/precompile_test.jl @@ -12,9 +12,15 @@ p = collect(4:6) # instead of in the compiled module! @test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_iip).parameters[2]) == ModelingToolkit @test parentmodule(typeof(ODEPrecompileTest.f_bad.f.f_oop).parameters[2]) == ModelingToolkit +@test parentmodule(typeof(ODEPrecompileTest.f_noeval_bad.f.f_iip).parameters[2]) == ModelingToolkit +@test parentmodule(typeof(ODEPrecompileTest.f_noeval_bad.f.f_oop).parameters[2]) == ModelingToolkit @test_throws KeyError ODEPrecompileTest.f_bad(u, p, 0.1) +@test_throws KeyError ODEPrecompileTest.f_noeval_bad(u, p, 0.1) # This case works, because "f_good" gets defined in the precompiled module. @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_iip).parameters[2]) == ODEPrecompileTest @test parentmodule(typeof(ODEPrecompileTest.f_good.f.f_oop).parameters[2]) == ODEPrecompileTest -@test ODEPrecompileTest.f_good(u, p, 0.1) == [4, 0, -16] \ No newline at end of file +@test parentmodule(typeof(ODEPrecompileTest.f_noeval_good.f.f_iip).parameters[2]) == ODEPrecompileTest +@test parentmodule(typeof(ODEPrecompileTest.f_noeval_good.f.f_oop).parameters[2]) == ODEPrecompileTest +@test ODEPrecompileTest.f_good(u, p, 0.1) == [4, 0, -16] +@test ODEPrecompileTest.f_noeval_good(u, p, 0.1) == [4, 0, -16] \ No newline at end of file diff --git a/test/precompile_test/ODEPrecompileTest.jl b/test/precompile_test/ODEPrecompileTest.jl index ed9ccda7fc..453cb0d774 100644 --- a/test/precompile_test/ODEPrecompileTest.jl +++ b/test/precompile_test/ODEPrecompileTest.jl @@ -25,4 +25,8 @@ module ODEPrecompileTest using RuntimeGeneratedFunctions RuntimeGeneratedFunctions.init(@__MODULE__) const f_good = system(; eval_module=@__MODULE__) + + # Also test that eval_expression=false works + const f_noeval_bad = system(; eval_expression=false) + const f_noeval_good = system(; eval_expression=false, eval_module=@__MODULE__) end \ No newline at end of file From fc64aa2d8b250fd91babf6467961b9d702a2d828 Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Fri, 18 Dec 2020 14:58:48 +0900 Subject: [PATCH 6/9] Updated syntax to use new constructor changes from RuntimeGeneratedFunctions.jl#20 --- src/build_function.jl | 2 +- src/systems/diffeqs/abstractodesystem.jl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/build_function.jl b/src/build_function.jl index dc6ff3642b..049b2f0218 100644 --- a/src/build_function.jl +++ b/src/build_function.jl @@ -133,7 +133,7 @@ function _build_function(target::JuliaTarget, op, args...; end function _build_and_inject_function(mod::Module, ex) - @RuntimeGeneratedFunction(mod, ModelingToolkit.inject_registered_module_functions(ex)) + RuntimeGeneratedFunction(mod, ModelingToolkit.inject_registered_module_functions(ex)) end # Detect heterogeneous element types of "arrays of matrices/sparce matrices" diff --git a/src/systems/diffeqs/abstractodesystem.jl b/src/systems/diffeqs/abstractodesystem.jl index a38b2a343d..3c4789f094 100644 --- a/src/systems/diffeqs/abstractodesystem.jl +++ b/src/systems/diffeqs/abstractodesystem.jl @@ -129,7 +129,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), kwargs...) where {iip} f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen + f_oop,f_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen f(u,p,t) = f_oop(u,p,t) f(du,u,p,t) = f_iip(du,u,p,t) @@ -137,7 +137,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), tgrad_gen = generate_tgrad(sys, dvs, ps; simplify=simplify, expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen + tgrad_oop,tgrad_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen _tgrad(u,p,t) = tgrad_oop(u,p,t) _tgrad(J,u,p,t) = tgrad_iip(J,u,p,t) else @@ -148,7 +148,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), jac_gen = generate_jacobian(sys, dvs, ps; simplify=simplify, sparse = sparse, expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen + jac_oop,jac_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen _jac(u,p,t) = jac_oop(u,p,t) _jac(J,u,p,t) = jac_iip(J,u,p,t) else From 6705d6adde0fe104fce11e21beda26810f0231f6 Mon Sep 17 00:00:00 2001 From: Dan Padilha Date: Fri, 18 Dec 2020 15:10:07 +0900 Subject: [PATCH 7/9] Update version requirement for RuntimeGeneratedFunctions. --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ff8d8ce886..9dd107c933 100644 --- a/Project.toml +++ b/Project.toml @@ -46,7 +46,7 @@ MacroTools = "0.5" NaNMath = "0.3" RecursiveArrayTools = "2.3" Requires = "1.0" -RuntimeGeneratedFunctions = "0.4" +RuntimeGeneratedFunctions = "0.4.3" SafeTestsets = "0.0.1" SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1.0" StaticArrays = "0.10, 0.11, 0.12, 1.0" From 73390fb98d8b74418046d1a3679b46fc32fbecd6 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 4 Jan 2021 08:10:17 -0500 Subject: [PATCH 8/9] Update abstractodesystem.jl --- src/systems/diffeqs/abstractodesystem.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/systems/diffeqs/abstractodesystem.jl b/src/systems/diffeqs/abstractodesystem.jl index 3c4789f094..a38b2a343d 100644 --- a/src/systems/diffeqs/abstractodesystem.jl +++ b/src/systems/diffeqs/abstractodesystem.jl @@ -129,7 +129,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), kwargs...) where {iip} f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - f_oop,f_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen + f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in f_gen) : f_gen f(u,p,t) = f_oop(u,p,t) f(du,u,p,t) = f_iip(du,u,p,t) @@ -137,7 +137,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), tgrad_gen = generate_tgrad(sys, dvs, ps; simplify=simplify, expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - tgrad_oop,tgrad_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen + tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in tgrad_gen) : tgrad_gen _tgrad(u,p,t) = tgrad_oop(u,p,t) _tgrad(J,u,p,t) = tgrad_iip(J,u,p,t) else @@ -148,7 +148,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys), jac_gen = generate_jacobian(sys, dvs, ps; simplify=simplify, sparse = sparse, expression=Val{eval_expression}, expression_module=eval_module, kwargs...) - jac_oop,jac_iip = eval_expression ? (RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen + jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(eval_module, ex) for ex in jac_gen) : jac_gen _jac(u,p,t) = jac_oop(u,p,t) _jac(J,u,p,t) = jac_iip(J,u,p,t) else From 8170e4d5eabbc91d56f1cab6647a19df2d51599b Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 4 Jan 2021 08:12:08 -0500 Subject: [PATCH 9/9] Update build_function.jl --- src/build_function.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build_function.jl b/src/build_function.jl index 049b2f0218..dc6ff3642b 100644 --- a/src/build_function.jl +++ b/src/build_function.jl @@ -133,7 +133,7 @@ function _build_function(target::JuliaTarget, op, args...; end function _build_and_inject_function(mod::Module, ex) - RuntimeGeneratedFunction(mod, ModelingToolkit.inject_registered_module_functions(ex)) + @RuntimeGeneratedFunction(mod, ModelingToolkit.inject_registered_module_functions(ex)) end # Detect heterogeneous element types of "arrays of matrices/sparce matrices"