Fast LP file writer for scipy CSR matrices, implemented in Rust with Python bindings via PyO3.
Designed as a prototype for linopy integration, where LP file serialization is a bottleneck for large energy system models (10M+ nonzeros).
Benchmarked on random sparse matrices written to /tmp/ (median of 3 runs):
| Size | NNZ | Rust (s) | Linopy total (s) | Speedup |
|---|---|---|---|---|
| small | 20K | 0.001 | 0.062 | 62× |
| medium | 1M | 0.049 | 0.220 | 4.5× |
| large | 10M | 0.224 | 1.728 | 7.7× |
| xlarge | 20M | 0.402 | 3.539 | 8.8× |
| Size | NNZ | Rust (s) | Linopy write (s) | Speedup |
|---|---|---|---|---|
| small | 20K | 0.001 | 0.022 | 22× |
| medium | 1M | 0.049 | 0.156 | 3.2× |
| large | 10M | 0.224 | 1.436 | 6.4× |
| xlarge | 20M | 0.402 | 2.999 | 7.5× |
Rust throughput peaks at ~50M NNZ/s (~1.3 GB/s).
Key optimizations: ryu for float formatting, itoa for integer formatting, row-buffered writes, prefix-based name generation (no Python string copies), 4MB BufWriter.
Requires Python ≥ 3.10 and a Rust toolchain.
uv venv
uv pip install maturin numpy scipy
maturin develop --releaseimport numpy as np
from scipy.sparse import csr_matrix
from lp_writer import write_lp_constraints
A = csr_matrix([[1.0, -2.5, 0, 3.0],
[0, 1.0, -1.0, 0],
[4.0, 0, 1.0, -7.0]])
rhs = np.array([10.0, 20.0, 30.0])
senses = ["<=", ">=", "="]
write_lp_constraints("model.lp", A, rhs, senses)Output:
\\ Problem
Minimize
obj: x0
Subject To
c0: x0 - 2.5 x1 + 3.0 x3 <= 10.0
c1: x1 - x2 >= 20.0
c2: 4.0 x0 + x2 - 7.0 x3 = 30.0
Bounds
-inf <= x0 <= +inf
-inf <= x1 <= +inf
-inf <= x2 <= +inf
-inf <= x3 <= +inf
End
def write_lp_constraints(
path: str,
A: csr_matrix,
rhs: np.ndarray,
senses: list[str] | np.ndarray, # "<=", ">=", "="
var_prefix: str = "x",
con_prefix: str = "c",
) -> None- path — output file path
- A — constraint matrix (scipy CSR)
- rhs — right-hand side values
- senses — constraint senses, either
list[str]ornp.ndarrayofuint8(ord('<'),ord('>'),ord('=')) - var_prefix / con_prefix — name prefixes; variables are named
{var_prefix}{col_index}, constraints{con_prefix}{row_index}
uv venv
uv pip install -e ".[dev]" linopy
maturin develop --release
# tests
pytest tests/
# benchmark
python bench/benchmark.py├── Cargo.toml
├── pyproject.toml
├── src/lib.rs # Rust extension (PyO3)
├── python/lp_writer/
│ ├── __init__.py # Python wrapper
│ └── py.typed
├── tests/test_lp_writer.py
└── bench/benchmark.py