Skip to content

Commit 6745da8

Browse files
Merge pull request #4685 from KristofferC/kc/cache_maps
cache `parameters`, `namespacemap` and `reorder_parameters`
2 parents 6cab99e + 0c5ade6 commit 6745da8

3 files changed

Lines changed: 100 additions & 28 deletions

File tree

lib/ModelingToolkitBase/src/systems/abstractsystem.jl

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,27 +1613,47 @@ function __no_initial_params_pred(x::SymbolicT)
16131613
end
16141614
end
16151615

1616-
"""
1617-
$(TYPEDSIGNATURES)
1616+
struct CachedSystemParameters
1617+
value::Vector{SymbolicT}
1618+
end
16181619

1619-
Get the parameters of the system `sys` and its subsystems.
1620+
function should_invalidate_mutable_cache_entry(::Type{CachedSystemParameters}, patch::NamedTuple)
1621+
return haskey(patch, :ps) || haskey(patch, :systems)
1622+
end
16201623

1621-
See also [`@parameters`](@ref) and [`ModelingToolkitBase.get_ps`](@ref).
1622-
"""
1623-
function parameters(sys::AbstractSystem; initial_parameters = false)
1624+
function _unfiltered_parameters(sys::AbstractSystem)
16241625
ps = get_ps(sys)
1625-
if ps === SciMLBase.NullParameters()
1626-
return SymbolicT[]
1627-
end
1626+
ps === SciMLBase.NullParameters() && return SymbolicT[]
16281627
if eltype(ps) <: Pair
16291628
ps = Vector{SymbolicT}(unwrap.(first.(ps)))
16301629
end
1631-
systems = get_systems(sys)
16321630
result = OrderedSet{SymbolicT}(ps)
1633-
for subsys in systems
1631+
for subsys in get_systems(sys)
16341632
union!(result, namespace_parameters(subsys))
16351633
end
1636-
result = collect(result)
1634+
return collect(result)
1635+
end
1636+
1637+
"""
1638+
$(TYPEDSIGNATURES)
1639+
1640+
Get the parameters of the system `sys` and its subsystems.
1641+
1642+
See also [`@parameters`](@ref) and [`ModelingToolkitBase.get_ps`](@ref).
1643+
"""
1644+
function parameters(sys::AbstractSystem; initial_parameters = false)
1645+
if sys isa System && iscomplete(sys)
1646+
cached = check_mutable_cache(sys, CachedSystemParameters, CachedSystemParameters, nothing)
1647+
if cached isa CachedSystemParameters
1648+
result = copy(cached.value)
1649+
else
1650+
base = _unfiltered_parameters(sys)
1651+
store_to_mutable_cache!(sys, CachedSystemParameters, CachedSystemParameters(base))
1652+
result = copy(base)
1653+
end
1654+
else
1655+
result = _unfiltered_parameters(sys)
1656+
end
16371657
if !initial_parameters && !is_initializesystem(sys)
16381658
filter!(__no_initial_params_pred, result)
16391659
end

lib/ModelingToolkitBase/src/systems/codegen.jl

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,43 @@ function (pred::CheckInvalidAndTrackNamespaced)(x::SymbolicT)
11781178
return false
11791179
end
11801180

1181+
struct NamespaceMap
1182+
value::Dict{SymbolicT, SymbolicT}
1183+
end
1184+
1185+
function should_invalidate_mutable_cache_entry(::Type{NamespaceMap}, patch::NamedTuple)
1186+
return haskey(patch, :name) || haskey(patch, :observed) || haskey(patch, :unknowns) ||
1187+
haskey(patch, :ps) || haskey(patch, :systems)
1188+
end
1189+
1190+
function _build_namespace_map(sys)
1191+
ns_map = Dict{SymbolicT, SymbolicT}(renamespace(sys, eq.lhs) => eq.lhs for eq in observed(sys))
1192+
for sym in unknowns(sys)
1193+
ns_map[renamespace(sys, sym)] = sym
1194+
if iscall(sym) && operation(sym) === getindex
1195+
ns_map[renamespace(sys, arguments(sym)[1])] = arguments(sym)[1]
1196+
end
1197+
end
1198+
for sym in parameters(sys; initial_parameters = true)
1199+
ns_map[renamespace(sys, sym)] = sym
1200+
if iscall(sym) && operation(sym) === getindex
1201+
ns_map[renamespace(sys, arguments(sym)[1])] = arguments(sym)[1]
1202+
end
1203+
end
1204+
return ns_map
1205+
end
1206+
1207+
function get_namespace_map(sys)
1208+
if sys isa System && iscomplete(sys)
1209+
cached = check_mutable_cache(sys, NamespaceMap, NamespaceMap, nothing)
1210+
cached isa NamespaceMap && return cached.value
1211+
m = _build_namespace_map(sys)
1212+
store_to_mutable_cache!(sys, NamespaceMap, NamespaceMap(m))
1213+
return m
1214+
end
1215+
return _build_namespace_map(sys)
1216+
end
1217+
11811218
"""
11821219
build_explicit_observed_function(sys, ts; kwargs...) -> Function(s)
11831220
@@ -1283,19 +1320,7 @@ Base.@nospecializeinfer function build_explicit_observed_function(
12831320
end
12841321

12851322
namespace_subs = Dict{SymbolicT, SymbolicT}()
1286-
ns_map = Dict{SymbolicT, SymbolicT}(renamespace(sys, eq.lhs) => eq.lhs for eq in observed(sys))
1287-
for sym in unknowns(sys)
1288-
ns_map[renamespace(sys, sym)] = sym
1289-
if iscall(sym) && operation(sym) === getindex
1290-
ns_map[renamespace(sys, arguments(sym)[1])] = arguments(sym)[1]
1291-
end
1292-
end
1293-
for sym in parameters(sys; initial_parameters = true)
1294-
ns_map[renamespace(sys, sym)] = sym
1295-
if iscall(sym) && operation(sym) === getindex
1296-
ns_map[renamespace(sys, arguments(sym)[1])] = arguments(sym)[1]
1297-
end
1298-
end
1323+
ns_map = get_namespace_map(sys)
12991324
allsyms = as_atomic_array_set(unknowns(sys))
13001325
foreach(Base.Fix1(push_as_atomic_array!, allsyms), observables(sys))
13011326
foreach(Base.Fix1(push_as_atomic_array!, allsyms), parameters(sys; initial_parameters = true))

lib/ModelingToolkitBase/src/systems/index_cache.jl

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,36 @@ end
588588

589589
const ReorderedParametersT = Vector{Union{Vector{SymbolicT}, Vector{Vector{SymbolicT}}}}
590590

591-
function reorder_parameters(
592-
sys::AbstractSystem, ps = parameters(sys; initial_parameters = true); kwargs...
593-
)
591+
struct ReorderedDefaultParameters
592+
value::ReorderedParametersT
593+
end
594+
595+
function should_invalidate_mutable_cache_entry(::Type{ReorderedDefaultParameters}, patch::NamedTuple)
596+
return haskey(patch, :ps) || haskey(patch, :index_cache)
597+
end
598+
599+
function _copy_reordered(v::ReorderedParametersT)
600+
return ReorderedParametersT(map(v) do inner
601+
inner isa Vector{SymbolicT} ? copy(inner) : map(copy, inner)
602+
end)
603+
end
604+
605+
function reorder_parameters(sys::AbstractSystem; kwargs...)
606+
if isempty(kwargs) && sys isa System && has_index_cache(sys) && get_index_cache(sys) !== nothing
607+
cached = check_mutable_cache(sys, ReorderedDefaultParameters, ReorderedDefaultParameters, nothing)
608+
if cached isa ReorderedDefaultParameters
609+
return _copy_reordered(cached.value)
610+
end
611+
val = reorder_parameters(
612+
get_index_cache(sys)::IndexCache, parameters(sys; initial_parameters = true)
613+
)
614+
store_to_mutable_cache!(sys, ReorderedDefaultParameters, ReorderedDefaultParameters(val))
615+
return _copy_reordered(val)
616+
end
617+
return reorder_parameters(sys, parameters(sys; initial_parameters = true); kwargs...)
618+
end
619+
620+
function reorder_parameters(sys::AbstractSystem, ps; kwargs...)
594621
if has_index_cache(sys) && get_index_cache(sys) !== nothing
595622
return reorder_parameters(get_index_cache(sys)::IndexCache, ps; kwargs...)
596623
elseif ps isa Tuple

0 commit comments

Comments
 (0)