Expand description
The solve → DiffHandoff contract — the solver-agnostic bundle that
every differentiable solve hands to its backward pass.
Design: dev-notes/diff-handoff-contract.md. The motivation is that
POUNCE differentiates solves across several frontends (JAX / PyTorch,
NLP / QP) and each was re-deriving the same active-set facts —
“a bound is active when its multiplier exceeds a tolerance”, “an
equality row is always active”, “active-bound / fixed (e.g. integer)
variables are pinned, dx/dp = 0”. This struct computes those facts
once, in the producer, so every consumer reads them instead of
recomputing |mult| > tol under its own tolerance.
This module is intentionally small and dependency-light: it is plain
data plus the one active-set derivation. It does not own the KKT
factor’s linear algebra — that stays in crate::solver /
crate::PdSensBacksolver; a DiffHandoff produced from a live
solve carries the converged solution and duals, and the factor is
reached through the owning crate::Solver / [ConvergedState].
It introduces no branch-and-bound and references no downstream consumer: the test for belonging here is “would any differentiable layer want it?” — and every one does.
Structs§
- Diff
Handoff - Everything the implicit-function-theorem backward pass needs from a converged solve, in a solver-agnostic shape.
Constants§
- DEFAULT_
ACTIVE_ TOL - Default activity tolerance: a constraint or bound multiplier with
magnitude above this is treated as active. Matches the
_ACTIVE_TOLlong used by the Python JAX/torch backward passes (python/pounce/jax/_diff.py), centralized here so there is one documented knob rather than one per frontend.