Sparse_Numba
A Numba-compatible sparse linear solver: SuperLU, Eigen (SparseLU and
SimplicialLDLT) and a user-supplied UMFPACK behind one interface that runs
inside @njit(nogil=True) code and keeps its numba cache across processes.
- New to it? The user guide walks through the backends, the orderings, the handle's life, numba use and the cache.
- Scripts to run and read: examples/.
- What 0.2.0 adds and changes over 0.1.11: the release notes.
0.2.0 vs 0.1.11 at a glance (the largest test matrix, n = 20698; one machine; details and every size in Performance):
- Solve: 3969 us in 0.1.11 (SuperLU, NATURAL only) -> 1426 us with the new ordering choice (SuperLU COLAMD, 2.8x) and 755 us with the new Eigen backend (Eigen LU COLAMD, 5.3x); SuperLU NATURAL stays bit-identical to 0.1.11 on the same CPU and BLAS kernel.
- Factorize: 68961 us -> 16450 us (SuperLU COLAMD, 4.2x) and 12585 us (Eigen
LU COLAMD, 5.5x); the new
refactorizere-factors the same pattern in 10138 us (SuperLU COLAMD). - Overhead of the numba wrapper against a direct C++ call (sparse_numba / direct, ratio of medians): 0.85 to 1.23 at the largest size and 0.77 to 2.17 over all four sizes, in both directions; in 19 of the 102 measured cells sparse_numba's and the direct call's min - max ranges do not overlap.
Why Sparse_Numba?
Sparse linear solvers in Python (SciPy, CVXOPT, KVXOPT) are called from the
interpreter. Sparse_Numba's functions are njit(nogil=True, cache=True):
they are called from Numba-compiled code, release the GIL, and so run in
parallel threads (prange) without a round trip through Python.
Installation
pip install sparse-numba
One wheel per Python (CPython 3.10 - 3.13) and platform, each built and tested on its own Python. Requires numba >= 0.61 (the first numba with Python 3.13; it needs Python 3.10) and numpy >= 1.24. Python 3.9 users stay on 0.1.11.
| Platform | Python | Wheels | SuperLU / OpenBLAS | UMFPACK |
|---|---|---|---|---|
| Windows (x86_64) | 3.10 - 3.13 | yes | vendored in the wheel | the user's SuiteSparse |
| Linux (x86_64, manylinux_2_28: glibc >= 2.28) | 3.10 - 3.13 | yes | bundled in the wheel (SuperLU 5.x, OpenBLAS, ATLAS, the gfortran runtime) | the user's SuiteSparse |
| macOS (Apple Silicon) | 3.10 - 3.13 | yes | Homebrew's (superlu, openblas) | the user's SuiteSparse |
| macOS (Intel) | 3.10 - 3.13 | build from source | Homebrew's | the user's SuiteSparse |
Intel Mac users: pip install sparse-numba --no-binary=sparse-numba.
SuperLU's version differs per platform: 7.0.0 in the Windows wheels, 5.x
in the Linux wheels (AlmaLinux 8's package, bundled by auditwheel into
sparse_numba.libs), Homebrew's on macOS.
The Linux wheels are manylinux_2_28: they need glibc >= 2.28 (e.g.
Ubuntu 18.10+, Debian 10+, RHEL / AlmaLinux / Rocky 8+); on an older
glibc pip builds from the sdist (section "Building from source").
UMFPACK: bring your own SuiteSparse
No SuiteSparse binary ships with sparse_numba (UMFPACK and CHOLMOD are GPL / LGPL; see Licences below). The UMFPACK backend loads the user's library at its first call:
SPARSE_NUMBA_UMFPACK_LIBRARY=/path/to/libumfpack.{dll,so,dylib}names it (only that path is tried); otherwise- the platform's library names are tried through the platform loader:
libumfpack.dll,umfpack.dll(Windows: the default DLL directories, among them those added withos.add_dll_directory; sparse_numba addsSUITESPARSE_BINwhen it is set);libumfpack.so.6,.so.5,.so(Linux);libumfpack.6.dylib,.5.dylib,.dylib(macOS).
Not found: every UMFPACK call returns BACKEND_ABSENT (-20), backends()
leaves it out, and require(UMFPACK) raises with this hint. Nothing is
printed at import.
Building from source
Windows needs MinGW-w64 (x86_64-posix-seh) on PATH; setup.py selects the
mingw32 compiler itself. Then:
python -m build --wheel
pip install dist/sparse_numba-<VERSION>-<TAGS>.whl
Linux and macOS need the SuperLU and OpenBLAS development packages (and SuiteSparse's headers for the UMFPACK interface). Build switches (setup.py, read at build time):
| variable | effect |
|---|---|
SPARSE_NUMBA_SKIP_UMFPACK=1 |
the UMFPACK interface extension is not built (no SuiteSparse headers needed) |
SPARSE_NUMBA_DEBUG=1 |
every extension is compiled WITHOUT -DNDEBUG (the asserts on, for development); never set for a release wheel |
SPARSE_NUMBA_EXTRA_CFLAGS="..." |
appended to every extension's compile flags (a comparison build, e.g. -march=native); never set for a release wheel |
The release flags: -O3 -DNDEBUG on every extension and platform (plus
-DMS_WIN64 on 64-bit Windows, -fPIC on Linux / macOS); the Eigen
extension adds -std=c++17 -DEIGEN_MPL2_ONLY -DEIGEN_DONT_PARALLELIZE;
MinGW links with -Wl,--no-insert-timestamp (a rebuild of unchanged
source gives the same extension bytes). The flags compiled in are part of
cache_key().
More: the installation guide (wheels, UMFPACK, building from source, checking the install) and the user guide (its parts 1, Install, and 8, UMFPACK's library).
The API
Every function below is njit(nogil=True, cache=True) unless marked
python-level. Input: CSC of an n x n matrix, data float64, indices
and indptr int32; b / out float64, 1-D, length n, C-contiguous;
B / OUT (n, k) C-contiguous.
ADDED in 0.2.0: the backend-neutral interface
| function | returns |
|---|---|
factorize(data, indices, indptr, n, backend, ordering) |
(handle, info) |
solve_into(handle, b, out) |
info (x written into out; no allocation on SuperLU / UMFPACK) |
solve_many_into(handle, B, OUT) |
info |
refactorize(handle, data) |
info (new values, the same pattern, the analysis kept) |
free(handle) |
info |
solve(data, indices, indptr, n, b, backend, ordering) |
(x, info) (factorize + solve_into + free) |
handle_info(handle) |
(n, nnz_L, nnz_U, backend_id, ordering_id, last_status, pivot_tolerance, info) |
Factors(data, indices, indptr, n, backend, ordering) |
python-level context manager: .solve(b), .refactorize(data), .free(); raises SparseNumbaError |
backends(), require(backend), is_eigen_available() |
python-level: the available backend ids; raise with an install hint; Eigen present |
explain(info), SparseNumbaError, SymbolConflictError |
python-level: a code in words; the exceptions |
cache_key() |
python-level: a string for the caller's own cache key (below) |
sparse_numba.symbols.TABLE, declared(name) |
the LLVM symbol table and its signatures, as data |
Backends: SUPERLU, UMFPACK, EIGEN_LU, EIGEN_LDLT. Orderings:
NATURAL, COLAMD, AMD, MMD_AT_PLUS_A. There is no default backend
and no default ordering: both are arguments of factorize.
import numpy as np
from numba import njit
import sparse_numba as sn
# a 3 x 3 CSC matrix
data = np.array([4.0, 1.0, 1.0, 4.0, 1.0, 1.0, 4.0])
indices = np.array([0, 1, 0, 1, 2, 1, 2], dtype=np.int32)
indptr = np.array([0, 2, 5, 7], dtype=np.int32)
n = 3
handle, info = sn.factorize(data, indices, indptr, n, sn.SUPERLU, sn.COLAMD)
assert info == 0, sn.explain(info)
@njit(nogil=True)
def many_solves(handle, rhs, out):
status = 0
for i in range(rhs.shape[0]):
status |= sn.solve_into(handle, rhs[i], out[i])
return status
rhs = np.random.rand(1000, n)
out = np.empty_like(rhs)
assert many_solves(handle, rhs, out) == 0
data2 = data * 1.5 # new values, the same pattern
assert sn.refactorize(handle, data2) == 0
assert sn.free(handle) == 0
The same with Eigen's SparseLU at AMD, or SimplicialLDLT on a symmetric
positive definite matrix: sn.factorize(..., sn.EIGEN_LU, sn.AMD),
sn.factorize(..., sn.EIGEN_LDLT, sn.AMD).
What each backend supports
"refused" = the call returns ORDERING_UNSUPPORTED or BAD_SHAPE by name,
never a silent fallback.
| SUPERLU | UMFPACK | EIGEN_LU | EIGEN_LDLT | |
|---|---|---|---|---|
| unsymmetric general | yes | yes | yes | refused (BAD_SHAPE) |
| symmetric positive definite | yes (as general) | yes (as general) | yes (as general) | yes (the only input) |
| NATURAL | yes (ColPerm NATURAL) | yes (UMFPACK_ORDERING_NONE; refused by a library without umfpack_version) | NaturalOrdering | refused |
| COLAMD | yes | yes (STRATEGY_UNSYMMETRIC) | COLAMDOrdering | refused |
| AMD | refused | yes (STRATEGY_SYMMETRIC) | AMDOrdering | yes (its only one) |
| MMD_AT_PLUS_A | yes | refused | refused | refused |
| refactorize on the same pattern | yes (SamePattern) | yes (numeric again) | yes (factorize after analyzePattern) | yes |
| several right-hand sides in one call | yes (dgstrs nrhs) | a loop per column | yes (a dense block) | yes |
| solve into a held out | yes | yes | yes | yes |
| what it needs at run time | the vendored DLLs (Windows) / the libraries bundled in the wheel (Linux) / Homebrew's (macOS) | the user's SuiteSparse | nothing (compiled in) | nothing (compiled in) |
| threads | single | single | single (EIGEN_DONT_PARALLELIZE) | single |
| handle_info's nnz_L / nnz_U | L (SCformat), U (NCformat) | Info[UMFPACK_LNZ], Info[UMFPACK_UNZ] | nnzL(), nnzU() | the strictly lower L; 0 |
| pivot tolerance (handle_info) | DiagPivotThresh (1.0) | 1.0 | 1.0 | 0.0 (no pivoting) |
Notes:
- EIGEN_LDLT checks that the PATTERN is symmetric (the stored entries,
explicit zeros among them), not the values; it reads the lower triangle.
An indefinite matrix is refused after the factorization:
SINGULAR(= 1) when an entry of D is <= 0. - A row index repeated inside one column: the Eigen backends sum the entries; UMFPACK refuses it (BACKEND_ERROR); SuperLU passes it to dgstrf as given.
- SINGULAR: SuperLU and UMFPACK return k > 0, the zero pivot's 1-based index; the Eigen backends return 1.
The status codes
info == 0 is success; info != 0 is failure (the 0.1.11 contract).
sparse_numba.errors names every code and explain(info) says it in
words; nothing is printed by any call.
| code | value |
|---|---|
| OK | 0 |
| BAD_DTYPE | -1 |
| BAD_SHAPE | -2 |
| BAD_INDPTR | -3 |
| BAD_INDEX | -4 |
| NOT_SQUARE | -5 |
| HANDLE_INVALID | -10 |
| HANDLE_FREED | -11 (a double free or a use after free) |
| HANDLE_WRONG_BACKEND | -12 |
| BACKEND_ABSENT | -20 |
| ORDERING_UNSUPPORTED | -21 |
| ALLOC_FAILED | -30 |
| BACKEND_ERROR | -31 (the backend's own status in handle_info's last_status) |
| SINGULAR | k > 0 |
The handle is an int64 registry index: the caller who factorized owns it and frees it; it is process-local (it never crosses processes).
KEPT from 0.1.11 (same names, signatures and return shapes)
superlu_solve_csc / _coo / _csr, superlu_factorize_csc / _coo / _csr,
superlu_solve_factored, superlu_free_factors, and the same umfpack_*
set; convert_coo_to_csc, convert_csr_to_csc, convert_coo_to_csr,
sparse_matvec_csr, validate_sparse_matrix, check_matrix_properties,
validate_csc_matrix; is_slu_available, is_umf_available. They are
thin shims over the interface above; SuperLU's give bit-identical
solutions to 0.1.11 (NATURAL ordering) on the same CPU and BLAS kernel
(OpenBLAS picks its kernel by CPU at run time; CI pins
OPENBLAS_CORETYPE=Haswell for this check). The values some codes carry
changed (the 0.2.0 release notes, docs/RELEASE_NOTES_0.2.0.md).
from sparse_numba import superlu_factorize_csc, superlu_solve_factored, superlu_free_factors
b = np.ones(n)
handle, info = superlu_factorize_csc(data, indices, indptr)
x, info = superlu_solve_factored(handle, b)
superlu_free_factors(handle)
DEPRECATED (kept through 0.2.x, removed at 0.3)
*_solve_factored(handle, b) -> (x, info) (allocates x) in favour of
solve_into; the *_factorize_* forms without an ordering in favour of
factorize(..., backend, ordering); *_free_factors in favour of free.
The deprecation is in the documentation only (njit functions do not warn).
The numba cache across processes
- Every function is
cache=True; the C entry points are registered with llvmlite under stable names (sparse_numba.symbols.TABLE) at import, so a cached caller loads in a new process without recompiling. - No cache file ships in a wheel (no
__pycache__,*.nbi,*.nbc). - A read-only install (site-packages not writable): numba writes its
cache where
NUMBA_CACHE_DIRpoints. - Upgrades: the symbol names are stable across releases; the contract
for a caller that caches its own compiled code is to fold
sparse_numba.cache_key()into its cache key (it names the version, the symbol table, each extension's sha256, the SuperLU / UMFPACK / Eigen versions and the compile flags). For example, a downstream DAE solver that keeps factorizations across steps records the key in its generated modules' manifest and regenerates them when it changes.
Performance: the comparison record
The numbers below are one run of tools/compare_record.py at tree cb0617e on one machine (its json record, holding every sample, sha256 ff2cc551f5347012b8aa88870be4b88afd36834445dde17f4d923364f51bf1fe; the record is kept with the development tree). Machine: Intel(R) Core(TM) Ultra 7 258V, 8 logical CPUs, Windows power plan Balanced; Python 3.11.9, numpy 2.4.6, numba 0.67.0; the wheel's build (-O3 -DNDEBUG, MinGW gcc 14.2.0). Single-threaded (OPENBLAS / OMP / MKL / NUMEXPR threads = 1; Eigen with EIGEN_DONT_PARALLELIZE). The protocol: per arm the factorization is the second of two calls, 7 repeats; the substitution is solve_into on a held out from a numba loop, 10,000 calls a repeat x 7 repeats; refactorize 100 calls x 7; a repeat's calls cut to fit 2 s (the actual N in the record); an arm whose first factorization takes over 0.5 s is run as a function test only (its solution checked, no timing). Every value is the median of the 7 repeats, in microseconds; min and max are in the record. Every arm's solution is within 1e-10 (relative, max norm) of the 0.1.11 SuperLU solution; SuperLU NATURAL's is bit-identical to it at every size (the same CPU and BLAS kernel).
The matrices: G, the unsymmetric chain matrix of a power-system model (n = 688 / 2068 / 6898 / 20698); S, its symmetric positive definite nodal reduction (n = 207 / 621 / 2070 / 6210). The same right-hand side every call.
Substitution (us per solve_into) against n
| arm | G n 688 | G n 2068 | G n 6898 | G n 20698 |
|---|---|---|---|---|
| 0.1.11 superlu_solve_factored (NATURAL) | 45.76 | 161.15 | 1138.73 | 3969.46 |
| SUPERLU.NATURAL | 36.09 | 141.69 | 1017.48 | 3935.80 |
| SUPERLU.COLAMD | 50.15 | 149.28 | 405.07 | 1425.87 |
| SUPERLU.MMD_AT_PLUS_A | 37.53 | 137.98 | 398.14 | 1529.57 |
| UMFPACK.NATURAL | 20.01 | 127.23 | 372.89 | 1575.99 |
| UMFPACK.COLAMD | 18.83 | 122.54 | 376.74 | 1552.94 |
| UMFPACK.AMD | 33.74 | 131.27 | 367.57 | 1330.19 |
| EIGEN_LU.NATURAL | 21.16 | 97.38 | 804.06 | 3739.60 |
| EIGEN_LU.COLAMD | 17.30 | 65.52 | 212.30 | 755.29 |
| EIGEN_LU.AMD | 59.09 | 540.57 | function-only | function-only |
| arm (on S) | S n 207 | S n 621 | S n 2070 | S n 6210 |
|---|---|---|---|---|
| EIGEN_LDLT.AMD | 2.69 | 9.52 | 30.61 | 108.76 |
| SUPERLU.COLAMD | 12.53 | 38.17 | 126.68 | 423.44 |
| EIGEN_LU.COLAMD | 8.32 | 22.62 | 73.16 | 251.75 |
Factorization and refactorization (us) against n
| arm | G n 688 | G n 2068 | G n 6898 | G n 20698 |
|---|---|---|---|---|
| 0.1.11 superlu_factorize_csc (NATURAL) | 641 / -- | 3363 / -- | 17766 / -- | 68961 / -- |
| SUPERLU.NATURAL | 514 / 742 | 2731 / 2426 | 13116 / 13635 | 61935 / 60793 |
| SUPERLU.COLAMD | 327 / 351 | 1114 / 1281 | 3541 / 2987 | 16450 / 10138 |
| SUPERLU.MMD_AT_PLUS_A | 457 / 281 | 1191 / 879 | 4391 / 3473 | 16470 / 13413 |
| UMFPACK.NATURAL | 699 / 456 | 2856 / 1530 | 13124 / 5589 | 95642 / 29681 |
| UMFPACK.COLAMD | 369 / 271 | 1285 / 960 | 5247 / 4286 | 18697 / 13265 |
| UMFPACK.AMD | 324 / 235 | 1080 / 823 | 4047 / 3536 | 15834 / 11110 |
| EIGEN_LU.NATURAL | 326 / 302 | 2293 / 2045 | 15699 / 13895 | 91095 / 91893 |
| EIGEN_LU.COLAMD | 268 / 135 | 829 / 566 | 4278 / 2788 | 12585 / 8437 |
| EIGEN_LU.AMD | 3716 / 3592 | 62310 / 63306 | function-only | function-only |
Each cell: factorize / refactorize (--: 0.1.11 has no refactorize). UMFPACK is the user's library (6.3.5, SuiteSparse built by MSYS2), loaded at run time.
The wrapper's overhead against n: sparse_numba / a C++ direct call
A C++ driver (tools/cpp_direct/direct_arms.cpp) calls the same SuperLU and Eigen builds directly -- the same DLLs, the extensions' own compile flags, the shims' options and template parameters, no sparse_numba in between -- in the same process, on the same matrix and right-hand side, under the same protocol. Each cell is the sparse_numba median divided by the direct-call median (1.000 = the same time). Single runs: the spread between repeats is in the record's min / max.
| substitution | n69 (G 688 / S 207) | n207 (G 2068 / S 621) | n690 (G 6898 / S 2070) | n2070 (G 20698 / S 6210) |
|---|---|---|---|---|
| SUPERLU.NATURAL.G | 0.969 | 1.006 | 0.974 | 0.920 |
| SUPERLU.COLAMD.G | 1.120 | 1.062 | 0.988 | 0.915 |
| SUPERLU.MMD_AT_PLUS_A.G | 0.933 | 0.977 | 0.980 | 0.941 |
| EIGEN_LU.NATURAL.G | 0.953 | 1.087 | 1.017 | 0.992 |
| EIGEN_LU.COLAMD.G | 1.015 | 1.098 | 0.961 | 0.980 |
| EIGEN_LU.AMD.G | 0.909 | 1.012 | function-only | function-only |
| EIGEN_LDLT.AMD.S | 1.021 | 1.083 | 1.123 | 1.060 |
| SUPERLU.COLAMD.S | 0.925 | 0.951 | 0.824 | 0.889 |
| EIGEN_LU.COLAMD.S | 1.105 | 1.060 | 1.129 | 1.052 |
| factorize | n69 (G 688 / S 207) | n207 (G 2068 / S 621) | n690 (G 6898 / S 2070) | n2070 (G 20698 / S 6210) |
|---|---|---|---|---|
| SUPERLU.NATURAL.G | 0.964 | 1.220 | 1.023 | 1.109 |
| SUPERLU.COLAMD.G | 0.941 | 0.798 | 0.919 | 1.234 |
| SUPERLU.MMD_AT_PLUS_A.G | 1.404 | 1.189 | 1.103 | 0.963 |
| EIGEN_LU.NATURAL.G | 1.094 | 0.816 | 0.953 | 0.931 |
| EIGEN_LU.COLAMD.G | 1.204 | 0.770 | 1.046 | 0.921 |
| EIGEN_LU.AMD.G | 1.049 | 1.603 | function-only | function-only |
| EIGEN_LDLT.AMD.S | 1.184 | 1.094 | 1.067 | 1.059 |
| SUPERLU.COLAMD.S | 0.948 | 0.969 | 0.990 | 0.928 |
| EIGEN_LU.COLAMD.S | 0.808 | 1.053 | 1.156 | 1.159 |
| refactorize | n69 (G 688 / S 207) | n207 (G 2068 / S 621) | n690 (G 6898 / S 2070) | n2070 (G 20698 / S 6210) |
|---|---|---|---|---|
| SUPERLU.NATURAL.G | 1.713 | 0.972 | 1.094 | 0.851 |
| SUPERLU.COLAMD.G | 1.285 | 1.538 | 1.017 | 0.975 |
| SUPERLU.MMD_AT_PLUS_A.G | 0.952 | 0.978 | 1.052 | 0.985 |
| EIGEN_LU.NATURAL.G | 0.969 | 1.026 | 0.960 | 0.991 |
| EIGEN_LU.COLAMD.G | 1.011 | 1.188 | 1.148 | 0.979 |
| EIGEN_LU.AMD.G | 1.007 | 0.901 | function-only | function-only |
| EIGEN_LDLT.AMD.S | 1.409 | 1.742 | 1.349 | 1.039 |
| SUPERLU.COLAMD.S | 2.167 | 0.902 | 0.901 | 1.090 |
| EIGEN_LU.COLAMD.S | 0.948 | 1.289 | 1.129 | 1.065 |
Column headers: the vehicle, then the n of G (the .G rows) and of S (the .S rows).
The direct-call arms' own medians, the substitution (us):
| direct arm | n69 (G 688 / S 207) | n207 (G 2068 / S 621) | n690 (G 6898 / S 2070) | n2070 (G 20698 / S 6210) |
|---|---|---|---|---|
| SUPERLU.NATURAL.G | 37.25 | 140.88 | 1044.71 | 4275.84 |
| SUPERLU.COLAMD.G | 44.76 | 140.53 | 409.84 | 1557.72 |
| SUPERLU.MMD_AT_PLUS_A.G | 40.24 | 141.22 | 406.38 | 1625.87 |
| EIGEN_LU.NATURAL.G | 22.21 | 89.61 | 790.64 | 3770.93 |
| EIGEN_LU.COLAMD.G | 17.04 | 59.67 | 221.02 | 770.65 |
| EIGEN_LU.AMD.G | 64.97 | 533.93 | function-only | function-only |
| EIGEN_LDLT.AMD.S | 2.64 | 8.79 | 27.26 | 102.64 |
| SUPERLU.COLAMD.S | 13.54 | 40.15 | 153.67 | 476.10 |
| EIGEN_LU.COLAMD.S | 7.52 | 21.34 | 64.78 | 239.35 |
Function-only by the 0.5 s rule: EIGEN_LU at AMD on G at n 6898 and 20698 (Eigen's AMDOrdering on the symmetrized pattern of the unsymmetric G; first factorizations 2.7 s and 39.5 s), on both sides.
Architecture
User code (@njit)
|
v
sparse_numba.api / the kept interface modules (njit, cache=True; numba
ExternalFunctions on stable LLVM symbol names)
|
v
Cython layer (cdef api entry points)
|
v
the shims: superlu_wrapper.c, umfpack_wrapper.c (the user's library loaded
at run time), eigen_wrapper.cpp; one handle registry per backend
|
v
SuperLU 7.0.0 + OpenBLAS (vendored on Windows) / Eigen 3.4.0 (compiled
in) / the user's UMFPACK
Every layer releases the GIL.
Licences
sparse_numba is BSD 3-Clause. The components it ships or compiles in (docs/LICENSE_AUDIT.md holds each one's version, licence file and sha256):
| component | licence | how it ships |
|---|---|---|
| SuperLU 7.0.0 | BSD 3-Clause | Windows wheel: libsuperlu-7.dll, its licence beside it |
| OpenBLAS 0.3.29 (with reference LAPACK) | BSD 3-Clause | Windows wheel: libopenblas.dll, its licences beside it |
| GCC 14.2.0 runtime (libgcc_s_seh-1, libgomp-1, libgfortran-5) | GPL-3.0+ with the GCC Runtime Library Exception | Windows wheel, the licence files beside them |
| libquadmath-0 (GCC 14.2.0) | LGPL-2.1+ | Windows wheel, unmodified and replaceable, its licence text beside it |
| mingw-w64 winpthreads | MIT / BSD | Windows wheel, its licence beside it |
| SuperLU 5.x (AlmaLinux 8) | BSD 3-Clause | Linux wheels: sparse_numba.libs/libsuperlu-*, its licence in sparse_numba/third_party_licenses/linux/superlu/ |
| OpenBLAS 0.3.15 (AlmaLinux 8) | BSD 3-Clause | Linux wheels: sparse_numba.libs/libopenblas-*, its licence in .../linux/openblas/ |
| ATLAS 3.10 (libsatlas; SuperLU's BLAS on AlmaLinux 8) | BSD-style | Linux wheels: sparse_numba.libs/libsatlas-*, its licence in .../linux/atlas/ |
| GCC runtime (libgfortran, AlmaLinux 8's) | GPL-3.0+ with the GCC Runtime Library Exception | Linux wheels, the licence files in .../linux/libgfortran/ |
| libquadmath (GCC, AlmaLinux 8's) | LGPL-2.1+ | Linux wheels, unmodified and replaceable, its licence text in .../linux/libquadmath/ |
| Eigen 3.4.0 | MPL-2.0 (compiled with -DEIGEN_MPL2_ONLY) |
compiled into the Eigen extension; the source form at https://eigen.tuxfamily.org and in this repository's third_party/eigen-3.4.0 |
| SuiteSparse (UMFPACK, CHOLMOD, ...) | GPL / LGPL | not shipped: interface-only, the user's library |
On macOS SuperLU and OpenBLAS are Homebrew's, loaded at run time; the macOS wheels bundle nothing. CI reads every wheel's own listing (tests/test_sn6_wheel.py): each library a Linux wheel bundles must have its licence text in the wheel.
Citation
@software{hong2025sparse_numba,
author = {Hong, Tianqi},
title = {Sparse_Numba: A Numba-Compatible Sparse Solver},
year = {2025},
publisher = {GitHub},
url = {https://github.com/th1275/sparse_numba}
}
Release process
- Set the version in
setup.py,setup.cfgandsparse_numba/__init__.py(cache_key()readssparse_numba.__version__). - Open a pull request to main: CI builds one wheel per Python (cp310 - cp313) on Windows, manylinux x86_64 and macOS arm64 and tests each on its own Python (on Windows the full test suite from the wheel, with no UMFPACK library on the runner, and the wheel's contents; on Linux and macOS the import check and the wheel's contents); no wheel may carry a SuiteSparse library; no upload.
- When CI is green, merge, tag the merge commit
vX.Y.Zand push the tag: theupload_pypijob builds from the tagged tree and publishes the wheels and the sdist (trusted publishing). - A failed tag push before
upload_pypiran: delete the tag, fix, re-tag. A version uploaded to PyPI is never re-uploaded: bump the version.
Contributing
Contributions are welcome. Please open an issue or pull request on GitHub.
Metadata
Release files for sparse-numba 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sparse_numba-0.2.0.tar.gz | 18.2 MB | With provenance | Details |
Built distributions (wheels)
Total release size: 156.7 MB
Release files / sparse_numba-0.2.0.tar.gz
| Download URL | sparse_numba-0.2.0.tar.gz |
|---|---|
| Size | 18.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
858266cc60d84cd6f3c503da3c6efb665453a8442c92269c122337b980b520bb
|
|
BLAKE2b-256 checksum How to use checksums |
a0c6762f4316e2040890397750da329367929827fd12dce543bbe2dad5d97a52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp313-cp313-win_amd64.whl
| Download URL | sparse_numba-0.2.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 17.3 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
cdb75a3a95b3a0be566fcc7217952a74011577adfa36e21e4653da9f5904ac37
|
|
BLAKE2b-256 checksum How to use checksums |
c04ebba0dca26c8e67f9a0ec9c7d929d30150e80aace46a0537c98eb5248ae8c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | sparse_numba-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 17.1 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
579db27d35d1abee373aab8288635a82b56cccf19cbf590d0ca3536002b769b2
|
|
BLAKE2b-256 checksum How to use checksums |
b0fae644628bdab5e2aff4987af4d898c2bcc10b6a37692b3461ea5d50d3fa99
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp313-cp313-macosx_14_0_arm64.whl
| Download URL | sparse_numba-0.2.0-cp313-cp313-macosx_14_0_arm64.whl |
|---|---|
| Size | 200.3 kB |
| Tags | CPython 3.13 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
79bab3a9180e3bfa08988ea885a4fad9f0061de7b3f0c057b66195628c349099
|
|
BLAKE2b-256 checksum How to use checksums |
5335f73b42d13486e154ae207fb85ddbf9c5a42463753a6d3e6f3495575c757d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp312-cp312-win_amd64.whl
| Download URL | sparse_numba-0.2.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 17.3 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b4cb7081e3ac0dc4ae99fc4abe4edd7f4bbb6aa4369ad85deaaea0794b1558fe
|
|
BLAKE2b-256 checksum How to use checksums |
0ac514f718f1de2c92a8434f0a327e5f188373826448e38347d42897d5babb8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | sparse_numba-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 17.1 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
5fb6408da23d6eca844d6cba74b7f520887e06ea52f16ca43b13ec03505e0ae8
|
|
BLAKE2b-256 checksum How to use checksums |
a983f76da31431e8b9f668625d5404cd1cb56fd76acf582d28e2dcca8a641ea3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp312-cp312-macosx_14_0_arm64.whl
| Download URL | sparse_numba-0.2.0-cp312-cp312-macosx_14_0_arm64.whl |
|---|---|
| Size | 200.2 kB |
| Tags | CPython 3.12 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
560379178cff5ce02f361a40ee6f5544f73ff43592a8ee12ea2b97e4d19f8797
|
|
BLAKE2b-256 checksum How to use checksums |
f3ec86cedd17884a1b166153896c5038f6dde73e1e0411926352058e1f9be728
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp311-cp311-win_amd64.whl
| Download URL | sparse_numba-0.2.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 17.3 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
46747265f96cbc7b63a0fec3d0a845ae291b323c0444ba74d4eeb97af9d06688
|
|
BLAKE2b-256 checksum How to use checksums |
abb75a7b3022d919d9fe9ee269651e2373ce5822a040ff50028402f284c50368
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | sparse_numba-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 17.1 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
b0ab2877944ee409bae49429058c541e2030e4fe3f94186bb5f47bfa57336974
|
|
BLAKE2b-256 checksum How to use checksums |
ca165970be16d774fa46a98fdfee8be79e7849e359ee805c690074af1e373c87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | sparse_numba-0.2.0-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 199.5 kB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7d0a09d08ae4440ee07029bf7764eed18401df55cdbdede18a5ecfe72c393df3
|
|
BLAKE2b-256 checksum How to use checksums |
e85f563ca0e9aeb8fd49f9f4eb0c7af011e98c0aa8e55cce3ca78a2fbe73172b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp310-cp310-win_amd64.whl
| Download URL | sparse_numba-0.2.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 17.3 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
9d45efee3b28054f1820877d1c58cde2d9765d3c9c1c62f49200028e872dde2a
|
|
BLAKE2b-256 checksum How to use checksums |
4f4948a85e647db8eaf88b82a0ef7a82ab82f257c455f31620dbd2f817c30777
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | sparse_numba-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 17.1 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
01212685dd1ebeabd8841752cb3290f5dc18cb4495cd7e8c3ae83f896530ec09
|
|
BLAKE2b-256 checksum How to use checksums |
c8ade64990ffb39d7470c71fd05eeca1d5745218e45510380f53b8d97091423c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / sparse_numba-0.2.0-cp310-cp310-macosx_14_0_arm64.whl
| Download URL | sparse_numba-0.2.0-cp310-cp310-macosx_14_0_arm64.whl |
|---|---|
| Size | 199.9 kB |
| Tags | CPython 3.10 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8b06341a79f6acbb786a06da23e6e21b427514fa34cec6a69cbab56faa428227
|
|
BLAKE2b-256 checksum How to use checksums |
186d436deef98233fa05fb1fe9ad46a83bb03df15ea62fb38357f7599347dc4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for sparse-numba 0.2.0
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.
Full provenance
All 13 files in this release have been uploaded with provenance metadata.
Attestation for sparse_numba-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA 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.