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_gpart.py |
Differential: byte-identity with Scotch's own gpart (opt-in via PYSCOTCH_GPART) |
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)
_patches/ # Bundled quickfix patches for upstream releases
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.
Acknowledgments
Built on PT-Scotch by Francois Pellegrini and the Scotch team at INRIA Bordeaux.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 pyscotch-7.0.3.tar.gz.
File metadata
- Download URL: pyscotch-7.0.3.tar.gz
- Upload date:
- Size: 209.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
316870a804d86572677ddc9a99ae03b0948f33023908839b80a5f6bfe7368093
|
|
| MD5 |
59bce1d187d7cfff5af1e63028ba5b9a
|
|
| BLAKE2b-256 |
bfbcd64a1d805894ff03edf9c0cd4571c1bc5b8f34309c229e6c1c03bcaa93c2
|
Provenance
The following attestation bundles were made for pyscotch-7.0.3.tar.gz:
Publisher:
wheels.yml on c4ffein/pyscotch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyscotch-7.0.3.tar.gz -
Subject digest:
316870a804d86572677ddc9a99ae03b0948f33023908839b80a5f6bfe7368093 - Sigstore transparency entry: 2391968160
- Sigstore integration time:
-
Permalink:
c4ffein/pyscotch@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Branch / Tag:
refs/tags/v7.0.3 - Owner: https://github.com/c4ffein
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyscotch-7.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyscotch-7.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 742.8 kB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
925af6ae7c74b045d90687e472939fa201fc48c27c03ffd4ae2bcf8d9f451ec6
|
|
| MD5 |
d485295c692c498d644e1009d2395fe2
|
|
| BLAKE2b-256 |
5d2269321b6b52091f6baa25c99d7a6451544e72deb86f74b0a12641f6005720
|
Provenance
The following attestation bundles were made for pyscotch-7.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
wheels.yml on c4ffein/pyscotch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyscotch-7.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
925af6ae7c74b045d90687e472939fa201fc48c27c03ffd4ae2bcf8d9f451ec6 - Sigstore transparency entry: 2391968239
- Sigstore integration time:
-
Permalink:
c4ffein/pyscotch@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Branch / Tag:
refs/tags/v7.0.3 - Owner: https://github.com/c4ffein
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyscotch-7.0.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pyscotch-7.0.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 738.2 kB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf14e8bd61c9e0b11d2846dd0e9927a2b24e06014a6bb33d5a014b6132178b84
|
|
| MD5 |
7827dc6b56b30a7ed9f601935db096d7
|
|
| BLAKE2b-256 |
b0d0200a53c00945db900601358def8c73e5b07c3c1563197543f1b027e34c3a
|
Provenance
The following attestation bundles were made for pyscotch-7.0.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
wheels.yml on c4ffein/pyscotch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyscotch-7.0.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
bf14e8bd61c9e0b11d2846dd0e9927a2b24e06014a6bb33d5a014b6132178b84 - Sigstore transparency entry: 2391968330
- Sigstore integration time:
-
Permalink:
c4ffein/pyscotch@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Branch / Tag:
refs/tags/v7.0.3 - Owner: https://github.com/c4ffein
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@1f999b401ec14c2e1f4afa19a3cd0abcb620f342 -
Trigger Event:
push
-
Statement type: