Skip to content

Fix SOC index collision and simplify QC-to-SOC conversion by routing linear QCs through general LDLT path#1564

Open
yuwenchen95 wants to merge 3 commits into
NVIDIA:mainfrom
yuwenchen95:fix-qcqp-translation
Open

Fix SOC index collision and simplify QC-to-SOC conversion by routing linear QCs through general LDLT path#1564
yuwenchen95 wants to merge 3 commits into
NVIDIA:mainfrom
yuwenchen95:fix-qcqp-translation

Conversation

@yuwenchen95

Copy link
Copy Markdown
Contributor

Description

Simplify SOC conversion in translate_soc.hpp and fix a variable-index collision when mixing general convex QCs with affine-style QCs (e.g. hub1.mps.gz).

Bug fix: When a general LDLT QC was converted before an affine QC with a linear part, both paths could allocate overlapping auxiliary column indices. This produced SOC variable index ... collision at runtime.

Refactor — merge affine fast path into general LDLT path: QCs with a nonzero linear part (COLUMNS) no longer use a separate affine auxiliary-variable + linking-row fast path. They always route through the general LDLT lift, which handles the linear term directly in the s_0 / s_{r+1} rows. This removes:

  • qc_affine_heads / n_affine_linear_aux pre-allocation
  • post-loop affine linking rows
  • the rotated-SOC-with-implicit-head affine branch

Refactor — clearer path routing: Classification is inverted to match the header comment: a QC is eligible for standard or rotated SOC fast paths when it matches those patterns (rhs = 0, no linear part); otherwise it uses the general path.

Tests: Add mixed_general_and_affine_soc_conversion regression test that reproduces the pre-fix failure mode (general QC first, affine QC second).

Issue

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

Signed-off-by: yuwenchen95 <yuwchen@nvidia.com>
@yuwenchen95 yuwenchen95 requested review from chris-maes and rg20 July 13, 2026 17:37
@yuwenchen95 yuwenchen95 requested a review from a team as a code owner July 13, 2026 17:37
@yuwenchen95 yuwenchen95 added bug Something isn't working improvement Improves an existing functionality barrier non-breaking Introduces a non-breaking change and removed improvement Improves an existing functionality labels Jul 13, 2026
@coderabbitai

coderabbitai Bot commented Jul 13, 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: 43d66f08-36c6-40b7-be54-f5dadd8f5bf2

📥 Commits

Reviewing files that changed from the base of the PR and between 737b429 and 949ea32.

📒 Files selected for processing (1)
  • cpp/src/barrier/translate_soc.hpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/barrier/translate_soc.hpp

📝 Walkthrough

Walkthrough

The SOC conversion now routes quadratic constraints with linear parts through the general LDLT/PSD lift, refines standard and rotated fast-path checks, removes affine auxiliary-variable linking, and adds mixed-conversion barrier-solver coverage.

Changes

SOC conversion

Layer / File(s) Summary
Fast SOC eligibility and construction
cpp/src/barrier/translate_soc.hpp
Fast standard and rotated SOC eligibility is computed explicitly, with revised validation and construction for rhs=0 standard SOC patterns.
General lift and mixed conversion validation
cpp/src/barrier/translate_soc.hpp, cpp/tests/socp/general_quadratic_test.cu
Affine auxiliary-variable bookkeeping is removed, and a mixed general/affine conversion test validates cone layout, solution optimality, and quadratic constraint satisfaction.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: rg20

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the index-collision fix and the SOC conversion routing change.
Description check ✅ Passed The description is directly aligned with the changeset and clearly explains the bug fix, refactor, and test addition.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
cpp/src/barrier/translate_soc.hpp (1)

155-181: 🚀 Performance & Scalability | 🔵 Trivial

General-path routing for affine QCs trades performance for correctness.

Every QC with a nonzero linear part now goes through dense LDLT factorization plus rank+2 new variables/rows, instead of the previous lightweight single auxiliary variable + link row. This is the right fix for the index-collision bug, but for models with many simple affine QCs this is a meaningful cost increase (dense local Hessian assembly, LDLT factorization per QC). Worth keeping an eye on for large models with many affine-style QCs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/barrier/translate_soc.hpp` around lines 155 - 181, Review the
nonzero-linear-term routing around has_linear_part so simple affine quadratic
constraints can retain the lightweight single-auxiliary-variable and link-row
path when safe, while still using the general LDLT rank+2 path for cases
affected by index collisions. Preserve the existing validation and ensure the
collision-safe path remains correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/barrier/translate_soc.hpp`:
- Around line 320-346: The degenerate SOC conversion in the
pos_diag_rows.empty() branch must validate the head variable’s nonnegative lower
bound before constructing the one-element cone. Reuse the existing head-bound
validation from the multi-term SOC path, applying it before setting head or
accepting the q_nnz == 1 conversion, while preserving the current diagonal and
tail validations.
- Around line 274-279: Update the standard_soc_eligible condition to require
exactly one negative diagonal row by changing the neg_diag_rows size check from
allowing zero or one to requiring one. Leave rotated_soc_eligible and the
general-path selection unchanged so all-positive-diagonal cases use the LDLT
fallback.

---

Nitpick comments:
In `@cpp/src/barrier/translate_soc.hpp`:
- Around line 155-181: Review the nonzero-linear-term routing around
has_linear_part so simple affine quadratic constraints can retain the
lightweight single-auxiliary-variable and link-row path when safe, while still
using the general LDLT rank+2 path for cases affected by index collisions.
Preserve the existing validation and ensure the collision-safe path remains
correct.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b698de37-fe2d-4f66-8eb6-a8a989a5edc6

📥 Commits

Reviewing files that changed from the base of the PR and between 37a099e and 08d33ad.

📒 Files selected for processing (2)
  • cpp/src/barrier/translate_soc.hpp
  • cpp/tests/socp/general_quadratic_test.cu

Comment thread cpp/src/barrier/translate_soc.hpp
Comment thread cpp/src/barrier/translate_soc.hpp Outdated
Comment thread cpp/src/barrier/translate_soc.hpp Outdated
// 2) rotated SOC — one off-diagonal cross -2*d on two heads plus tail diagonals +s
// (d > 0, s > 0; stored as Q cross (head0, head1, -2*d); lift uses sqrt(d/s))
//
// General path (LDLT lift on H = Q + Q^T, must be PSD):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a LDLT lift?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the general path for quadratic constraints where we need to factorize the quadratic cost. We are using LDL factorization for factorization and positive semidefinite check.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote that code. But I'm not sure how the word "lift" relates to that code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we considered any introduction of new variables as a lift.

Comment thread cpp/src/barrier/translate_soc.hpp Outdated
Signed-off-by: yuwenchen95 <yuwchen@nvidia.com>
@github-actions

Copy link
Copy Markdown

CI Test Summary

✅ All 31 test job(s) passed.

Signed-off-by: yuwenchen95 <yuwchen@nvidia.com>
@rg20 rg20 added this to the 26.08 milestone Jul 14, 2026
@yuwenchen95 yuwenchen95 self-assigned this Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

barrier bug Something isn't working non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants