Skip to content

[BUG] Rotated SOC with single (asymmetric) cross term returns nan instead of raising the logged ValidationError #1354

@rgsl888prabhu

Description

@rgsl888prabhu

Describe the bug

A rotated second-order cone constraint written the intuitive way — with a single
cross term - x3*x4 — is rejected internally by the SOC conversion (a
ValidationError is logged), but the error is not propagated to the caller.
solve() returns Status = NoTermination with ObjValue = nan instead of either
solving the cone or raising the validation error.

The SOC converter (cpp/src/barrier/translate_soc.hpp) requires the rotated-cone
cross term to be supplied as a symmetric off-diagonal pair (-d, -d). A single
off-diagonal entry trips:

Quadratic constraint 'Q0' rotated SOC Q must contain exactly one symmetric
off-diagonal pair (-d,-d); found 1 off-diagonal entries

The quadratic-objective path symmetrizes Q, so users reasonably expect the
quadratic-constraint path to behave the same. At minimum, the validation error
should surface as a Python exception / non-OK termination status rather than a
silent nan.

Steps/Code to reproduce bug

import numpy as np
from cuopt.linear_programming.problem import Problem, MINIMIZE

def solve(symmetric):
    p = Problem()
    x1 = p.addVariable(lb=-np.inf, name="x1")
    x2 = p.addVariable(lb=-np.inf, name="x2")
    x3 = p.addVariable(lb=0, name="x3")
    x4 = p.addVariable(lb=0, name="x4")
    if symmetric:
        # works: symmetric Q (Q[x3,x4] = Q[x4,x3] = -0.5)
        p.addConstraint(x1*x1 + x2*x2 - 0.5*x3*x4 - 0.5*x4*x3 <= 0)
    else:
        # fails: single off-diagonal entry Q[x3,x4] = -1
        p.addConstraint(x1*x1 + x2*x2 - x3*x4 <= 0)
    p.addConstraint(x1 + x2 >= 2)
    p.setObjective(x3 + x4, sense=MINIMIZE)
    p.solve()
    return p.Status, p.ObjValue

print("intuitive (- x3*x4):   ", solve(False))   # -> (0, nan)  (error only logged)
print("symmetric (-0.5 each): ", solve(True))    # -> (1, 2.8284271257194744)

Output:

Error in solve_qcqp: {"CUOPT_ERROR_TYPE": "ValidationError", "msg": "Quadratic constraint 'Q0' rotated SOC Q must contain exactly one symmetric off-diagonal pair (-d,-d); found 1 off-diagonal entries"}
intuitive (- x3*x4):    (0, nan)
symmetric (-0.5 each):  (1, 2.8284271257194744)

(The same applies to MPS input: a QCMATRIX rotated cone must list both X3 X4
and X4 X3 entries.)

Expected behavior

One of:

  1. The quadratic-constraint Q is symmetrized (like the objective path), so the
    intuitive - x3*x4 form is accepted; or
  2. The ValidationError is raised to the caller (Python exception or a clear
    non-OK termination status), instead of a silent Status=NoTermination / nan.

Environment details:

  • Environment location: Bare-metal
  • Method of cuOpt install: from source (release/26.06, cuOpt 26.06.00)

Additional context

Found while documenting SOCP for the 26.06 docs. The user-facing docs now show the
symmetric form as a workaround; this issue tracks improving the ergonomics /
error propagation.

Metadata

Metadata

Assignees

Labels

awaiting responseThis expects a response from maintainer or contributor depending on who requested in last comment.bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions