Skip to main content

CVXPYgen

PyPI version Python License CI

CVXPYgen takes a parametrized CVXPY convex optimization problem and generates a custom C solver tailored to that problem family. The generated code provides interfaces in C/C++ (for embedded applications) and Python/CVXPY (for prototyping and desktop applications).

Problems need to be modeled according to disciplined parametrized programming (DPP). For more details, see our slides and manuscript. If you use this code, please cite

@article{schaller2022embedded,
  title={Embedded code generation with CVXPY},
  author={Schaller, Maximilian and Banjac, Goran and Diamond, Steven and Agrawal, Akshay and Stellato, Bartolomeo and Boyd, Stephen},
  journal={IEEE Control Systems Letters},
  volume={6},
  pages={2653--2658},
  year={2022},
  publisher={IEEE}
}

Install

pip install cvxpygen

The CLARABEL solver requires Rust and Eigen. Example notebooks require marimo and matplotlib.

Quick start: Nonnegative least squares

import cvxpy as cp
from cvxpygen import cpg

# define CVXPY problem
m, n = 3, 2
A = cp.Parameter((m, n), name='A')
b = cp.Parameter(m, name='b')
x = cp.Variable(n, name='x')
problem = cp.Problem(cp.Minimize(cp.sum_squares(A @ x - b)), [x >= 0])

# generate code
cpg.generate_code(problem, code_dir='nonneg_ls')

Important: Set name= on variables and parameters. You'll identify them with these names after code generation. An extended version of this example is available under quick_start.py. An HTML summary of the generated code is written to nonneg_ls/README.html, with instructions for using the generated code.

C interface

Here is how to compile the auto-generated example nonneg_ls/c/src/cpg_example.c (requires CMake). Parameters and variables are stored as Fortran-order (column-major) flat arrays in C.

Unix:

cd nonneg_ls/c/build
cmake ..
cmake --build . --target cpg_example
./cpg_example

Windows:

cd nonneg_ls\c\build
cmake ..
cmake --build . --target cpg_example --config release
Release\cpg_example
CVXPY interface Here is how to register the Python module as a custom method for CVXPY.
from nonneg_ls.cpg_solver import cpg_solve
problem.register_solve('CPG', cpg_solve)

b.value = ...
problem.solve(method='CPG', updated_params=['b'])

solution = x.value

You may pass updated_params to tell the solver which parameters changed (omit it to update all).

generate_code options

Argument Type Default Description
code_dir str 'cpg_code' Output directory
solver str 'OSQP' for QPs
'QOCOGEN' for SOCPs
Solver backend
solver_opts dict {} Options forwarded to the solver
enable_settings list[str] [] Solver settings to keep tuneable at runtime
prefix str '' Symbol prefix for multi-problem codegen
gradient bool False Enable gradient computation (QPs only)
wrapper bool True Compile Python wrapper

Examples

Domain Marimo notebook
Actuator allocation actuator.py
Approximate dynamic programming adp.py
Model predictive control mpc.py
Portfolio construction portfolio.py
Resource allocation resource.py
Energy management energy.py
Network flow optimization network.py
Tuning PV system design power.py (requires cvxpylayers>=1.2 and torch)
Learning alpha alpha.py (requires cvxpylayers>=1.2, torch, and pandas)

All examples require marimo and matplotlib. Run any marimo notebook as:

marimo edit actuator.py

Differentiable QPs

CVXPYgen can generate code for differentiating the parameter-solution map of quadratic programs, with an interface to CVXPYlayers (version 1.2 or newer):

cpg.generate_code(problem, code_dir='nonneg_ls_diff', gradient=True)

from nonneg_ls_diff.cpg_solver import forward, backward
from cvxpylayers.torch import CvxpyLayer
from cvxpylayers.interfaces import SolverInterface

layer = CvxpyLayer(problem, parameters=[A, b], variables=[x],
                   solver=SolverInterface.from_codegen(forward, backward))

As long as the problem is a QP, also conic solvers such as QOCOGEN or CLARABEL are supported. For more details, see our manuscript on differentiable QPs and examples/paper_grad for examples from the manuscript. Also see the example notebooks power.py and alpha.py. If you use this feature, please cite

@article{schaller2025code,
  title={Code generation for solving and differentiating through convex optimization problems},
  author={Schaller, Maximilian and Boyd, Stephen},
  journal={Optimization and Engineering},
  pages={1--25},
  year={2025},
  publisher={Springer}
}

Explicit solutions for QPs

For QPs whose parameters are all vectors (no matrix parameters), the solution is a piecewise affine function of the parameters. CVXPYgen integrates with PDAQP to precompute this map offline and generates code for instant evaluation online. Advantages of such an explicit solver can include transparency, interpretability, reliability, and speed. The number of inequality constraints (and non-differentiable atoms such as cp.norm1) should be small, since the number of affine pieces typically grows exponentially with those.

Important: Limit parameters with standard CVXPY constraints to keep the number of affine pieces tractable. For example, specify l <= p, p <= u where p is a CVXPY parameter and l and u are arrays:

prob = cp.Problem(obj, constr + [l <= p, p <= u])
cpg.generate_code(prob, code_dir='code_explicit', solver='explicit')

To enable the computation of dual variables, set solver_opts={'dual': True}. Control complexity via 'max_floats' (number of floating point numbers in the explicit solution, default 1e6) and 'max_regions' (maximum number of affine pieces, default 500) in solver_opts. Store the explicit solution in half precision (instead of single precision) by setting 'fp16': True in solver_opts.

For more details, see our slides and manuscript on explicit solutions for QPs. For practical examples, see power.py and alpha.py. If you use this feature, please cite

@article{schaller2025automatic,
  title={Automatic generation of explicit quadratic programming solvers},
  author={Schaller, Maximilian and Arnstr{\"o}m, Daniel and Bemporad, Alberto and Boyd, Stephen},
  journal={arXiv preprint arXiv:2506.11513},
  year={2025}
}

CVXPYgen 1.0 supports gradient=True along with solver='explicit'.

Tests

pip install pytest
cd tests
pytest

Metadata

Release files for cvxpygen 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cvxpygen 1.0.1
File Size Uploaded Provenance
cvxpygen-1.0.1.tar.gz 633.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cvxpygen 1.0.1
File Interpreter ABI Platform
cvxpygen-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / cvxpygen-1.0.1.tar.gz

Download URL cvxpygen-1.0.1.tar.gz
Size 633.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ef9e78919e51c4b8ea9210f224cd6d886f086db0d7b066fa0ca987dc919276a5
BLAKE2b-256 checksum
How to use checksums
542f42470ae7530421d6f09de8e5ce2e089669b9d113d748045b6e5d343db5a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / cvxpygen-1.0.1-py3-none-any.whl

Download URL cvxpygen-1.0.1-py3-none-any.whl
Size 774.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4134fd8f2319309eb96a71976f4fdc2cce9669b6341478b9d3963b510cf188e2
BLAKE2b-256 checksum
How to use checksums
ebe4fbbb54b1703814929c4e1ad18696b5e5d4e94bf1ab8b6dd2cb1468127c0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Security for cvxpygen 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page