Skip to content

refactor: immutable BuiltModel bundle replacing the mutable DOCP cache#157

Merged
ocots merged 2 commits into
mainfrom
refactor/builtmodel-immutable-cache
Jun 27, 2026
Merged

refactor: immutable BuiltModel bundle replacing the mutable DOCP cache#157
ocots merged 2 commits into
mainfrom
refactor/builtmodel-immutable-cache

Conversation

@ocots

@ocots ocots commented Jun 27, 2026

Copy link
Copy Markdown
Member

Summary

Replaces the mutable backend cache in the DOCP flow with an immutable BuiltModel.

build_model previously returned a bare NLP and (for the Exa backend) mutated
exa_getter into the shared DiscretizedModel.cache so that build_solution
could reuse it. The getter is a co-product of building the model and cannot be
cheaply recomputed. This PR makes build_model return an immutable bundle that
carries both the NLP and any build-time auxiliary, so nothing is mutated.

Changes

  • Optimization: new BuiltModel{problem, nlp, cache} + NoCache. build_model
    returns a BuiltModel; build_solution(built, sol, modeler) dispatches on it.
    The orchestrator threads built.nlp into the solver; the mid-level
    solve(nlp, solver) stub stays untyped (NLPModels weak dep).
  • DOCP: nlp_model returns the bare NLP (build_model(...).nlp);
    ocp_solution realigned onto BuiltModel.
  • Solvers: extract_solver_infos moved here from Optimization (solver-side utility).
  • Deps: KernelAbstractions promoted to a hard dep so the CTSolversExaModels
    extension triggers on ExaModels alone (downstream packages such as CTDirect
    needn't using KernelAbstractions); Aqua stale_deps ignores it since the main
    module does not reference it directly.
  • Tests: each modeler-using test file now imports ADNLPModels/ExaModels so the
    extensions trigger under per-file isolation; fixtures wrapped in BuiltModel.

Why it matters

  • Fully immutable cache; the Exa getter is never recomputed (zero overhead).
  • Removes a latent bug: two build_model calls on the same DiscretizedModel
    could clobber each other's getter; a stale getter could survive an ADNLP build.

Companion

CTDirect adopts the same bundle (DOCPCache becomes immutable, getter rides an
ExaBuildCache) on its refactor/docp-dispatch branch (PR #601).

Tests

Full CTSolvers suite green (non-extension suites + extensions, ~3100 tests),
including Aqua.

🤖 Generated with Claude Code

build_model now returns an immutable BuiltModel{problem, nlp, cache} consumed by
build_solution, eliminating the mutable backend cache (the Exa getter used to be
mutated into the shared DiscretizedModel). This also removes a latent bug where
two builds on the same DiscretizedModel could clobber each other's getter.

- Optimization: add BuiltModel + NoCache; build_solution dispatches on the bundle;
  the orchestrator threads built.nlp into the solver. The solve(nlp, solver) stub
  stays untyped (NLPModels weak dep).
- DOCP: nlp_model returns the bare NLP; ocp_solution realigned onto BuiltModel.
- Move extract_solver_infos from Optimization to Solvers (solver-side utility).
- KernelAbstractions promoted to a hard dep so the ExaModels extension triggers on
  ExaModels alone (CTDirect needn't load KernelAbstractions); Aqua stale_deps
  ignores it since the main module does not reference it.
- Tests: import ADNLPModels/ExaModels in each modeler-using test file so the
  extensions trigger under per-file isolation; wrap fixtures in BuiltModel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Documents the immutable BuiltModel refactor, the extract_solver_infos move to
Solvers, and the KernelAbstractions return to a hard dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ocots
ocots merged commit cce811d into main Jun 27, 2026
5 checks passed
@ocots
ocots deleted the refactor/builtmodel-immutable-cache branch June 27, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant