-
Notifications
You must be signed in to change notification settings - Fork 115
Add QP matrix to problem modeling #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughAdds MQuadraticExpression (matrix-form quadratic), updates Problem to accept/store quadratic objectives as sparse COO/CSR, adds ObjValue property and adjusts Obj behavior/state handling, updates tests to export MQuadraticExpression and compare CSR components, and adds scipy to conda/runtime dependencies. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
/ok to test 2e8717a |
|
/ok to test 95560f5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
python/cuopt/cuopt/linear_programming/problem.py (3)
1852-1867:Objnow returnsMQuadraticExpression— potential compatibility break.
MQuadraticExpressionlacksQuadraticExpressionaccessors (e.g.,getVariables,getCoefficients,getLinearExpression). Existing clients callingproblem.ObjorgetObjective()for quadratic objectives may fail. Consider returningQuadraticExpressionwhen appropriate, or add a compatibility shim/deprecation path. As per coding guidelines, ...
329-337: UseNoneinstead of mutable default arguments inQuadraticExpression.__init__.Mutable defaults (
vars=[],coefficients=[]) are a Python anti-pattern. Although the current codebase explicitly passes arguments, these defaults could cause unintended state sharing if future code relies on them. Thevarsandcoefficientslists are mutated via.extend()methods, making this a genuine concern.Suggested fix
def __init__( - self, qvars1, qvars2, qcoefficients, vars=[], coefficients=[], constant=0.0 + self, qvars1, qvars2, qcoefficients, vars=None, coefficients=None, constant=0.0 ): + if vars is None: + vars = [] + if coefficients is None: + coefficients = [] self.qvars1 = qvars1 self.qvars2 = qvars2 self.qcoefficients = qcoefficients self.vars = vars self.coefficients = coefficients self.constant = constant
1648-1700: Clear cached quadratic matrices when objective changes to prevent stale data.When an objective is changed from quadratic to linear (or another type), the cached
objective_qcsr_matrixremains and is returned bygetQuadraticObjective(), causing incorrect solver behavior. The matrices must be cleared at the start ofsetObjective()before any case matching. Additionally, fix E128 indentation on thecoo_matrixcall and add explicit shape toMQuadraticExpressionfor consistency withQuadraticExpression.🛠️ Suggested fix
def setObjective(self, expr, sense=MINIMIZE): ... if self.solved: self.reset_solved_values() # Reset all solved values self.ObjSense = sense + # Clear cached quadratic data whenever the objective is reset + self.objective_qcoo_matrix = None + self.objective_qcsr_matrix = None match expr: ... case QuadraticExpression(): ... self.ObjConstant = expr.constant qrows = [var.getIndex() for var in expr.qvars1] qcols = [var.getIndex() for var in expr.qvars2] self.objective_qcoo_matrix = coo_matrix( (np.array(expr.qcoefficients), - (np.array(qrows), np.array(qcols))), - shape=(self.NumVariables, self.NumVariables) + (np.array(qrows), np.array(qcols))), + shape=(self.NumVariables, self.NumVariables), ) case MQuadraticExpression(): ... self.ObjConstant = expr.constant - self.objective_qcoo_matrix = coo_matrix( - expr.qmatrix) + self.objective_qcoo_matrix = coo_matrix( + expr.qmatrix, + shape=(self.NumVariables, self.NumVariables), + )
🤖 Fix all issues with AI agents
In `@conda/recipes/cuopt/recipe.yaml`:
- Line 85: Update the conda recipe dependency for scipy to include a minimum
version constraint (e.g., change the plain "scipy" entry in recipe.yaml to
"scipy >=1.10") to ensure compatibility with code using scipy.sparse.coo_matrix
and scipy.spatial.distance; make the version range consistent with other
scientific deps (for example "scipy >=1.10,<2.0" if you want an upper bound) and
update any CI/test environment metadata to match.
In `@python/cuopt/cuopt/linear_programming/problem.py`:
- Around line 861-872: The inline TODO and commented-out method lines violate
flake8 E265 (missing space after '#'); update the comment lines in this block so
every comment token has a single space after the '#' (e.g., change "## TODO: Add
matrix multiplication" to "# TODO: Add matrix multiplication" and "#def
__matmul__..." to "# def __matmul__(self, qcols):", likewise "#def
__rmatmul__..." to "# def __rmatmul__(self, qcols):") while keeping the same
text and references to the methods __matmul__, __rmatmul__ and attributes
qcols/qrows.
- Around line 746-859: The match statements in __iadd__, __add__, __isub__, and
__sub__ on MQuadraticExpression lack default branches, so unsupported operand
types cause implicit None returns; add a final "case _:" branch in each method
that handles unsupported types by raising a TypeError (or returning
NotImplemented in the non-inplace methods if you prefer Pythonic binary-operator
behavior) with a clear message including the method name and the operand's
actual type (e.g., refer to __iadd__/__isub__/__add__/__sub__,
MQuadraticExpression, Variable, LinearExpression in the message) so the operator
protocol is not violated and errors are explicit.
- Around line 716-741: The constructor of MQuadraticExpression uses mutable
defaults and the qmatrix may be a list-of-lists, causing shared-state bugs and
TypeError in getValue; update __init__ signature to use None for qvars, vars,
and coefficients and inside __init__ set them to [] if None, and also normalize
qmatrix with np.asarray(qmatrix, dtype=float) (store back to self.qmatrix) so
getValue can safely use self.qmatrix[i, j]; ensure constant and other attributes
remain set as before and no other code paths rely on the old default objects.
🧹 Nitpick comments (1)
python/cuopt/cuopt/tests/linear_programming/test_python_API.py (1)
819-848: Consider adding an edge‑case quadratic‑matrix scenario.This test covers a feasible case; please add at least one degenerate/singleton or infeasible/unbounded case (or a variable‑ordering check) to exercise quadratic‑matrix handling under edge conditions. As per coding guidelines, ...
| - pylibraft =${{ minor_version }} | ||
| - python | ||
| - rmm =${{ minor_version }} | ||
| - scipy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for scipy imports in the Python cuopt package
rg -n "import scipy|from scipy" --type pyRepository: NVIDIA/cuopt
Length of output: 257
Addition of scipy dependency is justified.
The scipy dependency is actively used in the Python codebase for sparse matrix operations (scipy.sparse.coo_matrix in python/cuopt/cuopt/linear_programming/problem.py) and spatial distance calculations (scipy.spatial.distance in benchmark utilities). This confirms the addition is appropriate for QP matrix support.
Consider adding a minimum version constraint (e.g., scipy >=1.10) for consistency with other scientific Python dependencies (numpy >=1.23,<3.0, pandas >=2.0) and to ensure compatibility across the dependency stack.
🤖 Prompt for AI Agents
In `@conda/recipes/cuopt/recipe.yaml` at line 85, Update the conda recipe
dependency for scipy to include a minimum version constraint (e.g., change the
plain "scipy" entry in recipe.yaml to "scipy >=1.10") to ensure compatibility
with code using scipy.sparse.coo_matrix and scipy.spatial.distance; make the
version range consistent with other scientific deps (for example "scipy
>=1.10,<2.0" if you want an upper bound) and update any CI/test environment
metadata to match.
| def __init__( | ||
| self, qmatrix, qvars=[], vars=[], coefficients=[], constant=0.0 | ||
| ): | ||
| self.qmatrix = qmatrix | ||
| self.qvars = qvars | ||
| self.vars = vars | ||
| self.coefficients = coefficients | ||
| self.constant = constant | ||
|
|
||
|
|
||
| def shape(self): | ||
| return np.shape(self.qmatrix) | ||
|
|
||
| def getValue(self): | ||
| """ | ||
| Returns the value of the expression computed with the | ||
| current solution. | ||
| """ | ||
| # TODO: improve efficiency | ||
| value = 0.0 | ||
| for i, var in enumerate(self.vars): | ||
| value += var.Value * self.coefficients[i] | ||
| for i, var1 in enumerate(self.qvars): | ||
| for j, var2 in enumerate(self.qvars): | ||
| value += var1.Value * var2.Value * float(self.qmatrix[i,j]) | ||
| return value + self.constant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's verify the file exists and check the content around lines 716-741
wc -l python/cuopt/cuopt/linear_programming/problem.pyRepository: NVIDIA/cuopt
Length of output: 109
🏁 Script executed:
# Read the specific section mentioned in the review
sed -n '710,750p' python/cuopt/cuopt/linear_programming/problem.pyRepository: NVIDIA/cuopt
Length of output: 1242
🏁 Script executed:
# Let's also check the imports to understand what's available
head -30 python/cuopt/cuopt/linear_programming/problem.pyRepository: NVIDIA/cuopt
Length of output: 800
🏁 Script executed:
# Let's search for the MQuadraticExpression class definition
rg "class MQuadraticExpression" -A 50 python/cuopt/cuopt/linear_programming/problem.pyRepository: NVIDIA/cuopt
Length of output: 1521
🏁 Script executed:
# Verify numpy indexing behavior for list-of-lists
python3 << 'EOF'
import numpy as np
# Test with list-of-lists (as documented)
list_qmatrix = [[1.0, 2.0], [0.0, 0.0]]
# Try indexing directly - this should fail
try:
result = list_qmatrix[0, 1]
print(f"Direct list indexing [0,1]: {result}")
except TypeError as e:
print(f"Direct list indexing [0,1] FAILS: {e}")
# Try with np.asarray
np_qmatrix = np.asarray(list_qmatrix)
try:
result = np_qmatrix[0, 1]
print(f"np.asarray then [0,1]: {result}")
except Exception as e:
print(f"np.asarray then [0,1] FAILS: {e}")
# Also test that it works with float conversion
result = float(np_qmatrix[0, 1])
print(f"float(np.asarray(...)[0,1]): {result}")
EOFRepository: NVIDIA/cuopt
Length of output: 173
🏁 Script executed:
# Check for other uses of qmatrix in the class
rg "qmatrix" python/cuopt/cuopt/linear_programming/problem.py -B 2 -A 2Repository: NVIDIA/cuopt
Length of output: 2161
🏁 Script executed:
# Check for tests of MQuadraticExpression
find . -name "*test*" -type f | grep -E "\.(py|cpp)$" | xargs grep -l "MQuadraticExpression" 2>/dev/null || echo "No tests found"Repository: NVIDIA/cuopt
Length of output: 120
🏁 Script executed:
# Check the tests for MQuadraticExpression
sed -n '1,50p' python/cuopt/cuopt/tests/linear_programming/test_python_API.py | head -100Repository: NVIDIA/cuopt
Length of output: 1298
🏁 Script executed:
# Search for MQuadraticExpression usage in tests
grep -n "MQuadraticExpression" python/cuopt/cuopt/tests/linear_programming/test_python_API.py -B 2 -A 10Repository: NVIDIA/cuopt
Length of output: 897
🏁 Script executed:
# Also check if there are other places in the code where MQuadraticExpression is instantiated
rg "MQuadraticExpression(" -B 2 -A 2 --type pyRepository: NVIDIA/cuopt
Length of output: 148
🏁 Script executed:
# Let's search for MQuadraticExpression more carefully with simpler pattern
grep -n "MQuadraticExpression" python/cuopt/cuopt/tests/linear_programming/test_python_API.pyRepository: NVIDIA/cuopt
Length of output: 127
🏁 Script executed:
# Let's look at the test_model_quad_expression function in detail
sed -n '820,850p' python/cuopt/cuopt/tests/linear_programming/test_python_API.pyRepository: NVIDIA/cuopt
Length of output: 1122
🏁 Script executed:
# Let's see if getValue is ever called in tests
rg "\.getValue\(\)" python/cuopt/cuopt/tests/linear_programming/ -B 3 -A 3Repository: NVIDIA/cuopt
Length of output: 4632
🏁 Script executed:
# Check if there are any other files in the library that use MQuadraticExpression
rg "MQuadraticExpression" --type py | grep -v testRepository: NVIDIA/cuopt
Length of output: 1218
Fix mutable defaults and list-of-lists indexing in MQuadraticExpression.
The __init__ method uses mutable default arguments (qvars=[], vars=[], coefficients=[]), which cause state to leak between instances. Additionally, getValue() uses self.qmatrix[i,j] indexing, which fails for list-of-lists (the documented input type) with a TypeError—it only works for numpy arrays. Replace defaults with None and normalize qmatrix to a numpy array via np.asarray().
🛠️ Suggested fix
- def __init__(
- self, qmatrix, qvars=[], vars=[], coefficients=[], constant=0.0
- ):
- self.qmatrix = qmatrix
- self.qvars = qvars
- self.vars = vars
- self.coefficients = coefficients
+ def __init__(
+ self, qmatrix, qvars=None, vars=None, coefficients=None, constant=0.0
+ ):
+ self.qmatrix = np.asarray(qmatrix)
+ self.qvars = list(qvars) if qvars is not None else []
+ self.vars = list(vars) if vars is not None else []
+ self.coefficients = list(coefficients) if coefficients is not None else []
+ if self.qmatrix.ndim != 2 or self.qmatrix.shape[0] != self.qmatrix.shape[1]:
+ raise ValueError("qmatrix must be square")
+ if self.qvars and self.qmatrix.shape[0] != len(self.qvars):
+ raise ValueError("qmatrix size must match qvars length")
self.constant = constant📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def __init__( | |
| self, qmatrix, qvars=[], vars=[], coefficients=[], constant=0.0 | |
| ): | |
| self.qmatrix = qmatrix | |
| self.qvars = qvars | |
| self.vars = vars | |
| self.coefficients = coefficients | |
| self.constant = constant | |
| def shape(self): | |
| return np.shape(self.qmatrix) | |
| def getValue(self): | |
| """ | |
| Returns the value of the expression computed with the | |
| current solution. | |
| """ | |
| # TODO: improve efficiency | |
| value = 0.0 | |
| for i, var in enumerate(self.vars): | |
| value += var.Value * self.coefficients[i] | |
| for i, var1 in enumerate(self.qvars): | |
| for j, var2 in enumerate(self.qvars): | |
| value += var1.Value * var2.Value * float(self.qmatrix[i,j]) | |
| return value + self.constant | |
| def __init__( | |
| self, qmatrix, qvars=None, vars=None, coefficients=None, constant=0.0 | |
| ): | |
| self.qmatrix = np.asarray(qmatrix) | |
| self.qvars = list(qvars) if qvars is not None else [] | |
| self.vars = list(vars) if vars is not None else [] | |
| self.coefficients = list(coefficients) if coefficients is not None else [] | |
| if self.qmatrix.ndim != 2 or self.qmatrix.shape[0] != self.qmatrix.shape[1]: | |
| raise ValueError("qmatrix must be square") | |
| if self.qvars and self.qmatrix.shape[0] != len(self.qvars): | |
| raise ValueError("qmatrix size must match qvars length") | |
| self.constant = constant | |
| def shape(self): | |
| return np.shape(self.qmatrix) | |
| def getValue(self): | |
| """ | |
| Returns the value of the expression computed with the | |
| current solution. | |
| """ | |
| # TODO: improve efficiency | |
| value = 0.0 | |
| for i, var in enumerate(self.vars): | |
| value += var.Value * self.coefficients[i] | |
| for i, var1 in enumerate(self.qvars): | |
| for j, var2 in enumerate(self.qvars): | |
| value += var1.Value * var2.Value * float(self.qmatrix[i,j]) | |
| return value + self.constant |
🤖 Prompt for AI Agents
In `@python/cuopt/cuopt/linear_programming/problem.py` around lines 716 - 741, The
constructor of MQuadraticExpression uses mutable defaults and the qmatrix may be
a list-of-lists, causing shared-state bugs and TypeError in getValue; update
__init__ signature to use None for qvars, vars, and coefficients and inside
__init__ set them to [] if None, and also normalize qmatrix with
np.asarray(qmatrix, dtype=float) (store back to self.qmatrix) so getValue can
safely use self.qmatrix[i, j]; ensure constant and other attributes remain set
as before and no other code paths rely on the old default objects.
| def __iadd__(self, other): | ||
| # Compute quad_expr += lin_expr | ||
| match other: | ||
| case int() | float(): | ||
| # Update just the constant value | ||
| self.constant += float(other) | ||
| return self | ||
| case Variable(): | ||
| # Append just a variable with coefficient 1.0 | ||
| self.vars.append(other) | ||
| self.coefficients.append(1.0) | ||
| return self | ||
| case LinearExpression(): | ||
| # Append all linear variables, coefficients and constants | ||
| self.vars.extend(other.vars) | ||
| self.coefficients.extend(other.coefficients) | ||
| self.constant += other.constant | ||
| return self | ||
|
|
||
| def __add__(self, other): | ||
| # Compute quad_expr1 = quar_expr2 + lin_expr | ||
| match other: | ||
| case int() | float(): | ||
| # Update just the constant value | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| self.vars, | ||
| self.coefficients, | ||
| self.constant + float(other), | ||
| ) | ||
| case Variable(): | ||
| # Append just a variable with coefficient 1.0 | ||
| vars = self.vars + [other] | ||
| coeffs = self.coefficients + [1.0] | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| vars, | ||
| coeffs, | ||
| self.constant, | ||
| ) | ||
| case LinearExpression(): | ||
| # Append all linear variables, coefficients and constants | ||
| vars = self.vars + other.vars | ||
| coeffs = self.coefficients + other.coefficients | ||
| constant = self.constant + other.constant | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| vars, | ||
| coeffs, | ||
| constant, | ||
| ) | ||
|
|
||
| def __isub__(self, other): | ||
| # Compute quad_expr -= lin_expr | ||
| match other: | ||
| case int() | float(): | ||
| # Update just the constant value | ||
| self.constant -= float(other) | ||
| return self | ||
| case Variable(): | ||
| # Append just a variable with coefficient -1.0 | ||
| self.vars.append(other) | ||
| self.coefficients.append(-1.0) | ||
| return self | ||
| case LinearExpression(): | ||
| # Append all linear variables, coefficients and constants | ||
| self.vars.extend(other.vars) | ||
| for coeff in other.coefficients: | ||
| self.coefficients.append(-coeff) | ||
| self.constant -= other.constant | ||
| return self | ||
|
|
||
| def __sub__(self, other): | ||
| # Compute quad_expr2 = quad_expr1 - lin_expr | ||
| match other: | ||
| case int() | float(): | ||
| # Update just the constant value | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| self.vars, | ||
| self.coefficients, | ||
| self.constant - float(other), | ||
| ) | ||
| case Variable(): | ||
| # Append just a variable with coefficient -1.0 | ||
| vars = self.vars + [other] | ||
| coeffs = self.coefficients + [-1.0] | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| vars, | ||
| coeffs, | ||
| self.constant, | ||
| ) | ||
| case LinearExpression(): | ||
| # Append all linear variables, coefficients and constants | ||
| vars = self.vars + other.vars | ||
| coeffs = [] | ||
| for i in self.coefficients: | ||
| coeffs.append(i) | ||
| for i in other.coefficients: | ||
| coeffs.append(-1.0 * i) | ||
| constant = self.constant - other.constant | ||
| return MQuadraticExpression( | ||
| self.qmatrix, | ||
| self.qvars, | ||
| vars, | ||
| coeffs, | ||
| constant, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "problem.py" | grep -E "linear_programming|cuopt"Repository: NVIDIA/cuopt
Length of output: 106
🏁 Script executed:
cat -n ./python/cuopt/cuopt/linear_programming/problem.py | sed -n '746,859p'Repository: NVIDIA/cuopt
Length of output: 5191
🏁 Script executed:
grep -n "def __" ./python/cuopt/cuopt/linear_programming/problem.py | head -20Repository: NVIDIA/cuopt
Length of output: 709
Add explicit error handling for unsupported operand types in operator overloads.
The __iadd__, __add__, __isub__, and __sub__ methods lack default cases in their match statements. When unsupported types are passed, they implicitly return None, breaking Python's operator protocol. For __iadd__ and __isub__, this silently converts the object to None. For __add__ and __sub__, this returns None instead of an expression.
Add default case with error handling
def __iadd__(self, other):
# Compute quad_expr += lin_expr
match other:
case int() | float():
...
return self
case Variable():
...
return self
case LinearExpression():
...
return self
+ case _:
+ raise TypeError(
+ "unsupported operand type(s) for +=: 'MQuadraticExpression' and '%s'"
+ % type(other).__name__
+ )Apply the same fix to __add__, __isub__, and __sub__.
🤖 Prompt for AI Agents
In `@python/cuopt/cuopt/linear_programming/problem.py` around lines 746 - 859, The
match statements in __iadd__, __add__, __isub__, and __sub__ on
MQuadraticExpression lack default branches, so unsupported operand types cause
implicit None returns; add a final "case _:" branch in each method that handles
unsupported types by raising a TypeError (or returning NotImplemented in the
non-inplace methods if you prefer Pythonic binary-operator behavior) with a
clear message including the method name and the operand's actual type (e.g.,
refer to __iadd__/__isub__/__add__/__sub__, MQuadraticExpression, Variable,
LinearExpression in the message) so the operator protocol is not violated and
errors are explicit.
| ## TODO: Add matrix multiplication | ||
| #def __matmul__(self, qcols): | ||
| # if not self.qcols: | ||
| # self.qcols = qcols | ||
| # else: | ||
| # raise Exception("") | ||
|
|
||
| #def __rmatmul__(self, qcols): | ||
| # if not self.qrows: | ||
| # self.qrows = qrows | ||
| # else: | ||
| # raise Exception("") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix comment spacing to satisfy flake8 E265.
🧹 Suggested fix
- `#def` __matmul__(self, qcols):
+ # def __matmul__(self, qcols):
...
- `#def` __rmatmul__(self, qcols):
+ # def __rmatmul__(self, qcols):📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## TODO: Add matrix multiplication | |
| #def __matmul__(self, qcols): | |
| # if not self.qcols: | |
| # self.qcols = qcols | |
| # else: | |
| # raise Exception("") | |
| #def __rmatmul__(self, qcols): | |
| # if not self.qrows: | |
| # self.qrows = qrows | |
| # else: | |
| # raise Exception("") | |
| ## TODO: Add matrix multiplication | |
| # def __matmul__(self, qcols): | |
| # if not self.qcols: | |
| # self.qcols = qcols | |
| # else: | |
| # raise Exception("") | |
| # def __rmatmul__(self, qcols): | |
| # if not self.qrows: | |
| # self.qrows = qrows | |
| # else: | |
| # raise Exception("") |
🧰 Tools
🪛 Flake8 (7.3.0)
[error] 862-862: block comment should start with '# '
(E265)
[error] 868-868: block comment should start with '# '
(E265)
🤖 Prompt for AI Agents
In `@python/cuopt/cuopt/linear_programming/problem.py` around lines 861 - 872, The
inline TODO and commented-out method lines violate flake8 E265 (missing space
after '#'); update the comment lines in this block so every comment token has a
single space after the '#' (e.g., change "## TODO: Add matrix multiplication" to
"# TODO: Add matrix multiplication" and "#def __matmul__..." to "# def
__matmul__(self, qcols):", likewise "#def __rmatmul__..." to "# def
__rmatmul__(self, qcols):") while keeping the same text and references to the
methods __matmul__, __rmatmul__ and attributes qcols/qrows.
|
/ok to test c2b2032 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
conda/environments/all_cuda-129_arch-x86_64.yaml (1)
1-2: Update the sourcedependencies.yamlfile instead of editing the auto-generated file directly.This file is auto-generated from
../../dependencies.yaml. The header comment instructs that changes must be made to the source file and thenrapids-dependency-file-generatormust be run to regenerate this file. The scipy dependency was added only to this auto-generated file, not to the source. On the next regeneration, this change will be lost.Please add scipy to
dependencies.yamland regenerate this file to ensure the dependency persists.
🤖 Fix all issues with AI agents
In `@conda/environments/all_cuda-131_arch-aarch64.yaml`:
- Line 64: The generated environment includes "scipy" but the source
dependencies.yaml is missing it, so add a scipy entry to dependencies.yaml
(e.g., scipy>=1.15,<2.0 or another range compatible with your NumPy constraint
>=1.23.5,<3.0) and then regenerate the conda environment file so scipy is
preserved; ensure the dependency name matches "scipy" exactly and the version
pin is consistent with Python 3.10–3.13 and aarch64 conda-forge packages.
|
/ok to test 254a5a9 |
| raise Exception("Quadratic constraints not supported") | ||
|
|
||
|
|
||
| class MQuadraticExpression: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a separate MQuadraticExpression class? Could we just add another way to initialize a regular QuadraticExpression class?
chris-maes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we discuss the need for MQuadraticExpression before merging?
Description
Issue
Checklist
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.