PyScotch
WARNING: this is a vibe-engineering experiment - you probably shouldn't use this!
Python ctypes wrapper for the PT-Scotch graph partitioning library: graph/mesh partitioning, sparse matrix ordering, coloring, and distributed (MPI) graph operations.
📖 If you want to use PyScotch, start at the documentation site: c4ffein.github.io/pyscotch — tutorials covering installation, every workflow, parallel/MPI usage, and reproducibility, with runnable (CI-tested) examples. This README is the developer-facing map of the repository.
Installation (short version)
pip install pyscotch # wheels bundle sequential Scotch, 32- and 64-bit ints
pip install "pyscotch[interop]" # + scipy/networkx conversion helpers
Wheels can't ship MPI. For PT-Scotch (Dgraph), compile a parallel Scotch
through the CLI — no root, checksum-pinned source from upstream, with any
needed build quickfixes applied automatically:
pip install "pyscotch[parallel]" # + mpi4py
pyscotch scotch build --parallel --use
PYSCOTCH_PARALLEL=1 pyscotch doctor # verify the full parallel stack
When anything misbehaves, pyscotch doctor reports which Scotch loaded (and
from where), its capabilities, and the exact command that fixes what's
missing. Details, system/conda Scotch, and troubleshooting: see
Installing PyScotch.
Quick Taste
from pyscotch import Graph
graph = Graph.from_edges([(0, 1), (1, 2), (2, 3), (3, 0)])
parts = graph.partition(2) # numpy array of part indices
permtab, peritab = graph.order() # nested-dissection ordering
There's also a CLI: pyscotch partition/order/check/info, pyscotch doctor,
and pyscotch scotch build/list/use/rm/patches for managing local Scotch
builds.
Features
- Graph partitioning — sequential and distributed (MPI)
- Mesh partitioning — with mesh-to-graph conversion
- Sparse matrix ordering — nested dissection for reduced fill-in
- Graph coloring — greedy heuristic coloring
- Distributed graph operations — coarsening, growing, band extraction, redistribution, induced subgraphs
- Safe strategy strings —
Strategy(string)is validated against the live library's own parsers at construction (Scotch's grammar accepts silently-do-nothing strings; PyScotch refuses them), plus a typed builder (pyscotch.strategy_grammar) that makes the degenerate forms unrepresentable - Reproducibility, Scotch's way — explicit
random_reset()/random_seed()mirroring the C API, no implicit PRNG resets; under deterministic settings PyScotch's partitions are byte-identical to Scotch's owngpart - Managed Scotch builds —
pyscotch scotch builddownloads, patches (when upstream needs it), compiles, and selects local libraries; wheels, system, conda, and dev builds coexist - Multi-variant loading — 32/64-bit integer builds with
_32/_64symbol suffixes, sequential and parallel - No hard mpi4py dependency — bundled lightweight MPI ctypes wrapper (mpi4py supported and recommended for real MPI apps)
Configuration
Environment variables, read at import time:
| Variable | Values | Default | Description |
|---|---|---|---|
PYSCOTCH_INT_SIZE |
32, 64 |
64 |
Size of SCOTCH_Num integers |
PYSCOTCH_PARALLEL |
0, 1 |
0 |
Load PT-Scotch (parallel) or Scotch (sequential) |
PYSCOTCH_LIB_DIR |
path | unset | Explicit directory containing the Scotch libraries |
PYSCOTCH_SYSTEM |
0, 1 |
0 |
Force the system-installed Scotch (distro/conda packages) |
Library discovery order on import pyscotch:
PYSCOTCH_SYSTEM=1— skip straight to the system ScotchPYSCOTCH_LIB_DIR— explicit override- The managed build selected with
pyscotch scotch use(under~/.local/share/pyscotch, override withPYSCOTCH_HOME) - Libraries bundled inside the installed wheel (
pyscotch/_libs/) scotch-builds/next to the repo (development layout)- Fallback: system-installed Scotch (dlopen by soname; unsuffixed symbols, single width — verified via
SCOTCH_numSizeof(), with a mismatch refused at load)
Development Setup
git clone https://github.com/c4ffein/pyscotch.git
cd pyscotch
git submodule update --init --recursive
make build-all
uv pip install -e ".[dev]"
Prerequisites: GCC or Clang, Make, flex ≥ 2.6.4, bison, zlib headers, and an MPI implementation (OpenMPI or MPICH) for the parallel variants.
The Scotch submodule lives on
gitlab.inria.fr; if the submodule step fails, check that your environment can reach that host. Builds never compile the submodule in place —makeprepares a disposable, quickfix- patched copy underbuild/scotch-src/(viapyscotch scotch prepare), so the submodule stays pristine.
make build-all compiles 4 Scotch variants into scotch-builds/:
| Directory | Contents |
|---|---|
lib32/, lib64/ |
Sequential + parallel libraries, 32/64-bit SCOTCH_Num |
inc32/, inc64/ |
Matching headers |
plus libpyscotch_compat, a small C shim giving Scotch FILE*s opened by
the same C runtime it was compiled against.
Testing
make test # default: 64-bit parallel, no hypothesis
make test-full # full suite including hypothesis
make test-quadrant # all 4 variants (32/64 × seq/par) with hypothesis
| Tier | What it proves |
|---|---|
tests/scotch_ports/, tests/scotch_ports_mpi/ |
Direct ports of Scotch's C tests (MPI ones run via mpirun) |
tests/pyscotch_base/ |
PyScotch-specific: API completeness, int sizes, symbol prefixes, strategy structure |
tests/hypothesis/ |
Property-based tests — stronger validation than Scotch's own C tests |
tests/pyscotch_integration/ |
End-to-end orchestrated workflows |
tests/golden/ + scripts/golden_walkthrough.py |
Golden master: the full sdist user journey, byte-for-byte |
tests/pyscotch_base/test_differential.py + tests/scotch_ports_mpi/test_differential_parallel.py |
Differential: byte-identity with Scotch's own gpart/gord/gmap (and dgpart/dgord under mpirun); opt-in via PYSCOTCH_G*/PYSCOTCH_DG*, all wired by make test-differential |
docs/site/examples/ |
Every doc example runs as a test |
CI additionally builds Scotch from the upstream tarball through the CLI
(pre-release, from the repo: scotch-build.yml) and re-runs the same journey
against the published package (post-release, from PyPI: pypi-verify.yml).
Project Structure
pyscotch/
__init__.py # Public API exports
libscotch.py # ctypes bindings, library discovery/loading, type definitions
graph.py # Sequential graph operations
dgraph.py # Distributed graph operations (MPI)
mesh.py # Mesh operations
strategy.py # Strategy management + construction-time string validation
strategy_grammar.py # Typed builder for strategy strings
arch.py # Target architecture definitions
mapping.py # Mapping result container
ordering.py # Ordering result container
context.py # SCOTCH_Context (per-context options, private PRNG streams)
mpi.py # Minimal MPI wrapper (OpenMPI, MPICH, Intel MPI)
doctor.py # `pyscotch doctor` environment diagnostics
scotch_build.py # `pyscotch scotch` — download/patch/compile/manage Scotch builds
_store.py # Managed-build store (~/.local/share/pyscotch)
_scotch_patches/ # Bundled Scotch patches (quickfix + behavioral) and build config
api_decorators.py # @scotch_binding / @highlevel_api tracking
cli.py # Command-line interface
native/
file_compat.c # FILE* ABI compatibility layer
docs/site/ # Homegrown docs generator → c4ffein.github.io/pyscotch
external/
scotch/ # Scotch submodule (gitlab.inria.fr) — pristine, never built in place
How It Works
PyScotch uses ctypes to call Scotch's C functions directly. Key design decisions:
- Dynamic struct sizing via
SCOTCH_*Sizeof()— never hardcodes structure sizes - Symbol suffixes (
_32/_64) viaSCOTCH_NAME_SUFFIX— allows loading multiple variants - FILE* compatibility layer — a small C shim (
libpyscotch_compat) that opens files with the same C runtime Scotch was compiled against, avoiding ABI mismatches - Scotch stays the semantic authority — strategy strings, PRNG behavior, and defaults are Scotch's own; PyScotch validates and surfaces, never reinterprets
@scotch_bindingdecorators — track which C functions each Python method wraps, enabling automated API completeness checks
Versioning
PyScotch versions are X.Y.z, where X.Y mirrors the Scotch series it is
built and tested against (e.g. PyScotch 7.0.* supports Scotch 7.0.x) and
z counts PyScotch's own releases within that series. Pin accordingly,
e.g. pyscotch~=7.0.2. Use pyscotch.scotch_version() to check the Scotch
actually loaded at runtime.
License
MIT License. See LICENSE.
PT-Scotch itself is distributed under the CeCILL-C
license; the wheels bundle its libraries and the repository carries small patches
and a test graph from it — see LICENSES/.
Acknowledgments
Built on PT-Scotch by Francois Pellegrini and the Scotch team at INRIA Bordeaux.
Metadata
Release files for pyscotch 7.0.7
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 | |
|---|---|---|---|---|
| pyscotch-7.0.7.tar.gz | 112.1 kB | With provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyscotch-7.0.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| pyscotch-7.0.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 | Details |
Total release size: 1.6 MB
Release files / pyscotch-7.0.7.tar.gz
| Download URL | pyscotch-7.0.7.tar.gz |
|---|---|
| Size | 112.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
35a26a4e26ae1997b1c7fcf85b84ff3b70e95d8ca81ce214c46a322ae530f5b8
|
|
BLAKE2b-256 checksum How to use checksums |
3795e09c7dcdd200af56f26c5b7ead68bf1f4dbcbdec839af51dc1487c85de7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 14, 2026.
Transparency logRelease files / pyscotch-7.0.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pyscotch-7.0.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 766.4 kB |
| Tags | Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
21b6e99da755f763d467ca186b6ab21f19ec6ea83772507e2d3c320d1f28c87f
|
|
BLAKE2b-256 checksum How to use checksums |
211b4c83dea3c732d49221c31b2a723db78f58e8ce01d53a21525f1695551a9f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 14, 2026.
Transparency logRelease files / pyscotch-7.0.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pyscotch-7.0.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 762.0 kB |
| Tags | Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
0b6dc2165d9c95055eaec577930b3a9a9c61396817a81041e9940490219281c2
|
|
BLAKE2b-256 checksum How to use checksums |
b990d7c130533af30bd49916fe65cb25ecfbee2994f748a244eea0e825b1bca3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 14, 2026.
Transparency logSecurity for pyscotch 7.0.7
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 3 files in this release have been uploaded with provenance metadata.
Attestation for pyscotch-7.0.7.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 14, 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.