Dependencies#
Adding a dependency is a decision, not an implementation detail: propose it before adding
it (AGENTS.md). This page lists what is approved, why, and the candidates that could be
evaluated. Versions are lower bounds except where pinned; uv.lock is the resolution.
How a floor is chosen. A lower bound is a claim that solprop works with that
release, so it is the oldest release that (a) publishes CPython 3.14 wheels for Linux,
macOS and Windows and (b) provides every API solprop calls, unless a stricter reason is
recorded in the table. It is not the version that happened to be current. The oldest
CI job installs the package with uv pip install --resolution lowest-direct and runs
the default lane, so a floor that stops holding fails there. Raise a floor only for a
reason written here. The recorded states under tests/ are compared at a tolerance, not
pinned to a platform or a library build (testing.md section 5), so the floors
need no exception for them.
Core (always installed)#
package |
purpose |
notes |
|---|---|---|
solprop-native, at solprop’s own version |
the backend solprop runs on (SEP 43) |
below; no environment markers, so solprop’s supported platforms are the ones it installs on |
numpy ≥ 2.5 |
arrays |
the array type at every layer; the APIs used are NumPy 2.0’s ( |
scipy ≥ 1.18 |
|
root finding, special functions, interpolation and adaptive quadrature throughout; the newest API used is |
matplotlib ≥ 3.10.7 |
plotting |
earlier 3.10 releases call pyparsing APIs that current pyparsing deprecates, which the test suite’s warnings-as-errors refuses |
h5py ≥ 3.15 |
HDF5 output |
first release with 3.14 wheels on all three platforms |
optmat[gas] ≥ 0.9.1 |
built-in material models: gas dispersion, Kerr, equation of state and transport; solids; gas and silica Raman responses; gas ionisation rates (SEP 3) |
the same maintainers’ curated-data package; never imported at |
threadpoolctl ≥ 3.1 |
inspect and control the backend-owned BLAS pool |
pool provenance and limits are recorded per run |
jaxtyping ≥ 0.3.11 |
array annotations, evaluated at import time in every module |
pure Python; the checker (beartype) is dev-only; the floor dates from the removed |
tqdm ≥ 4.67 |
the progress bar ( |
pure Python; imported when the first bar is drawn, never at |
tomli-w ≥ 1.0 |
writes recipes as TOML ( |
pure Python, MIT-licensed, no dependencies of its own; |
Optional atomic-response engine#
Pyroraptor (pyroraptor) provides the helium atomic responses of the
TDSE response: the single-active-electron model of
SEP 12 and the haCC models of
SEP 20. It is not yet publicly available, so
solprop declares no dependency or extra for it, and imports it only when a TDSE response
is prepared; ordinary imports and non-TDSE runs never initialise its runtime. A missing
provider, an unsupported interpreter (the provider supports Python 3.14 only) or a
missing capability is refused with a BackendError.
solprop pins one provider source revision, solprop.driver.tdse._PROVIDER_REVISION
(currently 876b72d10b5286478125b842ea45548a5051b033);
the binding checks the installed provider against it, and the source identity and the
loaded native build identity are recorded separately with every run. A device build
(CUDA or HIP) is selected explicitly through TDSEExecution.device and checked against
the build’s execution space, with no fallback.
The Apple-GPU backend (mlx extra)#
MLX (mlx, MIT licence, compatible with GPL-3.0-or-later) is the optional extra of the
mlx backend (SEP 33), declared with the marker
sys_platform == "darwin" and platform_machine == "arm64" and pinned to a tested minor
version, mlx>=0.32.4,<0.33; the macOS floor is MLX’s wheels’. A pin is raised only in
a pull request that runs the GPU lane and the arithmetic probes (Q9). Nothing outside
solprop.backends.mlx_gpu imports it; availability is probed with
importlib.util.find_spec.
The native backend package#
solprop-native is the repository’s second distribution, built from native/ and a
required dependency of solprop. pyproject.toml lists the bare name, so uv resolves it to
the workspace member, and hatch_build.py writes solprop’s own version into the built
metadata as an exact pin. On a platform with no matching wheel the installer’s resolution
error is the answer, which the installation page
explains. Its
native build pins and fetches Kokkos 5.2.1, KokkosKernels 5.2.0 (BLAS component only) and
Kokkos-FFT 2.0.0 and uses nanobind. A local build (the default) links the system
Accelerate, oneAPI’s MKL or OpenBLAS through KokkosKernels, whichever it finds, and
neither fetches nor bundles a BLAS library. A distribution build
(SOLPROP_NATIVE_PROFILE=DISTRIBUTION, ADR-034) links Accelerate on macOS and, on Linux
and in the Windows wheel, OpenBLAS 0.3.34 built with OpenMP from its pinned, checksummed
source release and carried in the wheel; a Windows build without that library links the
scipy-openblas32 OpenBLAS from PyPI, a build requirement it copies into the wheel. The
release wheels also bundle FFTW 3.3.11 and their OpenMP runtime, built from pinned
sources by native/ci/ (Releasing and the native wheels). A reference
build links no BLAS. Its CUDA build uses the CUDA toolkit’s cuFFT and cuBLAS through Kokkos-FFT
and KokkosKernels, and its HIP build rocFFT and rocBLAS; it neither fetches nor bundles
device libraries. Both distributions resolve in the root workspace’s one uv.lock;
solprop-native has no runtime dependency on solprop.
SLEEF 3.9.0 (sleef.org, Boost Software License 1.0) is the
native CPU build’s host vector maths on x86-64 (ADR-059): vector exp, log and
sincos, its u10 functions (1.0 ulp over each function’s domain), called over blocks
by native/include/solprop_native/vmath.hpp. It is fetched at its release tag like
Kokkos (FETCHCONTENT_SOURCE_DIR_SLEEF names a local copy for an offline build), built
static as its own CMake project with only libsleef and the variants the layer calls
(SSE2, AVX2, AVX-512F on request; AdvSIMD on aarch64), and compiled into the extension, whose wheel
carries its licence as LICENSE-sleef.txt. Arm builds (Apple silicon, Linux aarch64)
and GPU builds use the system libm and do not fetch it; SOLPROP_NATIVE_VECTOR_MATH
overrides the choice. Its floor is the pinned release: it is never resolved from a
package index. Evaluated against glibc’s libmvec (2 ulp, and reachable from GCC only
through fast-math or hand-written vector declarations) and Intel’s MKL (faster on Intel
only, by at most 1.5 times, and a large dependency); see ADR-059.
The desktop front end (gui extra)#
solprop-gui is the repository’s third distribution, built from gui/ and installed
through solprop’s gui extra, which pins it to solprop’s own version; it pins solprop
the same way (the front end’s design, D2). Its own dependencies, beside
solprop’s:
package |
purpose |
notes |
|---|---|---|
PySide6-Essentials ≥ 6.10.1 |
Qt for Python: the window, widgets and docks (LGPL-3.0, compatible with GPL-3.0-or-later) |
6.10.1 is the first release whose wheels admit CPython 3.14 (6.10.0 declares |
pyqtgraph ≥ 0.14 |
the interactive plots (MIT) |
0.14 is the first release made after Qt 6.10 and CPython 3.14; 0.13.7 predates both and has not been tried, so the floor is lowered only with a lane that tests it |
Only solprop_gui.ui and solprop_gui.views import them. Its test plugin, pytest-qt ≥
4.5, is the dependency group gui-test, not part of dev: it refuses to start without a
Qt binding, which would stop every pytest run of an environment without the front end.
The gui CI job and uv sync --extra gui --group gui-test install both.
Development#
The benchmark controller uses psutil ≥ 7.1.0 for the CPU allocation, core
count, memory size and the busy-machine reading. This floor includes the macOS C
safety fixes and Windows ARM64 wheels recorded in the
upstream 7.1.0 changelog.
Collection records the installed version. Unsupported or sandbox-denied counters
remain unavailable with a reason; threadpoolctl supplies library-pool introspection.
psutil is a development dependency and does not enter the simulation API.
basedpyright (pinned exactly), scipy-stubs, beartype, sympy (the symbolic Marcatili
derivation in tests/data/, run by hand), pytest, pytest-xdist, pytest-randomly,
pytest-regressions, pytest-cov, hypothesis, poethepoet, pre-commit,
codespell, reuse (the per-file copyright and licence check of poe reuse), numpydoc, sphinx, myst-parser, pydata-sphinx-theme, sphinx-gallery, ruff, and
drawsvg (the structure figures of docs/dev/figures/build.py and the geometry figures of
docs/guide/figures/geometries.py only, run by hand with poe figures; the SVGs it
writes are committed, so the documentation builds without it).
Candidates (not approved; only evaluate for a selected use case)#
package |
for |
status |
|---|---|---|
rocket-fft |
transforms callable inside |
not needed; the shared march is Python (backends.md §3.5) |
mkl_fft |
Intel FFT on Linux nodes |
no evaluation planned |
jax |
array-compiler backend |
evaluated; not selected (ADR-002, backends.md §5) |
sphinx-design, sphinx-copybutton |
docs presentation |
no evaluation planned |
Rejected#
package |
why |
alternative |
|---|---|---|
refractiveindex |
A 9 KB shim that downloads an unversioned database to |
For glasses, crystals and metals: read the refractiveindex.info database offline, pinned to a database commit, with a generator script that writes provenance-tracked resources under |