dolfinx-solver
DOLFINx (FEniCSx) packaged as a Linux binary wheel, with a real-scalar PETSc and SLEPc inside the wheel — the piece upstream's own experimental wheels leave out.
pip install dolfinx-solver-real # the real-scalar build, named directly
pip install dolfinx-solver # the complex build, via the meta-package
import dolfinx_solver # noqa: F401 - orders MPI ahead of the bindings
import dolfinx
from petsc4py import PETSc
assert PETSc.ScalarType.__name__ == "float64"
Import dolfinx_solver before dolfinx, petsc4py or slepc4py.
That import loads mpi4py.MPI first, so every later binding binds to the
libmpi.so.12 mpi4py loaded, and it fails with an explanation if a foreign
petsc4py would shadow the vendored one.
What is in the wheel
DOLFINx's C++ core and nanobind bindings, real-scalar PETSc and SLEPc with
petsc4py and slepc4py built against exactly those, and the vendored native
stack (HDF5-parallel, SuperLU_DIST, MUMPS, PT-SCOTCH, OpenBLAS, ADIOS2 and
friends). fenics-basix, fenics-ffcx and fenics-ufl come from PyPI at
upstream's own pins — they are never re-vendored.
MPI is not vendored: the wheel depends on the PyPI
mpich wheel and carries only MPICH's
Fortran and C++ binding libraries, which that wheel does not ship. DOLFINx,
mpi4py and petsc4py therefore all share one MPI in one process.
Requirements and constraints
- Linux x86_64,
manylinux_2_34, Python 3.12+ (onecp312-abi3wheel). - The PyPI
mpichwheel, 5.0 series (installed for you). The wheel vendors MPICH's binding libraries built against that series, so neither an oldermpichnor another MPI — Open MPI, Intel MPI — will do. - A virtual-environment-style prefix; install into an environment of its own.
- Do not co-install the PyPI
petsc,petsc4py,slepcorslepc4pyprojects — they would put a second PETSc in the process. - Install one scalar variant, never both: the two wheels are the same payload at the same paths, so together they overwrite each other's files. The import refuses that environment rather than running whichever one landed second.
The complex-scalar build is published separately as dolfinx-solver-complex, and
is what pip install dolfinx-solver resolves to; PETSc's scalar type is baked
into the binaries, so it cannot be switched at runtime.
Versioning
The version mirrors the DOLFINx release the wheel ships, and the .postN
segment moves forward for packaging-only fixes:
dolfinx_solver.__version__ is the single source, DOLFINX_VERSION names the
upstream tag it builds.
Development
pip install -e '.[dev]'
ruff check . && ruff format --check .
mypy dolfinx_solver wheelbuild wheeltest
pytest
wheelbuild/ holds the build drivers and ships in no wheel; scripts/ drives
the manylinux container build.
Testing a built wheel
wheeltest/ is the suite that proves a finished wheel from outside the build:
it installs it into a clean venv and puts five stages to it. Point it at a
wheelhouse — scripts/build-in-container.sh leaves one in
.build-cache-<variant> —
and run the whole thing, or one stage at a time:
scripts/test-wheel.sh # every stage, one venv
scripts/wheel-test.sh # install, import order, foreign petsc4py
scripts/smoke-test.sh # the variant's problem and an eigensolve
scripts/interop-test.sh # mpiexec -n 2, one shared communicator
scripts/demo-test.sh # five upstream DOLFINx demos
PYTHON picks the interpreter the clean venv is made from (the wheel is abi3
and has to work on 3.12, 3.13 and 3.14, and that interpreter needs nothing
installed in it), WHEELHOUSE the directory holding the wheel, and
DEMO_SOURCE a DOLFINx source tree to take the demos from instead of
downloading the pinned release. The suite itself runs under DRIVER_PYTHON,
which is the environment the dev extras are installed in.
Troubleshooting
import dolfinx dies immediately, with UCX errors naming an ib or mana
device. Something like:
ib_iface.c:1316 UCX ERROR mana_0: ... failed: Operation not supported
MPICH chooses its transport through UCX when MPI initialises, which for this wheel is the import itself. UCX looks at what the host exposes, and some hosts expose an RDMA device a guest is not permitted to open — Azure's MANA card is one, and a machine with it can kill the import before a single message has been sent. It is not specific to running in parallel: a single-process script that never calls MPI initialises it just the same.
Name the transports instead of letting UCX discover them:
export UCX_TLS=self,sm,tcp
Shared memory, the intra-process transport and TCP are everything a
single-machine run needs, in serial or under mpiexec -n N. The wheel's own
test suite sets exactly this.
On a cluster with working InfiniBand, do not set it. There UCX finding the card is the point, and naming TCP would be slower for no reason. That case is untested: nothing in this project has ever run on a machine with a working fabric, so the high-speed path is expected to work rather than known to.
Releasing
A v* tag publishes three distributions from one workflow run: the two binary
variants it just built and tested, and the bare dolfinx-solver
meta-package, built in the publish job from meta/. They go up together —
dolfinx-solver-real cannot be added to a release afterwards under the same
version, and the meta-package pins its variant exactly — so the gather step
refuses a set that is not all three at dolfinx_solver.__version__:
python -m wheelbuild.publish --wheelhouse wheelhouse --outdir dist
Each publish job runs that same gather over the whole release and then stages
only its own part with --for, because the upload publishes every file in the
directory it is given. A job that verified only its own distribution would
cheerfully upload half a release that can never be completed.
Uploading uses PyPI trusted publishing: an OIDC token minted for each publish job, no API token stored anywhere.
One publish job per distribution, each with its own environment. That is not a style choice. A pending publisher — the kind that registers a project PyPI does not have yet — is identified by the claims in the OIDC token, which carry the repository, the workflow and the environment but never the project name. Three projects published from one repository, one workflow and one environment are three identical configurations, and PyPI refuses the second with "a pending trusted publisher matching this configuration has already been registered for a different project name". The environment is the field left to tell them apart.
Register these three at https://pypi.org/manage/account/publishing/, owner
benvial, repository dolfinx-solver, workflow wheels.yml:
| PyPI project | Environment |
|---|---|
dolfinx-solver-complex |
release-complex |
dolfinx-solver-real |
release-real |
dolfinx-solver |
release-meta |
wheelbuild.publish.ENVIRONMENTS is where those names live, and the workflow
is asserted against it — so the file and the form cannot drift apart.
The matching GitHub environments already exist on the repository. They carry no required reviewer; adding one to any of them is what makes that upload pause for a human, which is worth considering given PyPI never reuses a filename.
Nothing can be verified before the fact: PyPI has no API for reading publishers back, and it does not check that the environments or the workflow exist. The first tag is the test.
The tag is checked against the packaged version in seconds, in the checks job, long before the build:
git tag v$(python -c 'import dolfinx_solver; print(dolfinx_solver.__version__)')
After the upload, the published job installs the release the way a stranger
does — pip install dolfinx-solver on a machine that compiled nothing — and
puts three things to it: the meta-package resolves to
dolfinx-solver-complex, that wheel solves the numerical smoke problem, and
the refusals name the distribution pip recorded rather than the name that was
typed. It can also be run by hand against an index:
python -m wheeltest.published --index pypi --work-dir /tmp/published
License
LGPL-3.0-or-later, matching DOLFINx. The wheel carries a THIRD-PARTY-NOTICES
file with the license text of every vendored component.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dolfinx_solver_real-0.11.0.post0-cp312-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: dolfinx_solver_real-0.11.0.post0-cp312-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 58.4 MB
- Tags: CPython 3.12+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff7446d71a9981995bfb334ff7389fb81bd1df7639cd6c6b4af4d2678fcffaba
|
|
| MD5 |
7252e50061d00db46cba8cf773809ab5
|
|
| BLAKE2b-256 |
1d3706fd8a5f4d05cc0cabc18edb56e7d324e4c7fca07d22d3d3455d76d6f986
|
Provenance
The following attestation bundles were made for dolfinx_solver_real-0.11.0.post0-cp312-abi3-manylinux_2_34_x86_64.whl:
Publisher:
wheels.yml on benvial/dolfinx-solver
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dolfinx_solver_real-0.11.0.post0-cp312-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
ff7446d71a9981995bfb334ff7389fb81bd1df7639cd6c6b4af4d2678fcffaba - Sigstore transparency entry: 2821530827
- Sigstore integration time:
-
Permalink:
benvial/dolfinx-solver@1f6110ed65d7fcf6ee20999d4468be72aba57633 -
Branch / Tag:
refs/tags/v0.11.0.post0 - Owner: https://github.com/benvial
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@1f6110ed65d7fcf6ee20999d4468be72aba57633 -
Trigger Event:
push
-
Statement type: