Skip to content

Commit a30547c

Browse files
committed
Merge remote-tracking branch 'origin/master' into sm/symutils3
2 parents 22d208c + 35af497 commit a30547c

12 files changed

+200
-72
lines changed

Project.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelingToolkit"
22
uuid = "961ee093-0014-501f-94e3-6117800e7a78"
33
authors = ["Chris Rackauckas <[email protected]>"]
4-
version = "3.20.1"
4+
version = "3.21.0"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
@@ -11,7 +11,6 @@ DiffEqJump = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12"
1111
DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b"
1212
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
1313
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
14-
GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb"
1514
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
1615
LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800"
1716
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
@@ -22,6 +21,7 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
2221
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
2322
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
2423
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
24+
RuntimeGeneratedFunctions = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
2525
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
2626
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2727
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
@@ -34,11 +34,10 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
3434
[compat]
3535
ArrayInterface = "2.8"
3636
DataStructures = "0.17, 0.18"
37-
DiffEqBase = "6.38"
37+
DiffEqBase = "6.48"
3838
DiffEqJump = "6.7.5"
3939
DiffRules = "0.1, 1.0"
4040
DocStringExtensions = "0.7, 0.8"
41-
GeneralizedGenerated = "0.1.4, 0.2"
4241
IfElse = "0.1"
4342
LabelledArrays = "1.3"
4443
Latexify = "0.11, 0.12, 0.13, 0.14"
@@ -47,6 +46,7 @@ MacroTools = "0.5"
4746
NaNMath = "0.3"
4847
RecursiveArrayTools = "2.3"
4948
Requires = "1.0"
49+
RuntimeGeneratedFunctions = "0.4"
5050
SafeTestsets = "0.0.1"
5151
SpecialFunctions = "0.7, 0.8, 0.9, 0.10"
5252
StaticArrays = "0.10, 0.11, 0.12"
@@ -59,11 +59,13 @@ julia = "1.2"
5959
[extras]
6060
Dagger = "d58978e5-989f-55fb-8d15-ea34adc7bf54"
6161
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
62+
GalacticOptim = "a75be94c-b780-496d-a8a9-0878b188d577"
63+
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
6264
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
6365
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
6466
SteadyStateDiffEq = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f"
6567
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
6668
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6769

6870
[targets]
69-
test = ["Dagger", "ForwardDiff", "OrdinaryDiffEq", "Random", "SteadyStateDiffEq", "Test", "StochasticDiffEq"]
71+
test = ["Dagger", "ForwardDiff", "GalacticOptim", "OrdinaryDiffEq", "Optim", "Random", "SteadyStateDiffEq", "Test", "StochasticDiffEq"]

src/ModelingToolkit.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ using UnPack: @unpack
88
using DiffEqJump
99
using DataStructures: OrderedDict, OrderedSet
1010
using SpecialFunctions, NaNMath
11+
using RuntimeGeneratedFunctions
1112
using Base.Threads
1213
import MacroTools: splitdef, combinedef, postwalk, striplines
13-
import GeneralizedGenerated
1414
import Libdl
1515
using DocStringExtensions
1616
using Base: RefValue
1717
import IfElse
1818

19+
RuntimeGeneratedFunctions.init(@__MODULE__)
20+
1921
using RecursiveArrayTools
2022

2123
import SymbolicUtils

src/build_function.jl

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,7 @@ function _build_function(target::JuliaTarget, op, args...;
130130
end
131131

132132
function _build_and_inject_function(mod::Module, ex)
133-
# Generate the function, which will process the expression
134-
runtimefn = GeneralizedGenerated.mk_function(mod, ex)
135-
136-
# Extract the processed expression of the function body
137-
params = typeof(runtimefn).parameters
138-
fn_expr = GeneralizedGenerated.NGG.from_type(params[3])
139-
140-
# Inject our externally registered module functions
141-
new_expr = ModelingToolkit.inject_registered_module_functions(fn_expr)
142-
143-
# Reconstruct the RuntimeFn's Body
144-
new_body = GeneralizedGenerated.NGG.to_type(new_expr)
145-
return GeneralizedGenerated.RuntimeFn{params[1:2]..., new_body, params[4]}()
133+
@RuntimeGeneratedFunction(ModelingToolkit.inject_registered_module_functions(ex))
146134
end
147135

148136
# Detect heterogeneous element types of "arrays of matrices/sparce matrices"
@@ -186,7 +174,7 @@ function _build_function(target::JuliaTarget, rhss, args...;
186174
187175
Generates a Julia function which can then be utilized for further evaluations.
188176
If expression=Val{false}, the return is a Julia function which utilizes
189-
GeneralizedGenerated.jl in order to be free of world-age issues.
177+
RuntimeGeneratedFunctions.jl in order to be free of world-age issues.
190178
191179
If the `Expression` is an `Operation`, the generated function is a function
192180
with a scalar output, otherwise if it's an `AbstractArray{Operation}`, the output
@@ -570,7 +558,7 @@ function _build_function(target::CTarget, eqs::Array{<:Equation}, args...;
570558
open(`gcc -fPIC -O3 -msse3 -xc -shared -o $(libpath * "." * Libdl.dlext) -`, "w") do f
571559
print(f, ex)
572560
end
573-
eval(:((du::Array{Float64},u::Array{Float64},p::Array{Float64},t::Float64) -> ccall(("diffeqf", $libpath), Cvoid, (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Float64), du, u, p, t)))
561+
@RuntimeGeneratedFunction(:((du::Array{Float64},u::Array{Float64},p::Array{Float64},t::Float64) -> ccall(("diffeqf", $libpath), Cvoid, (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Float64), du, u, p, t)))
574562
end
575563
end
576564

src/systems/control/controlsystem.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ function runge_kutta_discretize(sys::ControlSystem,dt,tspan;
132132
n = length(tspan[1]:dt:tspan[2]) - 1
133133
m = length(tab.α)
134134

135-
f = eval(build_function([x.rhs for x in equations(sys)],sys.states,sys.controls,sys.ps,sys.iv,conv = ModelingToolkit.ControlToExpr(sys))[1])
136-
L = eval(build_function(sys.loss,sys.states,sys.controls,sys.ps,sys.iv,conv = ModelingToolkit.ControlToExpr(sys)))
135+
f = @RuntimeGeneratedFunction(build_function([x.rhs for x in equations(sys)],sys.states,sys.controls,sys.ps,sys.iv,conv = ModelingToolkit.ControlToExpr(sys))[1])
136+
L = @RuntimeGeneratedFunction(build_function(sys.loss,sys.states,sys.controls,sys.ps,sys.iv,conv = ModelingToolkit.ControlToExpr(sys)))
137137

138138
var(n, i...) = var(nameof(n), i...)
139139
var(n::Symbol, i...) = Sym{FnType{Tuple{symtype(sys.iv)}, Number}}(nameof(Variable(n, i...)))

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,15 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys),
133133
kwargs...) where {iip}
134134

135135
f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, kwargs...)
136-
f_oop,f_iip = eval_expression ? ModelingToolkit.eval.(f_gen) : f_gen
136+
f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in f_gen) : f_gen
137137
f(u,p,t) = f_oop(u,p,t)
138138
f(du,u,p,t) = f_iip(du,u,p,t)
139139

140140
if tgrad
141141
tgrad_gen = generate_tgrad(sys, dvs, ps;
142142
simplify=simplify,
143143
expression=Val{eval_expression}, kwargs...)
144-
tgrad_oop,tgrad_iip = eval_expression ? ModelingToolkit.eval.(tgrad_gen) : tgrad_gen
144+
tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in tgrad_gen) : tgrad_gen
145145
_tgrad(u,p,t) = tgrad_oop(u,p,t)
146146
_tgrad(J,u,p,t) = tgrad_iip(J,u,p,t)
147147
else
@@ -152,7 +152,7 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys),
152152
jac_gen = generate_jacobian(sys, dvs, ps;
153153
simplify=simplify, sparse = sparse,
154154
expression=Val{eval_expression}, kwargs...)
155-
jac_oop,jac_iip = eval_expression ? ModelingToolkit.eval.(jac_gen) : jac_gen
155+
jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in jac_gen) : jac_gen
156156
_jac(u,p,t) = jac_oop(u,p,t)
157157
_jac(J,u,p,t) = jac_iip(J,u,p,t)
158158
else
@@ -163,12 +163,12 @@ function DiffEqBase.ODEFunction{iip}(sys::AbstractODESystem, dvs = states(sys),
163163

164164
_M = (u0 === nothing || M == I) ? M : ArrayInterface.restructure(u0 .* u0',M)
165165

166-
ODEFunction{iip}(DiffEqBase.EvalFunc(f),
167-
jac = _jac === nothing ? nothing : DiffEqBase.EvalFunc(_jac),
168-
tgrad = _tgrad === nothing ? nothing : DiffEqBase.EvalFunc(_tgrad),
169-
mass_matrix = _M,
170-
jac_prototype = sparse ? similar(sys.jac[],Float64) : nothing,
171-
syms = Symbol.(states(sys)))
166+
ODEFunction{iip}(f,
167+
jac = _jac === nothing ? nothing : _jac,
168+
tgrad = _tgrad === nothing ? nothing : _tgrad,
169+
mass_matrix = _M,
170+
jac_prototype = sparse ? similar(sys.jac[],Float64) : nothing,
171+
syms = Symbol.(states(sys)))
172172
end
173173

174174
"""

src/systems/diffeqs/modelingtoolkitize.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,27 @@ function modelingtoolkitize(prob::DiffEqBase.SDEProblem)
8787

8888
de
8989
end
90+
91+
92+
"""
93+
$(TYPEDSIGNATURES)
94+
95+
Generate `OptimizationSystem`, dependent variables, and parameters from an `OptimizationProblem`.
96+
"""
97+
function modelingtoolkitize(prob::DiffEqBase.OptimizationProblem)
98+
99+
if prob.p isa Tuple || prob.p isa NamedTuple
100+
p = [x for x in prob.p]
101+
else
102+
p = prob.p
103+
end
104+
105+
vars = reshape([Variable(:x, i)() for i in eachindex(prob.u0)],size(prob.u0))
106+
params = p isa DiffEqBase.NullParameters ? [] :
107+
reshape([Variable(,i)() for i in eachindex(p)],size(Array(p)))
108+
109+
110+
eqs = prob.f(vars, params)
111+
de = OptimizationSystem(eqs,vec(vars),vec(params))
112+
de
113+
end

src/systems/diffeqs/sdesystem.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ function DiffEqBase.SDEFunction{iip}(sys::SDESystem, dvs = sys.states, ps = sys.
148148
version = nothing, tgrad=false, sparse = false,
149149
jac = false, Wfact = false, eval_expression = true, kwargs...) where {iip}
150150
f_gen = generate_function(sys, dvs, ps; expression=Val{eval_expression}, kwargs...)
151-
f_oop,f_iip = eval_expression ? ModelingToolkit.eval.(f_gen) : f_gen
151+
f_oop,f_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in f_gen) : f_gen
152152
g_gen = generate_diffusion_function(sys, dvs, ps; expression=Val{eval_expression}, kwargs...)
153-
g_oop,g_iip = eval_expression ? ModelingToolkit.eval.(g_gen) : g_gen
153+
g_oop,g_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in g_gen) : g_gen
154154

155155
f(u,p,t) = f_oop(u,p,t)
156156
f(du,u,p,t) = f_iip(du,u,p,t)
@@ -159,7 +159,7 @@ function DiffEqBase.SDEFunction{iip}(sys::SDESystem, dvs = sys.states, ps = sys.
159159

160160
if tgrad
161161
tgrad_gen = generate_tgrad(sys, dvs, ps; expression=Val{eval_expression}, kwargs...)
162-
tgrad_oop,tgrad_iip = eval_expression ? ModelingToolkit.eval.(tgrad_gen) : tgrad_gen
162+
tgrad_oop,tgrad_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in tgrad_gen) : tgrad_gen
163163
_tgrad(u,p,t) = tgrad_oop(u,p,t)
164164
_tgrad(J,u,p,t) = tgrad_iip(J,u,p,t)
165165
else
@@ -168,7 +168,7 @@ function DiffEqBase.SDEFunction{iip}(sys::SDESystem, dvs = sys.states, ps = sys.
168168

169169
if jac
170170
jac_gen = generate_jacobian(sys, dvs, ps; expression=Val{eval_expression}, sparse=sparse, kwargs...)
171-
jac_oop,jac_iip = eval_expression ? ModelingToolkit.eval.(jac_gen) : jac_gen
171+
jac_oop,jac_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in jac_gen) : jac_gen
172172
_jac(u,p,t) = jac_oop(u,p,t)
173173
_jac(J,u,p,t) = jac_iip(J,u,p,t)
174174
else
@@ -177,8 +177,8 @@ function DiffEqBase.SDEFunction{iip}(sys::SDESystem, dvs = sys.states, ps = sys.
177177

178178
if Wfact
179179
tmp_Wfact,tmp_Wfact_t = generate_factorized_W(sys, dvs, ps, true; expression=Val{true}, kwargs...)
180-
Wfact_oop, Wfact_iip = eval_expression ? ModelingToolkit.eval.(tmp_Wfact) : tmp_Wfact
181-
Wfact_oop_t, Wfact_iip_t = eval_expression ? ModelingToolkit.eval.(tmp_Wfact_t) : tmp_Wfact_t
180+
Wfact_oop, Wfact_iip = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in tmp_Wfact) : tmp_Wfact
181+
Wfact_oop_t, Wfact_iip_t = eval_expression ? (@RuntimeGeneratedFunction(ex) for ex in tmp_Wfact_t) : tmp_Wfact_t
182182
_Wfact(u,p,dtgamma,t) = Wfact_oop(u,p,dtgamma,t)
183183
_Wfact(W,u,p,dtgamma,t) = Wfact_iip(W,u,p,dtgamma,t)
184184
_Wfact_t(u,p,dtgamma,t) = Wfact_oop_t(u,p,dtgamma,t)
@@ -190,13 +190,13 @@ function DiffEqBase.SDEFunction{iip}(sys::SDESystem, dvs = sys.states, ps = sys.
190190
M = calculate_massmatrix(sys)
191191
_M = (u0 === nothing || M == I) ? M : ArrayInterface.restructure(u0 .* u0',M)
192192

193-
SDEFunction{iip}(DiffEqBase.EvalFunc(f),DiffEqBase.EvalFunc(g),
194-
jac = _jac === nothing ? nothing : DiffEqBase.EvalFunc(_jac),
195-
tgrad = _tgrad === nothing ? nothing : DiffEqBase.EvalFunc(_tgrad),
196-
Wfact = _Wfact === nothing ? nothing : DiffEqBase.EvalFunc(_Wfact),
197-
Wfact_t = _Wfact_t === nothing ? nothing : DiffEqBase.EvalFunc(_Wfact_t),
198-
mass_matrix = _M,
199-
syms = Symbol.(sys.states))
193+
SDEFunction{iip}(f,g,
194+
jac = _jac === nothing ? nothing : _jac,
195+
tgrad = _tgrad === nothing ? nothing : _tgrad,
196+
Wfact = _Wfact === nothing ? nothing : _Wfact,
197+
Wfact_t = _Wfact_t === nothing ? nothing : _Wfact_t,
198+
mass_matrix = _M,
199+
syms = Symbol.(sys.states))
200200
end
201201

202202
function DiffEqBase.SDEFunction(sys::SDESystem, args...; kwargs...)

src/systems/jumps/jumpsystem.jl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ function generate_affect_function(js, affect, outputidxs)
8585
end
8686

8787
function assemble_vrj(js, vrj, statetoid)
88-
rate = eval(generate_rate_function(js, vrj.rate))
88+
rate = @RuntimeGeneratedFunction(generate_rate_function(js, vrj.rate))
8989
outputvars = (value(affect.lhs) for affect in vrj.affect!)
9090
outputidxs = ((statetoid[var] for var in outputvars)...,)
91-
affect = eval(generate_affect_function(js, vrj.affect!, outputidxs))
91+
affect = @RuntimeGeneratedFunction(generate_affect_function(js, vrj.affect!, outputidxs))
9292
VariableRateJump(rate, affect)
9393
end
9494

@@ -105,10 +105,10 @@ function assemble_vrj_expr(js, vrj, statetoid)
105105
end
106106

107107
function assemble_crj(js, crj, statetoid)
108-
rate = eval(generate_rate_function(js, crj.rate))
108+
rate = @RuntimeGeneratedFunction(generate_rate_function(js, crj.rate))
109109
outputvars = (value(affect.lhs) for affect in crj.affect!)
110110
outputidxs = ((statetoid[var] for var in outputvars)...,)
111-
affect = eval(generate_affect_function(js, crj.affect!, outputidxs))
111+
affect = @RuntimeGeneratedFunction(generate_affect_function(js, crj.affect!, outputidxs))
112112
ConstantRateJump(rate, affect)
113113
end
114114

@@ -196,8 +196,7 @@ function DiffEqBase.DiscreteProblem(sys::JumpSystem, u0map, tspan::Tuple,
196196
else
197197
p = parammap
198198
end
199-
# EvalFunc because we know that the jump functions are generated via eval
200-
f = DiffEqBase.EvalFunc(DiffEqBase.DISCRETE_INPLACE_DEFAULT)
199+
f = DiffEqBase.DISCRETE_INPLACE_DEFAULT
201200
df = DiscreteFunction(f, syms=Symbol.(states(sys)))
202201
DiscreteProblem(df, u0, tspan, p; kwargs...)
203202
end
@@ -226,9 +225,8 @@ function DiscreteProblemExpr(sys::JumpSystem, u0map, tspan::Tuple,
226225
u0 = varmap_to_vars(u0map, states(sys))
227226
p = varmap_to_vars(parammap, parameters(sys))
228227
# identity function to make syms works
229-
# EvalFunc because we know that the jump functions are generated via eval
230228
quote
231-
f = DiffEqBase.EvalFunc(DiffEqBase.DISCRETE_INPLACE_DEFAULT)
229+
f = DiffEqBase.DISCRETE_INPLACE_DEFAULT
232230
u0 = $u0
233231
p = $p
234232
tspan = $tspan
@@ -282,7 +280,7 @@ end
282280

283281

284282
### Functions to determine which states a jump depends on
285-
function get_variables!(dep, jump::Union{ConstantRateJump,VariableRateJump}, variables)
283+
function get_variables!(dep, jump::Union{ConstantRateJump,VariableRateJump}, variables)
286284
(jump.rate isa Symbolic) && get_variables!(dep, jump.rate, variables)
287285
dep
288286
end

0 commit comments

Comments
 (0)