Skip to content

Remove wrong exception of unsupported QCQP#1493

Merged
rapids-bot[bot] merged 7 commits into
NVIDIA:mainfrom
rg20:qcqp_remove_exception
Jul 7, 2026
Merged

Remove wrong exception of unsupported QCQP#1493
rapids-bot[bot] merged 7 commits into
NVIDIA:mainfrom
rg20:qcqp_remove_exception

Conversation

@rg20

@rg20 rg20 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

We were wrongly throwing an exception when the rotated cones and quadratic objectives were present.

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

@rg20 rg20 requested a review from a team as a code owner June 30, 2026 18:14
@rg20 rg20 requested review from kaatish and yuwenchen95 June 30, 2026 18:14
@copy-pr-bot

copy-pr-bot Bot commented Jun 30, 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.

@rg20 rg20 removed the request for review from yuwenchen95 June 30, 2026 18:14
@rg20 rg20 added bug Something isn't working non-breaking Introduces a non-breaking change labels Jun 30, 2026
@rg20 rg20 added this to the 26.08 milestone Jun 30, 2026
@rg20 rg20 requested review from yuwenchen95 and removed request for kaatish June 30, 2026 18:16
@rg20

rg20 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test d789f4e

user_problem.var_types.assign(n, variable_type_t::CONTINUOUS);

// Rotated SOC: x^2 - 2*t*u <= 0
// Q COO: (0,0,1) for x^2, (1,2,-2) for -2*t*u (canonical form: single cross term)

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.

Try specifying the problem using the lp reader? I can't visually verify the correctness of the hardcoded matrix inputs.

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.

Updated

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

CI Test Summary

✅ All 31 test job(s) passed.

Comment thread cpp/tests/socp/general_quadratic_test.cu Outdated
@rg20

rg20 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test ae2fea1

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Removes a rotated-SOC conversion check for quadratic objectives, adds a regression test for solving a QCQP with a rotated SOC constraint, and updates cuSPARSE SpMV algorithm selection to depend only on the cuSPARSE version.

Changes

Rotated SOC with quadratic objective support

Layer / File(s) Summary
Remove quadratic objective restriction
cpp/src/barrier/translate_soc.hpp
Deletes the check requiring empty Q_values before rotated-SOC conversion, allowing the conversion path to continue when quadratic objective terms are present.
Test QCQP with rotated SOC and quadratic objective
cpp/tests/socp/general_quadratic_test.cu
Adds solver includes and an end-to-end QCQP test that uses solve_lp with pdlp_solver_settings_t, expects Optimal, and verifies the objective is near -0.5.

cuSPARSE SpMV algorithm selection

Layer / File(s) Summary
Version-based SpMV algorithm selection
cpp/src/barrier/cusparse_view.cu
Updates get_spmv_alg to ignore num_rows for selection, mark it unused, and choose CUSPARSE_SPMV_CSR_ALG1 when the computed cuSPARSE version is below 13.0.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • NVIDIA/cuopt#1439: Also changes rotated-SOC conversion logic in cpp/src/barrier/translate_soc.hpp.

Suggested reviewers: ramakrishnap-nv, mlubin, chris-maes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the bug fix for the incorrect QCQP exception.
Description check ✅ Passed The description matches the change by explaining the incorrect exception for rotated cones with quadratic objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

ASSERT_EQ(problem.get_quadratic_constraints().size(), 1u);

pdlp_solver_settings_t<i_t, f_t> settings;
auto solution = solve_lp(&handle, problem, settings);

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.

Mind leaving a TODO to redo all the other tests in this form?

@rg20

rg20 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test

@copy-pr-bot

copy-pr-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

/ok to test

@rg20, there was an error processing your request: E1

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/1/

@rg20

rg20 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test fb18712

@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: 1

🧹 Nitpick comments (1)
cpp/src/barrier/cusparse_view.cu (1)

117-117: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the now-unused num_rows parameter.

Since the selection logic no longer depends on num_rows, consider removing the parameter entirely rather than marking it [[maybe_unused]], and updating the call sites (lines 208, 220, 232, 244, 314, 366) accordingly.

♻️ Proposed cleanup
-static cusparseSpMVAlg_t get_spmv_alg([[maybe_unused]] int num_rows)
+static cusparseSpMVAlg_t get_spmv_alg()
 {

And update call sites, e.g. get_spmv_alg(A_offsets_.size() - 1)get_spmv_alg().

🤖 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/cusparse_view.cu` at line 117, The get_spmv_alg helper no
longer uses num_rows, so remove that parameter instead of keeping it marked
[[maybe_unused]]. Update the get_spmv_alg function signature in cusparse_view.cu
and fix every call site that still passes A_offsets_.size() - 1 (and any similar
argument) to call get_spmv_alg() with no arguments.
🤖 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/cusparse_view.cu`:
- Around line 117-126: The ALG selection in get_spmv_alg is using the build-time
CUSPARSE_VER_* macros, which can diverge from the actually loaded cuSPARSE
library. Update this helper to use the runtime/library version instead,
preferably by reusing or extending the existing cuSPARSE loader/cache path
already used elsewhere in cusparse_view.cu, so the ALG1/ALG2 choice reflects the
real libcusparse.so and avoids the beta=1 accumulate bug.

---

Nitpick comments:
In `@cpp/src/barrier/cusparse_view.cu`:
- Line 117: The get_spmv_alg helper no longer uses num_rows, so remove that
parameter instead of keeping it marked [[maybe_unused]]. Update the get_spmv_alg
function signature in cusparse_view.cu and fix every call site that still passes
A_offsets_.size() - 1 (and any similar argument) to call get_spmv_alg() with no
arguments.
🪄 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: afc97cbb-e18b-4730-90d6-cdd7399fa480

📥 Commits

Reviewing files that changed from the base of the PR and between ae2fea1 and fb18712.

📒 Files selected for processing (3)
  • cpp/src/barrier/cusparse_view.cu
  • cpp/src/barrier/translate_soc.hpp
  • cpp/tests/socp/general_quadratic_test.cu
🚧 Files skipped from review as they are similar to previous changes (2)
  • cpp/tests/socp/general_quadratic_test.cu
  • cpp/src/barrier/translate_soc.hpp

Comment on lines +117 to 126
static cusparseSpMVAlg_t get_spmv_alg([[maybe_unused]] int num_rows)
{
// The older version of ALG2 has a bug with single row matrices
if (num_rows == 1 &&
(CUSPARSE_VER_MAJOR * 1000 + CUSPARSE_VER_MINOR * 100 + CUSPARSE_VER_PATCH < 12603)) {
return CUSPARSE_SPMV_CSR_ALG1;
}
// ALG2 has a bug in cuSPARSE < 13.0 where beta=1 accumulate mode ignores existing y values.
// ALG1 uses a deterministic row-split algorithm, while ALG2 uses a merge-based
// algorithm that may be faster but can use atomics. ALG1 is safe for reproducibility.
constexpr int cusparse_version =
CUSPARSE_VER_MAJOR * 1000 + CUSPARSE_VER_MINOR * 100 + CUSPARSE_VER_PATCH;
if (cusparse_version < 13000) { return CUSPARSE_SPMV_CSR_ALG1; }
return CUSPARSE_SPMV_CSR_ALG2;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Can cusparseGetProperty runtime cuSPARSE version differ from CUSPARSE_VER_MAJOR/MINOR compile-time macros when linked dynamically?

💡 Result:

Yes, the version reported by the runtime function cusparseGetProperty can differ from the versions defined by the CUSPARSE_VER_MAJOR and CUSPARSE_VER_MINOR compile-time macros [1][2]. Compile-time macros such as CUSPARSE_VER_MAJOR, CUSPARSE_VER_MINOR, and CUSPARSE_VER_PATCH are defined in the cuSPARSE header files (e.g., cusparse.h) available at the time the application is compiled [3][4][5]. These reflect the version of the cuSPARSE SDK used during the build process [1][2]. In contrast, cusparseGetProperty is a runtime API that queries the version of the specific cuSPARSE library (libcusparse.so or.dll) that is dynamically loaded into the application's process at execution time [6][7]. When linking dynamically, the library found at runtime by the system's dynamic linker may be different from the one against which the application was originally compiled (e.g., due to differences in the environment's LD_LIBRARY_PATH or PATH) [8]. This discrepancy is a known challenge in complex deployment environments where the runtime environment may contain a different version of the NVIDIA CUDA Toolkit or individual libraries than the development environment [1][2]. Developers are generally advised to rely on the runtime API (cusparseGetProperty) for features dependent on the loaded library version to ensure compatibility with the actual environment [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant file and call sites.
git grep -n "get_spmv_alg" -- cpp/src/barrier/cusparse_view.cu
sed -n '1,170p' cpp/src/barrier/cusparse_view.cu
sed -n '170,390p' cpp/src/barrier/cusparse_view.cu

# Check whether the runtime-version handling comment is present nearby.
git grep -n "There can be a missmatch between compiled CUDA version and the runtime CUDA version" -- cpp/src/barrier/cusparse_view.cu

Repository: NVIDIA/cuopt

Length of output: 18107


Use the loaded cuSPARSE version for ALG selection CUSPARSE_VER_* is build-time only, but this file already accounts for runtime/library mismatches elsewhere. Query the runtime cuSPARSE version here too (or cache it in the existing loader helper) so ALG1/ALG2 selection matches the actual libcusparse.so and doesn’t reintroduce the beta=1 accumulate bug.

🤖 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/cusparse_view.cu` around lines 117 - 126, The ALG selection
in get_spmv_alg is using the build-time CUSPARSE_VER_* macros, which can diverge
from the actually loaded cuSPARSE library. Update this helper to use the
runtime/library version instead, preferably by reusing or extending the existing
cuSPARSE loader/cache path already used elsewhere in cusparse_view.cu, so the
ALG1/ALG2 choice reflects the real libcusparse.so and avoids the beta=1
accumulate bug.

@rg20

rg20 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test d68726e

@rg20

rg20 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot rapids-bot Bot merged commit afbb89c into NVIDIA:main Jul 7, 2026
178 of 180 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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