CVXPY Integration¶
Moreau can be used as a solver backend for CVXPY, letting you formulate problems with CVXPY’s high-level modeling language and solve them with Moreau’s GPU-accelerated conic solver.
Requirements
Moreau support requires cvxpy >= 1.8.2 and cvxpylayers >= 1.0.4:
pip install 'cvxpy>=1.8.2' 'cvxpylayers>=1.0.4'
Quick Start¶
import cvxpy as cp
import numpy as np
# Define problem using CVXPY's modeling language
x = cp.Variable(3)
objective = cp.Minimize(cp.sum_squares(x) + x[0])
constraints = [cp.sum(x) == 1, x >= 0]
problem = cp.Problem(objective, constraints)
# Solve with Moreau
problem.solve(solver=cp.MOREAU)
print(f"Status: {problem.status}") # optimal
print(f"Optimal value: {problem.value}")
print(f"Optimal x: {x.value}")
CVXPY automatically converts your problem into the conic form that Moreau expects. You don’t need to manually construct P, A, b, or specify cones.
Supported Problem Types¶
Moreau supports any CVXPY problem that reduces to a conic program with the following cones:
CVXPY Construct |
Moreau Cone |
Notes |
|---|---|---|
|
Zero cone |
Equality constraints |
|
Nonnegative cone |
Inequality constraints |
|
Second-order cone |
Arbitrary dimension >= 2 |
|
Second-order cone |
Via automatic reformulation |
|
Quadratic objective |
Direct P matrix support |
Note
Moreau supports arbitrary-dimension second-order cones natively. As of cvxpy 1.8.2, CVXPY passes variable-length SOC dimensions directly to Moreau without reformulation.
Linear Programs¶
n = 5
c = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
x = cp.Variable(n)
problem = cp.Problem(
cp.Minimize(c @ x),
[cp.sum(x) == 1, x >= 0]
)
problem.solve(solver=cp.MOREAU)
Quadratic Programs¶
n = 10
np.random.seed(42)
P = np.random.randn(n, n)
P = P.T @ P + np.eye(n) # Positive definite
q = np.random.randn(n)
x = cp.Variable(n)
problem = cp.Problem(
cp.Minimize(0.5 * cp.quad_form(x, P) + q @ x),
[cp.sum(x) == 1, x >= 0]
)
problem.solve(solver=cp.MOREAU)
Second-Order Cone Programs¶
x = cp.Variable(3)
problem = cp.Problem(
cp.Minimize(x[0]),
[cp.SOC(x[0], x[1:]), x[1] == 1, x[2] == 0]
)
problem.solve(solver=cp.MOREAU)
# x[0] >= ||[x[1], x[2]]|| = 1
Norm constraints work too — CVXPY reformulates them into SOC form:
n = 10
x = cp.Variable(n)
problem = cp.Problem(
cp.Minimize(cp.norm(x)),
[cp.sum(x) == n]
)
problem.solve(solver=cp.MOREAU)
Mixed Constraints¶
Combine equality, inequality, and cone constraints freely:
n = 5
returns = np.array([0.1, 0.2, 0.15, 0.12, 0.18])
w = cp.Variable(n)
problem = cp.Problem(
cp.Minimize(cp.sum_squares(w)),
[
returns @ w >= 0.15, # Return target
cp.sum(w) == 1, # Budget
w >= 0, # Long only
cp.norm(w) <= 2, # Risk limit
]
)
problem.solve(solver=cp.MOREAU)
Solver Settings¶
Pass solver options as keyword arguments to problem.solve(). Top-level Settings fields (device, max_iter, verbose, time_limit) are passed directly; IPM-specific settings go in a nested ipm_settings dict:
# Top-level settings (device, iteration limit, verbosity)
problem.solve(
solver=cp.MOREAU,
verbose=True,
max_iter=500,
device="cpu", # 'auto' (default), 'cpu', or 'cuda'
time_limit=10.0, # seconds
)
# IPM tolerances and KKT solver method (via ipm_settings dict)
problem.solve(
solver=cp.MOREAU,
ipm_settings={
"tol_gap_abs": 1e-6,
"tol_feas": 1e-6,
"tol_gap_rel": 1e-6,
"direct_solve_method": "qdldl", # 'auto', 'qdldl', 'faer', 'cudss', 'riccati', 'woodbury'
},
)
Verifying Against Other Solvers¶
CVXPY makes it easy to verify Moreau’s solutions against other solvers:
# Solve with CLARABEL
problem.solve(solver=cp.CLARABEL)
clarabel_obj = problem.value
# Solve with Moreau
problem.solve(solver=cp.MOREAU)
moreau_obj = problem.value
np.testing.assert_allclose(moreau_obj, clarabel_obj, rtol=1e-4)
When to Use CVXPY vs Native API¶
Use Case |
Recommendation |
|---|---|
Prototyping |
CVXPY — easier problem formulation |
Production with fixed structure |
Native API — better performance |
Complex cone constraints |
CVXPY — automatic reformulation |
Batched solving |
Native |
Differentiable optimization |
cvxpylayers or native PyTorch/JAX API |
CVXPY adds some overhead from problem parsing and parameter evaluation compared to using Moreau directly. For production workloads — especially batched problems or training loops — the native Moreau API provides better performance.
Tip
A common workflow is to prototype with CVXPY, then port to the native API for production. See cvxpylayers Integration for differentiable optimization with CVXPY.