PyMatching
PyMatching is a high-performance Python package for decoding quantum error correcting codes using minimum-weight perfect matching algorithms. It provides an efficient C++ implementation of the blossom algorithm, significantly speeding up decoding for large codes. The library is actively maintained with frequent minor releases for bug fixes and feature additions, and major updates approximately every 1-2 years introducing significant architectural changes or performance improvements. The current version is 2.3.1.
Common errors
-
ModuleNotFoundError: No module named 'pymatching'
cause The pymatching package is not installed or not accessible in the current Python environment.fixInstall the package using pip: `pip install pymatching` -
AttributeError: 'Matching' object has no attribute 'load_from_retworkx'
cause You are using a PyMatching version (>=2.2.0) where `retworkx` methods have been deprecated/removed, and replaced by `rustworkx` methods.fixChange your code to use `matching.load_from_rustworkx()` or `matching.to_rustworkx()`. Ensure `rustworkx` is installed (`pip install rustworkx`). -
TypeError: Input matrix must be a scipy.sparse matrix, a networkx.Graph, or rustworkx.PyGraph.
cause The input provided when constructing `pymatching.Matching(graph)` is not in a supported format (e.g., a dense NumPy array or an incorrect object type).fixConvert your graph representation to a `scipy.sparse` matrix (e.g., `scipy.sparse.csc_matrix`), `networkx.Graph`, or `rustworkx.PyGraph` before passing it to the `Matching` constructor. -
Segmentation fault (core dumped)
cause When using the correlated matching feature, a bug in PyMatching v2.3.0 could lead to a segfault for specific circuits.fixUpgrade PyMatching to v2.3.1 or later. This bug was specifically addressed and fixed in that release.
Warnings
- breaking PyMatching v2.0.0 introduced a complete rewrite of the C++ extension, including a new implementation of the blossom algorithm. This resulted in significant performance improvements (100-1000x faster) and the decoding is now exact, unlike the 'local matching' approximation used in v0.7 and earlier. Code written for v0.x might need adjustments if it relied on internal approximations or specific performance characteristics.
- deprecated The `retworkx` package and its related methods (`Matching.load_from_retworkx`, `Matching.to_retworkx`) were deprecated in v2.2.0 due to `retworkx` being renamed to `rustworkx`. While they may still function for a time, they will eventually be removed.
- gotcha PyMatching v2.2.1 temporarily pinned the `numpy` dependency to `numpy==1.*` due to incompatibility with `numpy` v2.0.0. Full support for `numpy` v2 was re-added in PyMatching v2.2.2. Users attempting to install PyMatching with `numpy` v2.0.0 or later on PyMatching versions between 2.2.1 and 2.2.2 might encounter installation errors or runtime issues.
- gotcha For decoding multiple shots (batches of syndromes), `Matching.decode_batch` is significantly faster than iterating in Python and calling `Matching.decode` for each individual shot. This is especially true for smaller/easier decoding problems.
- gotcha The correlated matching feature, introduced in PyMatching v2.3.0, had a couple of minor bugs that could lead to a segmentation fault for certain circuits or incorrect reweights in rare cases. These were fixed in v2.3.1.
Install
-
pip install pymatching
Imports
- Matching
from pymatching import Matching
Quickstart
import pymatching
import numpy as np
import scipy.sparse
# Example: Parity check matrix (H) for a simple [3,1,2] repetition code
# This H matrix represents two stabilizers: qubit0^qubit1 and qubit1^qubit2
H = scipy.sparse.csc_matrix(np.array([
[1, 1, 0],
[0, 1, 1]
]))
# Initialize the Matching object from the parity check matrix
matching = pymatching.Matching(H)
# Simulate a syndrome measurement (e.g., after an error on qubit 1)
# An error on qubit 1 flips both stabilizers (syndrome = [1, 1])
syndrome = np.array([1, 1])
# Decode the syndrome to find the most likely error pattern
# The result 'correction' is a binary vector indicating the predicted error locations
correction = matching.decode(syndrome)
print(f"Input syndrome: {syndrome}")
print(f"Predicted error pattern: {correction}")
# Expected output for syndrome [1,1]: [0, 1, 0] (error on qubit 1)