Skip to content

SCS 3.3.1 Python bindings

Latest

Choose a tag to compare

@bodono bodono released this 05 Sep 17:02
e6f3ec7

Python bindings for SCS 3.3.1, pinned to core commit cc244ebc4bff620e2e228e99a4e2e24ab12f9e3b.

Important: replacement for the yanked 3.3.0 wheels

The 3.3.0 x86-64 Linux wheels omitted MKL's dynamically loaded CPU-dispatch libraries. Wheel-repair tools did not detect those dependencies, so a first solve on a machine without an external MKL installation could abort Python with Intel oneMKL FATAL ERROR: Cannot load libmkl_def.so.3 (cvxgrp/scs#423).

3.3.1 fixes the packaging rather than requiring users to repair their loader environment. Upgrade with:

python -m pip install --upgrade scs
python -c "import scs; print(scs.__version__)"

The version check should report 3.3.1. The historical 3.3.0 release remains yanked; its warning is not removed by this release.

Wheel backends and packaging (#232)

Wheel platform Standard BLAS/LAPACK Packaged MKL Pardiso Default solver
x86-64 Linux, manylinux/glibc Vendored OpenBLAS Static, sequential MKL MKL Pardiso
Linux aarch64, manylinux Vendored OpenBLAS No QDLDL
x86-64 Linux, musllinux Vendored OpenBLAS No QDLDL
macOS Apple Silicon Apple Accelerate No QDLDL
Windows x86-64 OpenBLAS No QDLDL
  • On x86-64 manylinux, MKL is linked statically into _scs_mkl; its symbols are hidden to avoid interposition with other libraries. No MKL shared libraries, separate runtime installation, LD_LIBRARY_PATH adjustment, or scs[mkl] extra is required. The Intel license notice is included in the wheel.
  • The packaged MKL backend uses its sequential variant. This is distinct from source configurations that can use threaded MKL; it is not a promise that every other BLAS in the Python process is single-threaded.
  • Windows wheels pin conda-forge OpenBLAS to 0.3.33 to avoid the 0.3.34 DGEMM crash observed on AMD Zen 4/5 AVX-512 systems (conda-forge/openblas-feedstock#196).
  • macOS users can still explicitly select the Accelerate solver where available. GPU and other optional backends remain source-build options.

The published inventory is 45 wheels and one source distribution: nine Python/ABI combinations on each of the five platforms above (CPython 3.9–3.15, plus 3.14t and 3.15t). Intel macOS wheels are not part of this inventory; use a source build or another suitable distribution on that platform. Python-version wheel availability is not a statement that every upstream Python version is already a stable release.

Source-build safety (#230)

  • An explicitly requested MKL build fails if MKL cannot be located, instead of appearing to succeed without the requested backend.
  • Meson's use_blas64=true requires link_mkl=true, and MKL ILP64 requires 64-bit SCS indices (int32=false). This prevents declaring 64-bit BLAS integers while calling an LP64 provider.
  • The legacy --blas64 path is rejected because it cannot verify the provider contract. Use the Meson build instead, for example:
python -m pip install . \
  -Csetup-args=-Dlink_mkl=true \
  -Csetup-args=-Duse_blas64=true \
  -Csetup-args=-Dint32=false
  • Dynamic MKL builds retain mkl_rt as an actual link dependency so the core's interface-width check cannot be silently dropped by the linker. Windows source configurations select sequential MKL to avoid broken threaded-provider metadata.
  • Settings validation follows the core's finite-value contract, and solver information includes the selected linear-system backend.

Interrupt handling and regularization (#231, #234)

  • Ctrl-C state is shared across SCS extension modules. Overlapping solves using different backends no longer restore handlers out of order and leave Python swallowing later interrupts.
  • On Windows, cleanup removes the exact console handler that was installed, even when the last active solve belongs to another extension. Regression tests cover cross-backend overlap and handler restoration.
  • The core repin enables finite negative acceleration_regularization: its absolute magnitude is pinned rather than adaptively scaled. Both AA types are tested with a real solved problem; NaN and both infinities remain invalid. Zero remains allowed.

Compatibility and validation

Python 3.9 or newer remains required. The 3.3.0 linear_solver=scs.LinearSolver.* selection API remains in place; this release does not add a backward-compatibility shim for the old boolean solver-selection arguments.

Every wheel is tested during its build. Linux wheel auditing checks standard extensions, vendored OpenBLAS, the appropriate MKL extension, absence of dynamic Intel dependencies, and relative loader paths. Clean x86-64 containers on Python 3.9, 3.14, and 3.14t import MKL, verify AUTO selects it, and solve a problem containing a PSD cone with each packaged backend before PyPI publication. Source MKL lanes cover LP64 success, ILP64 mismatch rejection, and ILP64 success; free-threading has a separate test workflow.

Local release validation built and installed a CPython 3.14 macOS arm64 wheel: native runtime, installed distribution, and wheel metadata all report 3.3.1; 396 tests passed, with 67 platform/optional-feature skips. The sdist was checked against the pinned core and successfully rebuilt into a wheel. Those local results do not substitute for the Linux MKL or Windows release gates.

Full Python changelog

Published artifact verification

The production release workflow passed, including PyPI upload. Every published filename, size, and SHA-256 digest matches the corresponding tested CI artifact (45 wheels and one sdist). Wheel metadata and backend inventories were checked across all five platforms. The production clean-container logs explicitly report SCS 3.3.1, AUTO selecting _scs_mkl, and successful Pardiso solves on Python 3.9, 3.14, and 3.14t.

Install/download from PyPI.

The macOS CPython 3.14 wheel was additionally downloaded directly from PyPI, installed in an isolated directory, and rerun through the full local suite: 396 passed, 67 platform/optional-feature skips; runtime and distribution versions both report 3.3.1.