[AI] Use declared inputs for input-aware codegen on compiled systems#4702
Merged
AayushSabharwal merged 3 commits intoJul 3, 2026
Merged
Conversation
unbound_inputs classifies an input as bound if it appears in an equation together with variables from another namespace. That connection-structure heuristic is only meaningful before flattening: after mtkcompile, connection and output equations are eliminated, so any effective input co-occurs with variables from other components and unbound_inputs is empty for every compiled hierarchical system. Three codegen entry points still use unbound_inputs(sys) as their default input set and silently degrade on compiled hierarchical systems: - generate_control_function warns "No unbound inputs were found" and binds the inputs at their operating-point values when handed an already-scheduled system, generating input-free dynamics - BVProblem computes n_controls = 0 and mis-shapes f_prototype - calculate_control_jacobian returns an empty jacobian Add default_codegen_inputs(sys), which returns the inputs declared to mtkcompile for scheduled systems (stored in the inputs field) and falls back to the unbound_inputs heuristic for unscheduled hierarchies. Use it at those three sites, and switch ODEInputFunction (already fixed to inputs(sys) in SciML#4406) to the same helper for consistency. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DiffEqDevTools v3 removed the construct* tableau functions (moved to OrdinaryDiffEqExplicitTableaus / OrdinaryDiffEqImplicitTableaus when it joined the OrdinaryDiffEq monorepo), and DiffEqDevTools v2's DiffEqBase cap conflicts with ModelingToolkitBase's DiffEqBase >= 7.2 requirement, making the whole Optimization test group unresolvable. Depend on the two tableau packages instead and use the new names (constructRK4() -> ExplicitTableaus.RK4(), etc.). Return types are unchanged (DiffEqBase.ExplicitRKTableau), so no source changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dynamic optimization problem structs collected kwargs as positional varargs, storing a Tuple in the kwargs field. Current SciMLBase remake asserts values(prob.kwargs)::NamedTuple and reconstructs the problem with T(f, u0, tspan, p, wrapped_model; kwargs...), and ConstructionBase setproperties (used by remake internals) reconstructs with all six fields positionally — both of which the varargs form breaks. This surfaces as a TypeError from solve() -> remake(prob, p = new_p) for any problem with tunable parameters, e.g. the parameter estimation tests. Give each problem struct an exact six-argument positional constructor (for setproperties) and a keyword-varargs constructor (for remake), and pass kwargs through process_DynamicOptProblem as keywords. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
unbound_inputsclassifies an input as bound if it appears in an equation together with variables from another namespace. That heuristic is only meaningful before flattening: aftermtkcompile, connection/output equations are eliminated, so any effective input co-occurs with variables from other components —unbound_inputsis empty for every compiled hierarchical system.Three codegen entry points still use it as their default input set and silently degrade on compiled hierarchical systems:
generate_control_functionwarns "No unbound inputs were found in system." and generates dynamics with the controls bound at their operating-point valuesBVProblemcomputesn_controls = 0, mis-shapingf_prototypecalculate_control_jacobianreturns an empty jacobian(We hit the first one through
JuMPDynamicOptProblemon a hierarchical vehicle model: the NLP ended up with control-free dynamics and Ipopt "converged" in a handful of iterations to a pseudo-optimal constant-input trajectory.)This PR adds
default_codegen_inputs(sys)—inputs(sys)for scheduled systems, where the declared inputs are the contractmtkcompilewas built around (stored in theinputsfield), falling back to theunbound_inputsheuristic for unscheduled hierarchies — and uses it at those three sites.ODEInputFunction, already fixed toinputs(sys)in #4406, is switched to the same helper for consistency.Includes a regression test with a minimal two-component system whose input is eliminated into a cross-namespace equation, covering the
ODEInputFunctiondefault andcalculate_control_jacobian.Also included: repairs to make the Optimization test group runnable again
The Optimization test group could not resolve or pass on current registry state, so two additional commits fix that (verified locally: the full
dynamic_optimization.jlfile passes, including the CasADi paths):construct*tableau functions (moved toOrdinaryDiffEqExplicitTableaus/OrdinaryDiffEqImplicitTableaus), and v2's DiffEqBase cap conflicts with MTKBase's DiffEqBase ≥ 7.2 requirement, making the test env unresolvable either way.DynamicOptProblemreconstruction underremake/setproperties. The problem structs collected kwargs as positional varargs (storing aTuple); current SciMLBaseremakeassertsvalues(prob.kwargs)::NamedTupleand reconstructs via keyword call, and ConstructionBasesetpropertiesreconstructs with all six fields positionally. This brokesolve→remake(prob, p = new_p)for problems with tunable parameters (the parameter estimation tests).🤖 Generated with Claude Code