From c595416864bded32a4aab6ad3a73222c41e432dc Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Wed, 4 Jun 2025 18:48:33 +0530 Subject: [PATCH] fix: fix major compile time regression due to `concrete_getu` --- src/systems/problem_utils.jl | 50 +++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/systems/problem_utils.jl b/src/systems/problem_utils.jl index 5ff00b4845..f79e8f6286 100644 --- a/src/systems/problem_utils.jl +++ b/src/systems/problem_utils.jl @@ -617,30 +617,40 @@ struct ReconstructInitializeprob{GP, GU} ugetter::GU end +""" + $(TYPEDEF) + +A wrapper over an observed function which allows calling it on a problem-like object. +`TD` determines whether the getter function is `(u, p, t)` (if `true`) or `(u, p)` (if +`false`). +""" +struct ObservedWrapper{TD, F} + f::F +end + +ObservedWrapper{TD}(f::F) where {TD, F} = ObservedWrapper{TD, F}(f) + +function (ow::ObservedWrapper{true})(prob) + ow.f(state_values(prob), parameter_values(prob), current_time(prob)) +end + +function (ow::ObservedWrapper{false})(prob) + ow.f(state_values(prob), parameter_values(prob)) +end + """ $(TYPEDSIGNATURES) Given an index provider `indp` and a vector of symbols `syms` return a type-stable getter -function by splitting `syms` into contiguous buffers where the getter of each buffer -is type-stable and constructing a function that calls and concatenates the results. -""" -function concrete_getu(indp, syms::AbstractVector) - # a list of contiguous buffer - split_syms = [Any[syms[1]]] - # the type of the getter of the last buffer - current = typeof(getu(indp, syms[1])) - for sym in syms[2:end] - getter = getu(indp, sym) - if typeof(getter) != current - # if types don't match, build a new buffer - push!(split_syms, []) - current = typeof(getter) - end - push!(split_syms[end], sym) - end - split_syms = Tuple(split_syms) - # the getter is now type-stable, and we can vcat it to get the full buffer - return Base.Fix1(reduce, vcat) ∘ getu(indp, split_syms) +function. + +Note that the getter ONLY works for problem-like objects, since it generates an observed +function. It does NOT work for solutions. +""" +Base.@nospecializeinfer function concrete_getu(indp, syms::AbstractVector) + @nospecialize + obsfn = SymbolicIndexingInterface.observed(indp, syms) + return ObservedWrapper{is_time_dependent(indp)}(obsfn) end """