Skip to content

Read epsilon-constraint duals as frontier slope / exchange rate in multi-objective skill#1406

Open
cafzal wants to merge 9 commits into
NVIDIA:mainfrom
cafzal:claude/elastic-goodall-3693ff
Open

Read epsilon-constraint duals as frontier slope / exchange rate in multi-objective skill#1406
cafzal wants to merge 9 commits into
NVIDIA:mainfrom
cafzal:claude/elastic-goodall-3693ff

Conversation

@cafzal

@cafzal cafzal commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Description

Adds dual-value guidance to the cuopt-multi-objective-exploration skill: the dual on a swept ε-constraint is the local slope of the Pareto frontier — the exchange rate between the objectives, read off each LP/QP solve — so the agent can report the tradeoff rate, and spot where to refine the sweep, without extra solves. Scoped to LP/QP off linear ε-constraints (MILP and quadratic-constraint problems return no duals). Adds a QP risk-return eval and clarifies the existing MILP eval to estimate the rate by differencing.

Follows #1393 (per-type dual/sensitivity); companions #1407 (formulation) and #1408 (API skills). Verified in source and empirically on a 26.08 nightly (linear-constrained QP returns the expected dual; a quadratic constraint NaN-fills all duals). validate_skills.sh passes; BENCHMARK.md / skill card / signature regenerate via NVSkills-Eval.

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

…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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

cafzal and others added 5 commits June 8, 2026 15:29
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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
…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) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
Condense the dual-as-slope note to four non-overlapping points — what it is
(slope/exchange rate/tangent, read off the solve free), the zero-dual=slack
diagnostic, scope+fallback (LP/QP, linear ε-constraint only; MILP and quadratic
constraints have none, so difference instead), and the formulation cross-ref.
Same facts, ~20% shorter; drops "exact" (kept in Step 5 as "to solve tolerance").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
@cafzal cafzal marked this pull request as ready for review June 9, 2026 17:00
@cafzal cafzal requested a review from a team as a code owner June 9, 2026 17:00
@cafzal cafzal requested a review from rgsl888prabhu June 9, 2026 17:00
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a704c925-d6b0-4509-a142-6c1871d93306

📥 Commits

Reviewing files that changed from the base of the PR and between d08d295 and 65d958e.

📒 Files selected for processing (1)
  • skills/cuopt-multi-objective-exploration/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • skills/cuopt-multi-objective-exploration/SKILL.md

📝 Walkthrough

Walkthrough

This pull request updates the multi-objective exploration skill documentation and evaluation cases to clarify when dual values from epsilon-constraint methods can interpret Pareto frontier exchange rates (LP/QP only) versus when differencing is required (MILP). It revises frontier refinement allocation to focus solves near dual-change knees for LP/QP and to use primal gaps for MILP, and strengthens reporting guidance with optimality caveats.

Changes

Multi-objective frontier dual interpretation and evaluation alignment

Layer / File(s) Summary
Dual interpretation and frontier refinement guidance
skills/cuopt-multi-objective-exploration/SKILL.md
SKILL.md now explicitly explains that ε-constraint dual values represent the frontier's local slope for LP/QP with a linear swept constraint, clarifies that zero duals indicate slack/binding status and that MILP/quadratic constraints preclude dual-based readings, and updates refinement strategy to concentrate solves around knees via dual-change magnitude (LP/QP) or primal objective gaps (MILP). It also strengthens frontier reporting: tie dual-derived exchange rates to solver optimality tolerance, report two-sided slopes/ranges at knees, treat dominated/gappy output as diagnostics, and state the weighting/ε used.
Evaluation case expectations for dual vs. differencing
skills/cuopt-multi-objective-exploration/evals/evals.json
Updates eval-002 (supplier selection, MILP) to require estimating cost/resilience exchange rates by differencing adjacent Pareto-frontier points since duals are unavailable. Updates eval-004 (dual exchange-rate) to state the exchange rate is read from the dual of the binding swept linear return-floor constraint, and restricts this to continuous LP/QP with a linear swept constraint.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/cuopt#1355: The main PR refines the existing cuopt-multi-objective-exploration documentation and evaluation expectations in skills/cuopt-multi-objective-exploration/SKILL.md and skills/cuopt-multi-objective-exploration/evals/evals.json, which directly builds on the same skill scaffolding added by retrieved PR #1355.
  • NVIDIA/cuopt#1393: Both PRs update SKILL/evaluation documentation around when duals (shadow prices) are available for LP/QP and unavailable for MILP, with the main PR applying that distinction to ε-constraint frontier “exchange rate” interpretation.

Suggested labels

non-breaking, improvement

Suggested reviewers

  • rgsl888prabhu
  • mlubin
  • tmckayus
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately describes the main change: adding guidance on reading epsilon-constraint duals as the frontier slope/exchange rate in the multi-objective exploration skill.
Description check ✅ Passed The description is clearly related to the changeset, providing detailed context about dual-value guidance, scope (LP/QP vs MILP), evaluation updates, and testing/documentation status.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

cafzal and others added 2 commits June 9, 2026 14:35
…barrier solver"

- Step 5 cross-ref: "defines shadow price ..." -> "covers what duals mean and
  which problem types expose them".
- Step 3 quadratic-constraint note: drop "the barrier solver" (the solve method
  isn't part of the dual contract); keep the second-order-cone constraint form.

Consistent with the trim applied to the api-* skills in NVIDIA#1408.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
…ights wording

- Step 3: drop "(Q positive semidefinite, inequality only)" — the sentence
  already says convex, shows the <= form, and the next sentence covers the
  non-convex/equality exclusion. Same over-specification flagged on the
  companion formulation PR.
- Step 4: a dual jump between two solved points locates a bend between them,
  not necessarily the knee (Step 5 defines the knee as the sharpest bend).
- Step 5: weighted-sum with the epsilon-duals as weights reproduces that
  tradeoff, not necessarily the identical point (flat segments tie).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: cafzal <cameron.afzal@gmail.com>
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