scs 3.3.1


pip install scs

  Latest version

Released: Sep 05, 2026

Project Links

Meta
Author: Brendan O'Donoghue
Requires Python: >=3.9

Classifiers

License
  • OSI Approved :: MIT License

Programming Language
  • C
  • Python
  • Python :: 3
  • Python :: 3.9
  • Python :: 3.10
  • Python :: 3.11
  • Python :: 3.12
  • Python :: 3.13
  • Python :: 3.14
  • Python :: 3 :: Only
  • Python :: Free Threading :: 3 - Stable
  • Python :: Implementation :: CPython

Operating System
  • Microsoft :: Windows
  • POSIX
  • Unix
  • MacOS

scs-python

Build Status Documentation PyPI Downloads Conda Downloads

Python interface for SCS 3.0.0 and higher. The full documentation is available here.

Installation

pip install scs

On x86-64 Linux the manylinux (glibc) wheels include the MKL Pardiso direct linear solver (MKL linked statically into _scs_mkl, single-threaded) and use it automatically: it is faster than the built-in QDLDL solver for most problems, often dramatically so on larger ones, and nothing extra needs to be installed. Intel's license notice ships in the wheel as LICENSE-INTEL-MKL.txt. Every other wheel falls back to QDLDL.

To install from source:

git clone --recursive https://github.com/bodono/scs-python.git
cd scs-python
pip install .

Linear solver backends

SCS supports several linear solver backends. The default is AUTO, which selects the best available solver for the platform:

  • macOS: QDLDL (Apple Accelerate is available via LinearSolver.ACCELERATE)
  • Linux / Windows: MKL Pardiso if available, otherwise QDLDL
# Auto-detect best backend (default)
solver = scs.SCS(data, cone)

# Explicitly select a solver
solver = scs.SCS(data, cone, linear_solver=scs.LinearSolver.QDLDL)

Available values: AUTO, QDLDL, CPU_INDIRECT, MKL, ACCELERATE, CPU_DENSE, GPU_INDIRECT, CUDSS.

The pre-built wheels (pip install scs) link OpenBLAS on Linux and Windows, and Apple Accelerate on macOS; the x86-64 manylinux wheels also ship the MKL Pardiso backend (see Installation). MKL is linked statically rather than bundled as shared libraries, whose dlopen'd CPU dispatch kernels wheel-repair tools cannot see (cvxgrp/scs#423). The MKL backend is also available in source builds (e.g. conda environments providing MKL), where additional backends can be enabled with build-time flags:

# MKL Pardiso direct solver
pip install . -Csetup-args=-Dlink_mkl=true

# Use 64-bit BLAS/LAPACK integers (ILP64 / BLAS64). Requires the MKL
# backend (-Dlink_mkl=true): standard system BLAS (Accelerate/OpenBLAS)
# is LP64 and the build rejects the combination as unsafe.
pip install . -Csetup-args=-Dlink_mkl=true -Csetup-args=-Duse_blas64=true

# GPU direct solver (cuDSS)
pip install . -Csetup-args=-Dlink_cudss=true -Csetup-args=-Dint32=true

# Dense direct solver (LAPACK)
pip install . -Csetup-args=-Duse_lapack=true

# Spectral cones (logdet, nuclear norm, ell-1, sum-of-largest)
pip install . -Csetup-args=-Duse_spectral_cones=true

Notes:

  • x86-64 manylinux wheels ship a _scs_mkl extension with sequential MKL linked statically (CI asserts the shipped inventory and that no wheel carries a dynamic MKL dependency). The musllinux, aarch64, macOS and Windows wheels do not include the MKL backend; Windows source builds use sequential MKL because Intel's conda pkg-config metadata for the threaded variant is still broken.
  • Windows wheels link conda-forge OpenBLAS pinned to 0.3.33: the win-64 0.3.34 build crashes inside its DGEMM kernels on AMD Zen 4/5 CPUs that expose AVX-512 (conda-forge/openblas-feedstock#196), so Windows source builds should avoid that build too.
  • BLAS64 is a general SCS build mode for ILP64 BLAS/LAPACK libraries, not an MKL-only feature.
  • For the MKL Pardiso backend specifically, BLAS64 must be paired with 64-bit SCS integers (DLONG / int32=false), and SCS now fails early if another library in the process has already fixed MKL to an incompatible LP64/ILP64 interface layer.

Usage

import numpy as np
import scipy.sparse as sp
import scs

m, n = 4, 2
A = sp.random(m, n, density=0.5, format="csc")
b = np.random.randn(m)
c = np.random.randn(n)
P = sp.eye(n, format="csc")

cone = {"l": m}  # non-negative cone
data = {"P": P, "A": A, "b": b, "c": c}

solver = scs.SCS(data, cone, verbose=False)
sol = solver.solve()

print(sol["info"]["status"])  # 'solved'
print(sol["info"]["aa_stats"])  # Anderson acceleration diagnostics
print(sol["x"])               # primal solution

Anderson acceleration tuning

SCS applies Anderson acceleration (AA) on top of ADMM. The defaults work well for most problems, but the following settings can be tuned:

Setting Default Description
acceleration_lookback 10 AA memory size; 0 disables AA.
acceleration_interval 5 Apply AA every N ADMM iterations.
acceleration_type_1 1 1 = type-I AA, 0 = type-II AA.
acceleration_regularization 1e-8 Tikhonov regularization for the AA least-squares solve; a negative value pins its absolute value. Tuned for type-I; type-II typically prefers 1e-12.
acceleration_relaxation 1.0 Relaxation factor in [0, 2]; 1.0 is vanilla AA.
# Type-II AA with tighter regularization
solver = scs.SCS(data, cone,
                 acceleration_type_1=0,
                 acceleration_regularization=1e-12)

See the acceleration docs for the underlying algorithm.

Cone types

The cone dict supports the following keys:

Key Type Description
z int Zero cone
l int Non-negative cone
bu, bl array Box cone bounds
q list[int] Second-order cone lengths
s list[int] PSD cone matrix dimensions
cs list[int] Complex PSD cone matrix dimensions
ep int Primal exponential cone triples
ed int Dual exponential cone triples
p list[float] Power cone parameters

With -Duse_spectral_cones=true:

Key Type Description
d list[int] Log-determinant cone matrix dimensions
nuc_m, nuc_n list[int] Nuclear norm cone row/column dimensions
ell1 list[int] ell-1 norm cone dimensions
sl_n, sl_k list[int] Sum-of-largest-eigenvalues dimensions and k values

See the cone documentation for mathematical definitions and data layout details.

Testing

pip install pytest
pytest test/

Wheel compatibility matrix

Platform CPython 3.9 CPython 3.10 CPython 3.11 CPython 3.12 CPython 3.13 CPython 3.14 CPython 3.15 CPython (additional flags: t) 3.14 CPython (additional flags: t) 3.15
macosx_11_0_arm64
manylinux_2_27_aarch64
manylinux_2_27_x86_64
manylinux_2_28_aarch64
manylinux_2_28_x86_64
musllinux_1_2_x86_64
win_amd64

Files in release

scs-3.3.1-cp310-cp310-macosx_11_0_arm64.whl (229.1KiB)
scs-3.3.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp310-cp310-win_amd64.whl (7.3MiB)
scs-3.3.1-cp311-cp311-macosx_11_0_arm64.whl (229.1KiB)
scs-3.3.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp311-cp311-win_amd64.whl (7.3MiB)
scs-3.3.1-cp312-cp312-macosx_11_0_arm64.whl (229.7KiB)
scs-3.3.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp312-cp312-win_amd64.whl (7.3MiB)
scs-3.3.1-cp313-cp313-macosx_11_0_arm64.whl (229.3KiB)
scs-3.3.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp313-cp313-win_amd64.whl (7.3MiB)
scs-3.3.1-cp314-cp314-macosx_11_0_arm64.whl (229.3KiB)
scs-3.3.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp314-cp314-win_amd64.whl (7.4MiB)
scs-3.3.1-cp314-cp314t-macosx_11_0_arm64.whl (232.2KiB)
scs-3.3.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp314-cp314t-win_amd64.whl (7.4MiB)
scs-3.3.1-cp315-cp315-macosx_11_0_arm64.whl (229.3KiB)
scs-3.3.1-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp315-cp315-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp315-cp315-win_amd64.whl (7.4MiB)
scs-3.3.1-cp315-cp315t-macosx_11_0_arm64.whl (232.1KiB)
scs-3.3.1-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp315-cp315t-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp315-cp315t-win_amd64.whl (7.4MiB)
scs-3.3.1-cp39-cp39-macosx_11_0_arm64.whl (229.2KiB)
scs-3.3.1-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (5.1MiB)
scs-3.3.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (41.2MiB)
scs-3.3.1-cp39-cp39-musllinux_1_2_x86_64.whl (11.7MiB)
scs-3.3.1-cp39-cp39-win_amd64.whl (7.3MiB)
scs-3.3.1.tar.gz (1.7MiB)
Extras: None
Dependencies:
numpy
scipy