Skip to content

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

Open
cafzal wants to merge 11 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 11 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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: 59dfa618-32c1-49cc-ba29-68b860110995

📥 Commits

Reviewing files that changed from the base of the PR and between ea69feb and 740a280.

📒 Files selected for processing (1)
  • skills/cuopt-multi-objective-exploration/SKILL.md
✅ Files skipped from review due to trivial changes (1)
  • skills/cuopt-multi-objective-exploration/SKILL.md

📝 Walkthrough

Walkthrough

Updates SKILL.md and evals.json to clarify ε-constraint construction and interpretation: dual-derived local exchange rates apply only to LP/QP with a linear swept constraint; MILP requires adjacent-point differencing; refinement and reporting guidance are adjusted (dual-jump knee detection, MILP primal-gap handling, explicit ε/weight reporting).

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
Distinguishes ε-constraint handling for linear vs quadratic objectives (keep quadratic as f1 when appropriate; convex quadratics can be ε-constrained), states that ε-constraint duals represent local slopes only for LP/QP with a linear swept constraint (zero dual = slack), and revises refinement/reporting: concentrate solves where slope/dual jumps (LP/QP) or primal gaps (MILP), report exchange rates within solver tolerance or via MILP gaps, and report knees as two-sided slope ranges.
Evaluation case expectations for dual vs. differencing
skills/cuopt-multi-objective-exploration/evals/evals.json
Updates eval-002 (supplier exploration, MILP) to require estimating cost/resilience exchange rates by differencing adjacent Pareto-frontier points. Updates eval-004 (dual exchange-rate) to require reading the local exchange rate from the dual of the binding swept linear return-floor constraint and restrict that method to continuous LP/QP with a linear swept constraint.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/cuopt#1408: Related documentation updates restricting dual-based interpretations to binding linear constraints and excluding MILP/quad-constrained cases.

Suggested labels

non-breaking, improvement

Suggested reviewers

  • tmckayus
  • rgsl888prabhu
  • mlubin
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Read epsilon-constraint duals as frontier slope / exchange rate in multi-objective skill' directly describes the main change: exposing constraint duals as Pareto frontier slopes/exchange rates for multi-objective optimization.
Description check ✅ Passed The description clearly relates to the changeset by explaining that dual values on swept ε-constraints represent the local slope of the Pareto frontier and exchange rates between objectives, with scope to LP/QP off linear constraints.
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>
@rgsl888prabhu rgsl888prabhu requested a review from mlubin June 11, 2026 14:56
Comment thread skills/cuopt-multi-objective-exploration/SKILL.md Outdated
Comment thread skills/cuopt-multi-objective-exploration/SKILL.md Outdated
cafzal and others added 2 commits June 11, 2026 09:59
…al note

- Line 95: apply reviewer suggestion — "which cuOpt supports" (drop the
  second-order-cone mechanism; not part of the contract).
- Step 3 paragraph cut to a third and the claim qualified: the dual is the
  frontier's slope only where the frontier is smooth; at a kink it gives a
  one-sided rate. Drops content carried elsewhere (the keep-quadratic-as-f1
  advice in the paragraph above; the formulation cross-ref at lines 43/47).
  Keeps what is unique: smoothness caveat, zero-dual = slack diagnostic,
  LP/QP + linear-constraint scope with the differencing fallback.

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

- Step 3: the smooth/kink/zero-dual sentence carried three ideas; split after
  the kink clause.
- Step 4: "MILP has no duals" is established in Step 3 — the bullet keeps just
  the action ("On MILP, judge where to refine from the gaps...").

Co-Authored-By: Claude Fable 5 <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.

2 participants