Read epsilon-constraint duals as frontier slope / exchange rate in multi-objective skill#1406
Draft
cafzal wants to merge 6 commits into
Draft
Read epsilon-constraint duals as frontier slope / exchange rate in multi-objective skill#1406cafzal wants to merge 6 commits into
cafzal wants to merge 6 commits into
Conversation
…lti-objective skill Extends the dual/sensitivity work from NVIDIA#1393 into the multi-objective layer: the dual on a swept epsilon-constraint is the local slope of the Pareto frontier (the exchange rate between the two objectives), available off each LP/QP solve at no extra cost. - Step 3: note that the swept constraint's dual is the frontier's local tangent; defers "what duals are / which problem types expose them" to the formulation skill (no API symbols inlined). - Step 4: a practical-notes bullet to refine the sweep where the slope changes, spending fewer solves than a uniform grid (LP/QP; MILP falls back to gaps between primal objective values). - Step 5: the exchange rate is read from the dual on LP/QP (differencing on MILP), and the epsilon-constraint duals are the implicit weights per point. - evals: add a QP risk-return frontier task exercising dual-as-exchange-rate; clarify the MILP supplier eval to estimate the rate by differencing. Concepts/workflow skill: LP/QP-only scoping preserved, no maturity labels. BENCHMARK.md, the skill card, and the signature are regenerated by NVSkills CI. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
Addresses duality-review feedback (a PDLP co-author's lens). cuOpt's default LP method is Concurrent — it races PDLP (first-order), dual simplex, and barrier — so a returned dual is exact-basic only when dual simplex solved it and accurate only to the optimality tolerance otherwise. Three concepts-level, stale-robust edits (no method names in the skill text): - Step 5: drop "exact and local"; the exchange rate is the dual "accurate to the solve's optimality tolerance (tighten it before relying on a dual)." - Step 4: treat a slope change as a knee only when it exceeds the solve tolerance — smaller differences are solver noise, not curvature. - Step 5: at a knee the slope is two-sided; quote the exchange rate as a range. Consistent with the "PDLP-tolerance caveat" already noted in NVIDIA#1355. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
Verified against the cuOpt repo + docs. Two corrections: - cuOpt returns no dual variables for problems with quadratic constraints (docs/cuopt/source/cuopt-c/convex/convex-examples.rst). The skill offers a quadratic ε-constraint (xᵀQx ≤ ε) option, which would have no dual to read. Step 3 now says: read the dual off a *linear* ε-constraint — keep a quadratic objective as f1 and ε-constrain the linear objectives. - Switch the new eval from a QP risk-return frontier to an LP cost-vs-quality blend. LP duals are the tested, documented path (lp_duals asset); QP-dual reading is untested and the api-* skills scope duals to "LP only", so the eval should exercise the verified path. Skill prose stays "LP/QP" per the formulation skill. Separate (not in this PR): the formulation skill's "no quadratic constraints" is stale (cuOpt supports convex quadratic constraints via barrier/SOC), and the api-python/api-c "dual values (LP only)" likely needs "LP/QP, linear constraints" — flagged for follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
Reverts the over-conservative QP->LP eval switch. Git history confirms QP duals are real and recent: barrier extended for SOCP (NVIDIA#1290, 2026-05-30) and general convex quadratic constraints (NVIDIA#1361, 2026-06-02); the barrier solver is primal-dual and pdlp/solve.cu returns dual_solution + reduced_cost for the Barrier method. The api-python/api-c "dual values (LP only)" wording predates this (NVIDIA#1183, 2026-05-07) and is the stale part, not the formulation skill's "LP/QP" (NVIDIA#1393). The QP risk-return eval sweeps a *linear* return floor, whose dual is returned (cuOpt returns no dual for a quadratic constraint, so the quadratic stays the objective). Skill prose unchanged (already "LP/QP" + linear-constraint caveat). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
A zero shadow price means the constraint is slack (not binding), so during a sweep a zero dual on an ε-bound signals the objectives aren't trading off there — the sweep has run past the frontier's edge. Small precision/diagnostic addition; consistent with the dual-as-slope content already in Step 3. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
…vior cpp/src/pdlp/solve.cu (has_quadratic_constraints -> thrust::fill the entire dual_solution + reduced_cost with quiet_NaN) shows a single quadratic constraint suppresses duals for the *whole* solve, not just that constraint's row. Reword "no dual for a quadratic constraint" -> "any quadratic constraint makes cuOpt return no duals for the whole solve" in Step 3 and the QP eval, for consistency with PRs NVIDIA#1407 (formulation) and NVIDIA#1408 (api skills, "NaN-filled"). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: cafzal <[email protected]>
This was referenced Jun 8, 2026
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.
Description
Extends the per-type dual/sensitivity note from #1393 into the
cuopt-multi-objective-explorationskill. #1393 established what duals are per problem type (shadow price, reduced cost; none for MILP); this adds the frontier-specific fact that follows: the dual on a swept ε-constraint is the local slope of the Pareto frontier — the exchange rate between the two objectives at that point, available off each LP/QP solve, and a signal for where to spend solves on the sweep.Why. Step 5 of the skill already asks the agent to report the tradeoff exchange rate; on LP/QP that number is the swept constraint's dual (the local slope), where differencing two solved points only gives a secant across any kink between them. The same dual also shows where the curve bends, so the sweep can refine there instead of over a uniform grid. This is the downstream decision-layer consumer #1393 was written for.
Scope. LP/QP only — MILP optima have no duals (stated in every new note; cross-refs defer to the formulation skill rather than restating it). The dual must be read off a linear ε-constraint: cuOpt returns no dual for a quadratic constraint, so a quadratic objective stays the objective and the linear objectives are ε-constrained. Kept to interpretation plus a sweep-budget principle; no predict-and-extrapolate procedure, since a one-sided dual at a degenerate vertex can mislead past a breakpoint, and at a knee the slope is two-sided.
Dual accuracy (deliberate wording). The skill says the exchange rate is the dual "accurate to the solve's optimality tolerance," not "exact." cuOpt's default LP method is Concurrent — it races PDLP (first-order), dual simplex, and barrier — so a returned dual is exact-basic only when dual simplex solved it and tolerance-bounded otherwise (
solved_byreports which). Adaptive refinement therefore treats slope changes below the tolerance as solver noise. This matches the "PDLP-tolerance caveat" already noted in #1355.Tests. Adds a QP risk-return eval exercising the dual-as-exchange-rate reading, and clarifies the existing MILP eval to estimate the rate by differencing. QP duals are returned by cuOpt's barrier solver (extended for SOCP and general convex quadratic constraints in 26.06, #1290 / #1361); the eval sweeps a linear return floor, whose dual is returned — cuOpt returns no dual for a quadratic constraint.
Validation & gating.
ci/utils/validate_skills.shpasses;evals.jsonis valid (4 tasks); the skill has no executable assets.BENCHMARK.md, the skill card, andskill.oms.sigare regenerated by the NVSkills-Eval pipeline, which is the gate and needs a maintainer/nvskills-ci(fork branches can't self-validate).Related. Builds on #1393. Exposing the basis/variable-status and RHS/objective ranging that would pin the frontier's breakpoints exactly is tracked in #1394 / #1395.
Checklist
Companion PRs — coordinated follow-ons to #1393, catching the numerical-optimization skills up to cuOpt's 26.06 QP / quadratic-constraint additions:
Shared verified boundary across all three: a QP with linear constraints returns duals (the barrier solver is primal-dual); any quadratic constraint suppresses duals for the whole solve (
cpp/src/pdlp/solve.cuNaN-fills the dual/reduced-cost arrays). MILP has no duals.