QECTOR Decoder v3 enters its 1.x line. The public API contract is defined in
docs/STABLE_API.md; stable symbols are supported across
1.x, while optional GPU, network, and research interfaces remain provisional.
This release ships wheels only (no source distribution), supports CPython 3.9
through 3.13 on Windows x64, Linux x86_64, and macOS arm64, and includes the
Rust/Python decoder core, CLI, and interoperability entry points documented in
the README. See CHANGELOG.md for detailed technical history.
Patch release fixing three defects found by independent black-box verification of the published 0.7.0 wheel (120-test external suite, both license tiers, live MCP stdio probe, double-run, zero flaky):
- CLI
qector decodeno longer crashes.cli.pyimported the nonexistentBeliefMatchingDecoder; every invocation died withImportError. Also converts the loaded dense check matrix to adjacency form for graph decoders and builds the belief-matching decoder viaBeliefMatching.from_numpy_h. All seven--decoderchoices verified end-to-end. - MCP server implements
ping(empty-object result) — required by the protocol for client keepalive. - MCP server no longer responds to notifications. The spurious
{"id":null,"result":null}afternotifications/initializeddesynchronized strict in-order clients; notifications are now silent per JSON-RPC 2.0.
Published to PyPI. Note that src/*.rs is .gitignored, so
git log v0.6.9..HEAD shows none of the Rust work described here — the Rust
changes are verified by cargo test and by reading the tree, not by the commit
log.
Focus: usability at the edges — a CLI and a diagnostic, real ecosystem entry points, three new decoder families, weighted Union-Find on the GPU, and six crash-safety fixes in the Rust core.
qectorCLI withdecode,bench, andservesubcommands (python/qector_decoder_v3/cli.py, registered atpyproject.toml:128).qector-doctor— an environment diagnostic that reports 14 PASS / 1 WARN / 0 FAIL on a healthy Community-tier install and explains why a backend is unavailable, rather than surfacing it as a decode-time failure. Invoke it as a console script orpython -m: run as a bare script from inside its own package directory it puts the raw.pydonsys.path, shadows the__init__.pywrapper that supplies constructor defaults, and then misreportsnative-coreanddecodeas FAIL.- Sinter decoder entry points —
qector_blossom,qector_belief,qector_unionfind,qector_bposd,qector_unionfind_unweightedregistered under[project.entry-points.sinter_decoder], sosinter.collect()finds them without acustom_decoders=argument. - qiskit-qec plugin entry point under
[project.entry-points."qiskit.qec"]. from qector_decoder_v3.pymatching import Matching— the submodule spelling. The attribute form already worked; the module did not exist.
AmbiguityClusterDecoder(src/ambig_cluster.rs): BP, partition on|LLR|, DFS-cluster the ambiguous mechanisms, enumerate each cluster exactly.TwoStageDecoder(src/two_stage_decoder.rs): decode the X sector, propagate, decode the Z sector. Any of blossom / unionfind / bposd / sparse_blossom per stage. It needscheck_types— a DEM does not record which sector a detector belongs to.ColourCodeDecoder(python/qector_decoder_v3/colour_code.py): BP-OSD on the undecomposed hypergraph DEM. Matching is not a correct colour-code decoder — a colour-code mechanism can light three detectors and has no graphlike decomposition, and Stim'sdetector_error_model(decompose_errors=True)raises outright oncolor_code:memory_xyzatd ≥ 5.- Relay-BP (
BpMethod::Relayinsrc/bp_osd.rs): layered serial schedule, so each check sees the freshest messages.bp_method="relay"on bothBPOSDDecoderandBpOsdDecoder. - Weighted cluster growth on the GPU:
CUDABatchDecoderandOpenCLBatchDecodertake an optionaledge_weightsand run the same adaptive growth asuf_core::grow_weighted. Both kernels produce identical logical error rates — that agreement is the cross-check that the port is faithful. Omitting the weights keeps the original integer growth, bit-identical to the CPUUnionFindDecoder. DemModel.make_decodercovers all nine shipped families (it handled five);DemModel.DECODER_KINDSenumerates them.
Under panic = "abort" each of these killed the host process rather than raising
a catchable Python exception:
grpc_server.rs:316,325,354,369—decoder_cache.lock().unwrap()mutex-poison panic; now propagated viamap_err.cuda_bp_osd.rs:249,299— same pattern onworkspace.lock().cuda_batch.rs— every CUDA async error return was discarded withlet _ =, so corrupt corrections came back asOk. Thelet _ = cu_*count is now zero.cuda_workspace.rs:134—pointers()aborted the host; now returnsResult<_, String>. This is a signature change; every caller was updated.ler_benchmark.rs:266—Bernoulli::new(phys_error).unwrap()panicked on NaN or out-of-range input; now.ok()with the fall-through documented.cascade_decoder.rs:159—BPOSDDecoder::new(…).expect("invalid BP-OSD input")inside an infallible constructor.
HybridCascadeDecoderignored its edge weights. Weights reached the Blossom escalation decoder but not the Union-Find pre-filter — and the pre-filter accepts most circuit-level syndromes, so its unweighted answer is what callers received.- The CUDA BP-OSD kernel did not compile, so
CUDABpOsdDecodercould never be constructed. Every CUDA test treated construction failure as "no GPU here", so a hard compile error looked like a missing device. AutoRouterignoredpriority, andexplain()no longer describeddecode(). The native path bypassed the Python policy layer that enforces "never route a hyperedge code to a matching decoder".TwoStageDecoder.decodeandAmbiguityClusterDecoder.decodereturnedbyteswhile the other seven families return auint8ndarray.set_license_key()silently accepted invalid keys, surfacing later as an unexplained tier cap. It now raisesValueError.QECTOR_LICENSE_FILEand~/.qector/license.keywere never read, so a deployment pointed at a key file sat silently on Community tier.- Prometheus latency quantiles froze permanently until 8,192 samples had been recorded.
- Seven further logic defects fixed across
auto_decoder.rs,benchmark.rs,lookup_table.rs,neural_predecoder.rs,safetensors_loader.rs,cross_decoder_tests.rs,opencl_batch.rs.
- The four pre-v0.7.0 comparison tables in
README.mdare withdrawn. They compared code-capacity QECTOR against circuit-level PyMatching in one table, and cited artifacts under the.gitignoredbenchmark_results/path that no reader could obtain. See the README for the full notice. ler.assert_comparabletags every run with its noise model and refuses cross-model comparisons, so the error cannot recur silently.scripts/regenerate_benchmark_artifacts.pyrewritten: it previously had no argument parser, so any invocation — including--help— immediately launched a 1.6M-decode run. It now requires--yes, supports--dry-run, and embeds a provenance block (methodology, git commit, tree-dirty flag, parameters, dependency versions, caveats) in the artifact.- The
benchmarks_sessionharnesses are documented as not decoder performance measurements: they feed uniform-random bit patterns to a boundaryless ring code where ~49% of inputs have odd defect parity and admit no correction. That is why GPU paths previously appeared slower than CPU.
Measured 2026-07-31 on the working tree:
| Gate | Result |
|---|---|
cargo test --no-default-features |
303 passed, 0 failed |
cargo test --features full |
323 passed, 0 failed, 7 ignored (hardware-only) |
cargo clippy --no-default-features --all-targets -- -D warnings |
exit 0 |
cargo clippy --features full --all-targets -- -D warnings |
exit 0 |
| Full Python suite | no trustworthy baseline yet — the last full run was interrupted. Do not read a pytest pass rate into this release until one completes on a quiesced tree |
An earlier draft of this section claimed "cargo test 308 passed · pytest 100%
passed". Neither figure was reproducible: the Rust counts above are the measured
ones, and no complete Python run has been captured for 0.7.0. The claim is
withdrawn rather than corrected, since there is nothing yet to correct it to.
Focus: BP-OSD accuracy (exact log-domain BP, true OSD-1/2), belief-matching correctness, licence hardening.
BeliefMatching.from_numpy_hdecoders returned an empty array for every syndrome — zero observable rows meantdecodeproduced length-0 output with no error. Now returns a length-n_qubitscorrection withH @ corr == syndromeverified.verify_license_tokenraised on malformed input instead of returningFalse(binascii.Error/UnicodeDecodeErrorescaped the oldexcept RuntimeError). Nine adversarial inputs now locked by tests.- Blossom boundary bug: odd-defect boundary-less codes no longer panic.
- Stripe checkout no longer pins
payment_method_types=["card"], restoring Link/wallets/local payment methods.
- Exact log-domain sum-product BP (default;
bp_method="min_sum"opt-out) and true combination-sweep OSD-1/2 (osd_orderkwarg). GNNBeliefMatcher— GNN-guided MWPM pipeline with faithfulness fallback.- v2 licence tokens carrying
tier+expinside the Ed25519 signature; legacy tokens keep verifying;license_claims()exposes verified, unexpired claims. - Tuning env vars documented (
QECTOR_BLOSSOM_K_MULT,QECTOR_BLOSSOM_INTRA_PAR,QECTOR_BLOSSOM_INTRA_THREADS,QECTOR_CUDA_DEVICE_ID,QECTOR_OPENCL_DEVICE_ALLOW) — with which of them change results vs. only throughput. - Licensing notice now reaches non-interactive runs (one stderr message at import;
QECTOR_SILENT=1suppresses; silent when licensed; skipped in CI).
cargo test --lib 203 passed · clippy 0 warnings · pytest 1237 passed, 1 skipped, 0 failed · ruff check/format clean · captured under test-results/.
Focus: Hotfix for unimportable v0.6.7 wheel — guarded imports, CI smoke test, YAML fix.
- v0.6.7 was completely unimportable on all published wheels.
__init__.py:37unconditionally accessed_native_module.HybridCascadeDecoder, which does not exist in the current Rust build (symbol never registered in#[pymodule]). All 18 native-module lookups are now guarded by_guard("ClassName")— missing symbols return a callable stub that raisesRuntimeErroron instantiation.import qector_decoder_v3now always succeeds. - CI YAML syntax error: the smoke-test
run:step contained unindented Python code inside a literal block scalar, causing GitHub's parser to fail on the entire workflow file. This brokeworkflow_dispatch, tag-push triggers, and all CI runs silently (0 jobs,failureconclusion). Fixed by indenting the inline Python script to match the literal block's content level.
- CI smoke test:
releasejob now installs the built wheel, runsimport qector_decoder_v3, creates a code, and decodes beforetwine upload. This would have caught the v0.6.7 regression.
Focus: Self-auto-debug backend, offline licensing, and Stripe fulfillment.
- Self-Auto-Debug Backend:
AutoDecoderimplements a 7-tier fault-tolerant fallback engine (CUDA->OpenCL->CPU Rayon->CPU Batch->CPU Single->Blossom->Lookup Table) with automatic exception trapping, per-tier health scoring, and transparent recovery.reset_backend_health()restores suspended tiers. - Ed25519 Offline License Verification:
verify_license_token()validates signed license tokens fully offline against an embedded public key. Supports both legacy 2-part and self-contained 3-part (receipt_id.email_b64.sig_b64) token formats. Configurable viaQECTOR_LICENSEandQECTOR_SILENTenvironment variables. - Stripe Checkout & Webhook Fulfillment:
stripe_integration.pyandstripe_webhook_server.pyprovide end-to-end commercial license fulfillment - Checkout Session creation, webhook signature verification, and automatic Ed25519 token issuance on payment confirmation. Direct purchase link: Buy Commercial License. - DecoderPool LRU Caching: Added LRU pool caching for
get_decoder_poolindecoder_cache.py, preventing redundant process pool initialization across repeated multi-process decodes.
- Stripe Webhook Signature Verification: Enforced strict signature verification in
handle_stripe_webhook_payloadwhenever a webhook secret is set, preventing unauthenticated payload bypass. SparseBlossomDecoder::grow_regionsno longer collapses the compressed edge set - decoded syndromes are now bit-identical to the Blossom decoder.BPOSDDecoder.bp_decode_timedinitializes the wall-clock deadline before the iteration loop, so the latency budget is honored from the first iteration.- LER benchmark's rotated-surface generator now emits a proper two-half (X + Z) graphlike code.
_opencl_health_check()'s child-process probe script referenced an undefined_npname instead ofnp, causing a silentNameErrorthat always reportedopencl_is_available() == Falseregardless of hardware.
- Full test suite passing, including new
test_auto_debug_fallbacks.py,test_stripe_integration.py,test_stripe_zero_dollar_sale.py, andtest_release_import.py. - Wheels rebuilt for CPython 3.9-3.13 (win_amd64) and verified against a clean uninstall/reinstall.
- End-to-end $0 Stripe sale verified: checkout -> webhook -> Ed25519 issuance -> offline activation -> tamper rejection.
Focus: Critical stability fix and production hardening.
- Critical Import Failure: Resolved an
AttributeErroronOpenCLBatchDecoderduring module initialization. In v0.6.5, an unguarded import was left in__init__.py, which failed on wheels built with--no-default-features --features cuda. This has been removed, allowing the properly guarded fallback to execute as intended. - Hypergraph Validation:
UnionFindDecoderandFastUnionFindDecodernow explicitly reject hypergraph codes where any qubit participates in >2 checks (UfGraph::newreturnsResult<Self, String>), eliminating silent syndrome-invalid corrections. - Input Validation: Added comprehensive validation for empty, negative, duplicate, range,
u32::MAX, and non-integer types, raising cleanValueError/TypeError. - Namespace Leakage: Removed
os,sys,subprocess, andnpfrom the public__init__.pymodule scope. - Routing Safety:
recommend_decodernow safely avoids recommending the UF family on hypergraphs.
- Packaging: wheel matrix expanded to Linux x86_64, Windows x64, and macOS arm64 — 15 wheels (CPython 3.9–3.13 × 3 platforms).
Correction (2026-07-31): this entry originally read "
sdistis now published alongside wheels." That did not happen. Checked against the live PyPI JSON API, the only release that ever carried an sdist is 0.5.0; every release from 0.5.1 onward, 0.6.6 included, publishes 15 wheels and nothing else. - Testing: Expanded test matrix and relaxed d=21 latency threshold for CI stability.
This release was yanked from PyPI shortly after publication.
- Reason: Critical import failure on all published wheels due to an unguarded
OpenCLBatchDecoderreference in__init__.py. CI builds excluded OpenCL, causing an immediateAttributeErrorfor all users. - Resolution: All users should upgrade directly to
v0.6.6.
This release was yanked from PyPI shortly after publication.
- Reason: Internal CI/CD pipeline misconfiguration resulted in incomplete artifact publishing.
- Resolution: Superseded by
v0.6.6.
This release was yanked from PyPI shortly after publication.
- Reason: GitHub Actions secrets misconfiguration during the Rust build step.
- Resolution: Superseded by
v0.6.6.
Focus: Production hardening, correctness, and audit remediation.
- Comprehensive input validation and improved NumPy type coercion (
np.int*,np.bool_). - All docs, versioning, and metadata aligned to 0.6.2.
- (Note: This was the last stable release prior to the v0.6.6 corrective rollout).
Focus: API drift correction and Python 3.9 compatibility.
- API Drift: Updated
README.mdandPYPI_README.mdStim detector-error-model quick-start examples to usefrom_stim_detector_error_modelinstead of the removedstim_circuit_to_check_matrix. - Python 3.9 Compatibility: Replaced PEP 604
X | Noneunion syntax withtyping.Optional/typing.Unioninbackend.py,qiskit_plugin.py,stim_compat.py, and__init__.py.
- Package metadata (
pyproject.toml,Cargo.toml,Cargo.lock, runtime fallback version,CITATION.cff,codemeta.json) bumped to0.6.0.
Focus: GPU acceleration, routing, and streaming workflows.
- CuPy-accelerated GPU backend (
gpu_backend.py,bp_cupy.py). - Automatic decoder backend routing (
routing.py). - Streaming/sliding-window decoding sessions (
streaming.py).
- Superseded
advanced.pymodule and due-diligence bundle helper scripts.
Codename: Lepton
- Blossom exactness at large distance:
BlossomDecodernow uses an adaptive candidate capk = max(12, 4·√n_defects), restoring exact-MWPM behaviour through d=15.
- QECTOR Workbench: Headless, fully-tested controller for benchmark jobs and JSON/CSV/PDF report generation.
- Expanded validation suite: 832 tests green, covering exact-MWPM parity, DEM-collapse equivalence, belief-matching cross-checks, and GPU CPU-bit-identity.
- Full technical report: Regenerated for 0.5.0, detailing accuracy parity and a ~0.8% threshold.
QECTOR Decoder is source-available under the PolyForm Noncommercial License 1.0.0 (see LICENSE).
- Free for personal, academic, educational, and non-commercial research use.
- Commercial, institutional, lab, or product-integration use requires a paid commercial license.
For licensing inquiries, source-review access, or enterprise deployment, please contact:
- Email: admin@qector.store
- Web: https://qector.store/pricing
- Provenance: Protected by timestamped archival (Zenodo DOI).
See LICENSE and COMMERCIAL.md for full terms.
| Module | Purpose |
|---|---|
codes |
One-call code-family helpers: repetition_code, ring_code, rotated_surface_code, unrotated_surface_code, toric_code, heavy_hex_code, from_parity_check_matrix (dense/scipy.sparse), hypergraph_product (CSS). All surface families are validated matching graphs. |
dem |
Correct Stim Detector Error Model loader: parse_dem, load_dem_file, from_stim. Mechanisms = columns, detectors = rows; handles repeat / shift_detectors / ^ decomposition; emits check matrix, observables matrix, priors and matching weights. Works without Stim installed. |
result |
DecodeResult / decode_with_diagnostics: correction as uint8 / sparse / bit-packed, logical flips, matching weight, timing, backend metadata, to_json(), explain(). |
backend |
AutoDecoder routes CPU / Rayon / CUDA / OpenCL by batch size, with calibrate() crossover measurement, manual override, graceful GPU fallback and diagnostics. |
pymatching_compat |
Matching — a drop-in subset of pymatching.Matching (from_check_matrix, from_detector_error_model, add_edge, add_boundary_edge, decode, decode_batch). |
benchmarking |
Reproducible harness: environment capture, seeds, warmup, mean/median/std + p50/p90/p95/p99 + 95% CI, hot-vs-cold split, peak memory, JSON + CSV. |
stim_compat.from_stim_detector_error_modelnow delegates todem. The previous implementation conflated detector indices with qubit indices and produced an incorrectH; the detector graph is now built correctly (one column per fault mechanism, one row per detector).
BlossomDecoderis exact MWPM — brute-force optimal on every enumerated syndrome of the small codes (weight gap 0).SparseBlossomDecoderis a region-growing decoder — always syndrome-faithful and near-optimal (≥99% of small-code syndromes optimal, weight gap ≤1). It is not exact MWPM by design; useBlossomDecoderwhen exact minimum weight matters.- QECTOR matching is never heavier than PyMatching across repetition d=11, rotated surface d=5/7, and toric L=4 (differences are equal-weight tie representatives).
- New driver:
scripts/run_competitive_benchmark.py→ JSON + CSV + environment block. - New examples:
examples/example_codes_and_diagnostics.py,example_stim_dem.py,example_pymatching_and_backend.py(all exercised bytest_examples.py). - New CI:
.github/workflows/tests.yml(Linux/Windows/macOS × Python 3.9–3.12, Rustcargo test, benchmark smoke job, coverage, ruff/mypy). - New packaging extras:
[stim],[bench],[cuda],[opencl],[all]. - New docs:
docs/METHODOLOGY.md,docs/REPRODUCE.md,docs/SCALING.md,docs/CORRECTNESS_AUDIT.md. - Test suite: 387 passing (2 skipped, 1 xfailed) including new code/DEM/result/ backend/PyMatching/benchmark suites plus property-based and exhaustive brute-force correctness tests.
Version stays 0.4.0: the layer is additive and the compiled core is unchanged, so
qector_decoder_v3.__version__continues to report0.4.0.
Three additions that move QECTOR from "matches PyMatching" to "beats PyMatching on
accuracy and covers the LDPC frontier", all pure-Python on the 0.4.0 core and
cross-validated against reference packages. See docs/BEYOND_PYMATCHING.md.
Historical (2026-06-22), no surviving artifact. The LER figures in this section were measured circuit-level on Stim shots — the methodology is stated per bullet and is internally consistent — but the raw outputs were not archived and have not been reproduced on 0.7.0. Treat them as a record of what was claimed at the time, not as current evidence. For citable numbers use the archived Zenodo datasets listed in
README.md.
belief_matching.BeliefMatching— sum-product BP on the hyperedge detector graph + QECTOR exact weighted MWPM on the edge graph (belief-matching). Verified directly and through Sinter; cross-checked against the referencebeliefmatchingpackage.bposd.BpOsdDecoder— self-contained sum-product BP + ordered-statistics (OSD-0 / OSD-w) for arbitrary GF(2) / LDPC check matrices, plus LDPC code families (codes.bivariate_bicycle_code,codes.bicycle_code). Always syndrome-faithful, cross-validated against the referenceldpcpackage.sinter_compat—qector_blossom/qector_belief/qector_unionfindexposed assinter.Decoders, so QECTOR drops into the community-standard Monte-Carlo harness used to benchmark PyMatching and fusion-blossom.predecoder.PredecodedDecoder— faithful local-matching predecoder (resolves adjacent defect pairs before the residual decoder) andquantize_weights.
Shared infrastructure: vectorised min-sum and sum-product BP (_bp_core),
GF(2) ordered-statistics solver, and dem.DemModel.collapse_to_graph (parallel-edge
merge). Benchmark drivers: scripts/competitive_belief_matching.py,
scripts/competitive_stim_ler.py. Test suite now 414 tests (adds
belief-matching, BP-OSD/LDPC, Sinter, predecoder suites, all cross-validated);
the fast core is verified stable over a 20× repeated-run stability sweep.
Requires the optional packages for the advanced paths:
stim,pymatching(matching/belief),ldpc(BP-OSD cross-checks),sinter(harness). Install via the[stim]/[all]extras.
This release delivers the complete QECTOR v3 decoder suite with 4 algorithmic backends, GPU acceleration via OpenCL, precision decoders (BP-OSD, Neural), Sparse Blossom with blossom contraction/shattering, and production infrastructure (gRPC, Prometheus, MCP). All 72 Rust tests and 260+ Python tests pass.
| Decoder | Status | Key Feature |
|---|---|---|
UnionFindDecoder |
Stable | SIMD + pooled allocators, hot-path optimised |
BlossomDecoder |
Stable | Edmonds MWPM, exact for d≤7 |
SparseBlossomDecoder |
Stable | Region-growing BFS, blossom contraction + shattering, exact DP n≤20 |
BPOSDDecoder |
Stable | Belief propagation + ordered statistics (OSD-0/OSD-w) |
NeuralPredecoder |
Stable | MLP Xavier/ReLU, hybrid fallback |
GNNPredecoder |
Experimental | Message-passing + edge readout, forward pass OK |
LookupTableDecoder |
Stable | Exact d=3,5,7 precomputed, SIMD fallback |
HybridDecoder |
Stable | Auto-selection per syndrome difficulty |
StreamingDecoder |
Stable | Sliding window; latency figure withdrawn, see below |
BatchDecoder / CPUBatchDecoder |
Stable | SIMD, parallel, pooled; throughput figure withdrawn, see below |
OpenCLBatchDecoder |
Stable | GPU dual-kernel, transparent fallback, resilience |
- Dual-kernel: global memory (batch≥1024) + local memory (batch<1024)
- Transparent CPU fallback on GPU failure
- Auto-recovery: exits degraded mode after 10 successful calls
- Observability:
consecutive_failures,total_failures,gpu_recoveries,degraded_calls - Performance: the "14.6M dec/s @ d=5, batch=10000" figure is withdrawn — it
is one of the rows under Performance Highlights below, which no surviving
artifact backs. No measured replacement is published for v0.7.0: the CUDA
kernel optimisation landed after the last benchmark run, so any figure taken
from that run would describe a different binary. What is documented instead is
behaviour: the kernels accept optional
edge_weights(the DEM'slog((1-p)/p)matching weights), and the weighted configuration is the accuracy path — pass the weights for the accuracy path (see the README quick-start). The unweighted configuration is documented as operating above threshold; it decodes topology-only and its logical error rate does not improve with distance. No latency or throughput figure for either path is published with this release.
- Feature flags:
opencl,grpc,cuda,full(Cargo.toml) - gRPC server: Decode + batch decode endpoints (commented,
grpcfeature) - Prometheus metrics:
metricsfeature,start_metrics_server() - MCP server: JSON-RPC 2.0 for Claude Code integration
- Examples:
examples/example_basic.py,example_batch.py,example_streaming.py,example_blossom.py
README.md— Quick start, decision matrix, validated scope & known limitationsCHANGELOG.md— Release history (incl. the adaptive-k fix)INSTALL.md— Installation instructions (this release)docs/QECTOR_Decoder_v3_Full_Report.pdf— Full technical report (26 sections)docs/BENCHMARK_COMPETITIVE.md— Competitive methodology vs PyMatchingdocs/BEYOND_PYMATCHING.md— Belief-matching, BP-OSD, GPUdocs/CORRECTNESS_AUDIT.md— Correctness auditdocs/METHODOLOGY.md,docs/SCALING.md,docs/REPRODUCE.mddocs/reports/— Historical reports (GNN training, decoder correctness v3.6)docs/internal/— Competitive analysis, roadmap (internal)
Historical, code-capacity, and not comparable to any circuit-level figure. The LER rows below were measured under code-capacity noise at
p = 0.05— an independent-error model on the data qubits with no measurement error and no repeated rounds. Circuit-level LERs quoted elsewhere in this project, and every number published by PyMatching, Stim, or Sinter, are a different quantity. Placing the two in one table is the methodology error that caused the v0.7.0 benchmark withdrawal. No artifact backs any of the rows this section once carried, and none of them may be cited — they are removed outright for v0.7.0. No performance figures are published with this release.
The decoder capabilities this section previously illustrated are:
| Capability | Where it lives |
|---|---|
CPU single-shot decode() with SIMD and pooled allocators |
UnionFindDecoder, FastUnionFindDecoder |
GPU batch decoding on CUDA and OpenCL, with optional edge_weights |
CUDABatchDecoder, OpenCLBatchDecoder |
| CPU parallel batch decoding | BatchDecoder, CPUBatchDecoder |
| BP-OSD for LDPC/qLDPC check matrices, OSD-0/OSD-w | BPOSDDecoder, BpOsdDecoder |
| Exact weighted MWPM | BlossomDecoder |
| Region-growing sparse MWPM | SparseBlossomDecoder |
| Sparse-vs-exact agreement (bit-identical on ring-code trials) | cross-decoder test suite |
These are specifications of what the decoders do, not measurements of how fast they do it. Measure on your own hardware and archive the artifact before citing any figure.
None — this is a forward-compatible release from v0.3.0. Feature flags are additive.
- Dead code warnings: 11 warnings in
blossom.rs(unused fields/methods) andsparse_blossom.rs(unused structs/methods). These are intentional保留 fields for future Edmonds blossom algorithm activation and Radix heap optimization. They do not affect functionality. - Neural predecoder: 35-93% fallback rate. Recommendations: switch to GNN, train on Blossom teacher, or predict edge weights for SparseBlossom.
- Sparse Blossom toric boundaries: Surface code with periodic boundaries (toric) has incomplete boundary handling. Use planar boundaries or ring code for now.
- CUDA Backend: Fully implemented using NVIDIA CUDA Driver API, dynamic NVRTC kernel compilation, and a reusable workspace (no longer a stub).
- Guillaume Lessard / iD01t Productions — Author, core algorithm design & Rust implementation
PolyForm Noncommercial License 1.0.0 — see LICENSE.
Copyright © 2026 Guillaume Lessard / iD01t Productions. All rights reserved.
Free for non-commercial use; commercial use requires a paid license
(admin@qector.store · https://www.qector.store).
From v0.3.0:
- No API changes — all Python classes remain compatible
- New feature flags available:
grpc,cuda(no-op),full - New
OpenCLBatchDecoder.reset()method for clearing resilience counters - New Python property:
OpenCLBatchDecoder.gpu_recoveries
- Repository: https://github.com/GuillaumeLessard/qector-decoder
- Issues: https://github.com/GuillaumeLessard/qector-decoder/issues
- Documentation: See
README.md