Skip to content

Commit 75cd45c

Browse files
author
Guillaume Lessard
committed
docs(readme): fix stale Workbench GUI version (v3.5.0 -> v0.5.3) and remove all em/en-dashes from prose
1 parent ab24240 commit 75cd45c

1 file changed

Lines changed: 36 additions & 36 deletions

File tree

README.md

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
[![Python](https://img.shields.io/pypi/pyversions/qector-decoder-v3.svg)](https://pypi.org/project/qector-decoder-v3/)
66
[![License](https://img.shields.io/badge/License-PolyForm_Noncommercial_1.0.0-blue)](https://github.com/GuillaumeLessard/qector-decoder/blob/main/LICENSE)
77

8-
**Production-grade quantum error correction decoding library Python + Rust.**
8+
**Production-grade quantum error correction decoding library, Python + Rust.**
99
*Copyright © 2026 Guillaume Lessard / iD01t Productions. All Rights Reserved.*
1010

1111
## 🚀 Support QECTOR Development
1212

13-
QECTOR is source-available and developed independently. Non-commercial use is free sponsorship
13+
QECTOR is source-available and developed independently. Non-commercial use is free; sponsorship
1414
and commercial licences are what keep the decoder maintained.
1515

1616
[![Sponsor qectorlab](https://img.shields.io/badge/GitHub_Sponsors-qectorlab-ea4aaa?style=for-the-badge&logo=githubsponsors&logoColor=white)](https://github.com/sponsors/qectorlab)
@@ -20,7 +20,7 @@ and commercial licences are what keep the decoder maintained.
2020
| Channel | Who it's for |
2121
|---|---|
2222
| [GitHub Sponsors](https://github.com/sponsors/qectorlab) | Individuals and companies funding ongoing development |
23-
| [Commercial licence](https://www.qector.store/pricing) | Required for company, SaaS, OEM or funded institutional use see [COMMERCIAL.md](https://github.com/GuillaumeLessard/qector-decoder/blob/main/COMMERCIAL.md) |
23+
| [Commercial licence](https://www.qector.store/pricing) | Required for company, SaaS, OEM or funded institutional use, see [COMMERCIAL.md](https://github.com/GuillaumeLessard/qector-decoder/blob/main/COMMERCIAL.md) |
2424
| [Direct purchase](https://buy.stripe.com/6oU00l77Xc8ifsegEqeUU07) | Immediate Stripe checkout, licence issued automatically |
2525
| [admin@qector.store](mailto:admin@qector.store) | Site licences, custom terms, academic partnerships |
2626

@@ -37,10 +37,10 @@ PyMatching-compatible MWPM validation · Belief-matching accuracy mode · BP-OSD
3737
pip install qector-decoder-v3
3838
```
3939

40-
Supported: **Python 3.93.13** (`requires-python = ">=3.9"`) on Linux x86_64,
40+
Supported: **Python 3.9-3.13** (`requires-python = ">=3.9"`) on Linux x86_64,
4141
Windows x64, and macOS arm64.
4242

43-
Each release publishes **15 binary wheels** CPython 3.9/3.10/3.11/3.12/3.13 ×
43+
Each release publishes **15 binary wheels**: CPython 3.9/3.10/3.11/3.12/3.13 ×
4444
`win_amd64` / `manylinux_2_17_x86_64` / `macosx_11_0_arm64`. There is **no sdist
4545
and no aarch64, musllinux, or macOS x86_64 wheel**, so `pip install` on any other
4646
platform will fail rather than fall back to a source build. Those targets need a
@@ -91,7 +91,7 @@ if CUDABatchDecoder.is_available():
9191

9292
**Pass the DEM's weights to the GPU.** Without `edge_weights` the GPU kernels run
9393
unweighted cluster growth, which cannot distinguish a `p = 1e-4` mechanism from a
94-
`p = 1e-2` one on circuit-level noise that costs several times the logical
94+
`p = 1e-2` one; on circuit-level noise that costs several times the logical
9595
error rate, no matter how fast the GPU is:
9696

9797
```python
@@ -119,11 +119,11 @@ hardware and noise model.
119119

120120
**No benchmark figures are published for this release.** Decoder performance is
121121
hardware-, code- and noise-dependent, and any number quoted here would not
122-
describe your setup. Run the harness yourself the JSON it writes carries its own
122+
describe your setup. Run the harness yourself: the JSON it writes carries its own
123123
environment and parameter block, so results are traceable to the machine that
124124
produced them. See `docs/GPU_AND_CUPY.md`.
125125

126-
### AutoDecoder 7-tier self-debugging fallback
126+
### AutoDecoder: 7-tier self-debugging fallback
127127

128128
```python
129129
from qector_decoder_v3 import AutoDecoder
@@ -153,7 +153,7 @@ decoder = BlossomDecoder(checks, n_qubits)
153153
```
154154

155155
`DemModel.make_decoder` builds any shipped decoder family straight from the
156-
model, already carrying its weights — enumerate them with
156+
model, already carrying its weights. Enumerate them with
157157
`DemModel.DECODER_KINDS`:
158158

159159
```python
@@ -207,7 +207,7 @@ print(f"Tier: {info['tier']} status: {info['key_status']}")
207207

208208
The core also resolves a key on its own, in this order: `QECTOR_LICENSE_KEY`,
209209
then `QECTOR_LICENSE_FILE`, then `~/.qector/license.key`. Prefer a file in
210-
deployments the key then never appears in a process listing or shell history.
210+
deployments: the key then never appears in a process listing or shell history.
211211
Check `info["key_status"] == "valid"`, not just the tier: a `QECTOR_LICENSE_FILE`
212212
that is set but unreadable is reported as an *invalid* key rather than silently
213213
falling back to Community.
@@ -303,13 +303,13 @@ QECTOR uses **offline Ed25519 signature verification** for license tokens. No ne
303303
## Tuning environment variables
304304

305305
These change decoder behaviour at construction time. Two of them affect
306-
**matching quality**, and therefore logical error rate set them deliberately,
306+
**matching quality**, and therefore logical error rate; set them deliberately,
307307
and record them alongside any benchmark you publish.
308308

309309
| Variable | Default | Effect |
310310
| --- | --- | --- |
311311
| `QECTOR_BLOSSOM_K_MULT` | `2.0` | Candidate-neighbour multiplier for sparse MWPM: `k = max(12, ceil(mult · sqrt(n_defects)))`. **Affects accuracy.** Lowering it reduces latency but can exclude the optimal partner on dense instances, producing a heavier (sub-optimal) matching. `2.0` is the tuned minimum that preserved exact-MWPM parity at d ≥ 15. |
312-
| `QECTOR_BLOSSOM_INTRA_PAR` | auto | Force intra-decode parallelism for candidate discovery. `0` disables, `1` forces. Unset selects automatically when the graph has ≥ 64 nodes (roughly d ≥ 9 for rotated surface codes). Performance only output is bit-identical either way. |
312+
| `QECTOR_BLOSSOM_INTRA_PAR` | auto | Force intra-decode parallelism for candidate discovery. `0` disables, `1` forces. Unset selects automatically when the graph has ≥ 64 nodes (roughly d ≥ 9 for rotated surface codes). Performance only; output is bit-identical either way. |
313313
| `QECTOR_BLOSSOM_INTRA_THREADS` | unset | Size a dedicated Rayon pool for candidate discovery, independent of the global batch pool. Unset or `< 1` uses the global pool. Performance only. |
314314
| `QECTOR_CUDA_DEVICE_ID` | `0` | Which CUDA device the native batch/BP-OSD decoders bind to. |
315315
| `QECTOR_OPENCL_DEVICE_ALLOW` | unset | Comma-separated substrings matched case-insensitively against OpenCL device names, e.g. `nvidia,geforce`. Unset accepts any device. Use it to avoid selecting an integrated GPU on multi-device hosts. |
@@ -335,16 +335,16 @@ Commercial licenses are issued automatically via Stripe Checkout:
335335

336336
| Area | Description |
337337
| --- | --- |
338-
| **`qector` CLI** | `qector decode` / `bench` / `serve`, plus `qector-doctor` a 15-check environment diagnostic that tells you *why* a decoder is unavailable instead of failing at decode time |
338+
| **`qector` CLI** | `qector decode` / `bench` / `serve`, plus `qector-doctor`, a 15-check environment diagnostic that tells you *why* a decoder is unavailable instead of failing at decode time |
339339
| **Ecosystem entry points** | Five Sinter decoders and the qiskit-qec plugin are now registered entry points, so `sinter.collect(decoders=["qector_blossom", ...])` works without `custom_decoders=` |
340-
| **`pymatching` shim** | `from qector_decoder_v3.pymatching import Matching` the submodule spelling, not only the attribute |
341-
| **New decoder families** | `AmbiguityClusterDecoder` (BP + \|LLR\| partition + exact per-cluster enumeration), `TwoStageDecoder` (X sector, propagate, Z sector), `ColourCodeDecoder` (BP-OSD on the *undecomposed* hypergraph matching is not a correct colour-code decoder) |
340+
| **`pymatching` shim** | `from qector_decoder_v3.pymatching import Matching`, the submodule spelling, not only the attribute |
341+
| **New decoder families** | `AmbiguityClusterDecoder` (BP + \|LLR\| partition + exact per-cluster enumeration), `TwoStageDecoder` (X sector, propagate, Z sector), `ColourCodeDecoder` (BP-OSD on the *undecomposed* hypergraph; matching is not a correct colour-code decoder) |
342342
| **Relay-BP** | Layered serial BP schedule for qLDPC (`bp_method="relay"`); each check sees the freshest messages |
343343
| **Weighted Union-Find on the GPU** | `CUDABatchDecoder` and `OpenCLBatchDecoder` accept `edge_weights` and run adaptive weighted growth; both kernels agree, which is the cross-check that the port is faithful |
344-
| **`DemModel.make_decoder`** | Covers all nine shipped families, not five a DEM is the entry point real circuit-level workloads use |
345-
| **Belief matching** | `from_numpy_h` decoders no longer return empty corrections output is a faithful length-`n_qubits` vector (`H @ corr == syndrome`) |
344+
| **`DemModel.make_decoder`** | Covers all nine shipped families, not five; a DEM is the entry point real circuit-level workloads use |
345+
| **Belief matching** | `from_numpy_h` decoders no longer return empty corrections; output is a faithful length-`n_qubits` vector (`H @ corr == syndrome`) |
346346
| **BP-OSD accuracy** | Exact log-domain sum-product BP by default; true combination-sweep OSD-1/2 via `osd_order` |
347-
| **Rust core: crash safety** | Six panic-to-abort paths removed gRPC and CUDA mutex-poison propagation, swallowed CUDA async errors, `Bernoulli::new` unwrap, cascade-decoder `expect`. Under `panic = "abort"` each of these killed the host process |
347+
| **Rust core: crash safety** | Six panic-to-abort paths removed: gRPC and CUDA mutex-poison propagation, swallowed CUDA async errors, `Bernoulli::new` unwrap, cascade-decoder `expect`. Under `panic = "abort"` each of these killed the host process |
348348
| **Licence hardening** | Malformed tokens return `False` instead of raising; v2 tokens carry tier + expiry inside the signature; `QECTOR_LICENSE_FILE` and `~/.qector/license.key` are read, and an unreadable file reports *invalid* rather than silently dropping to Community |
349349
| **Benchmark honesty** | The pre-v0.7.0 comparison tables are withdrawn; `ler.assert_comparable` now blocks cross-noise-model comparisons at the source |
350350

@@ -370,8 +370,8 @@ Commercial licenses are issued automatically via Stripe Checkout:
370370

371371
### Withdrawn: the pre-v1.0.0 comparison tables
372372

373-
**Four benchmark tables that stood here MWPM parity vs PyMatching at d=13/15,
374-
belief-matching LER at d=5/7, GPU bit-identity, and the native memory profile
373+
**Four benchmark tables that stood here: MWPM parity vs PyMatching at d=13/15,
374+
belief-matching LER at d=5/7, GPU bit-identity, and the native memory profile,
375375
are withdrawn. Do not cite them.**
376376

377377
Two independent reasons, either sufficient:
@@ -382,7 +382,7 @@ Two independent reasons, either sufficient:
382382
so the "parity" the tables reported was an artifact of the harness, not a
383383
property of the decoders.
384384
2. **The artifacts are unobtainable.** Each table cited a file under
385-
`benchmark_results/` a path that is in `.gitignore` and has never been part
385+
`benchmark_results/`, a path that is in `.gitignore` and has never been part
386386
of any published commit or wheel. The files are also no longer on disk. Nobody
387387
could have checked the numbers even when they were displayed.
388388

@@ -394,9 +394,9 @@ cannot recur silently.
394394

395395
**What replaces them:** `scripts/regenerate_benchmark_artifacts.py` and
396396
`scripts/run_custom_comparison_benchmark.py` both drive every decoder through
397-
one circuit-level pipeline `ler.estimate_ler_circuit_level`, one Stim circuit,
397+
one circuit-level pipeline: `ler.estimate_ler_circuit_level`, one Stim circuit,
398398
one decomposed DEM, one detector/observable sample set per cell, one
399-
`decode_batch` resolver, scored against the circuit's own logical observables
399+
`decode_batch` resolver, scored against the circuit's own logical observables;
400400
and stamp the result with its methodology, git commit, tree-dirty flag,
401401
parameters and dependency versions. `ler.assert_comparable` gates the rows
402402
before they are written.
@@ -418,27 +418,27 @@ through the package MCP server (stdio, JSON-RPC 2.0) on `2026-08-02T05:59:13Z`
418418
(Linux glibc 2.35, Python 3.12.13).
419419

420420
- **Peak throughput:** 11,540,387 shots/s (FastUnionFind, 5-qubit repetition code, 8,000 samples)
421-
- **54/54 benchmark points** with zero unfaithful corrections (repetition n=565, ring n=1648; unionfind, fastunionfind, blossom, sparseblossom, bposd, auto)
421+
- **54/54 benchmark points** with zero unfaithful corrections (repetition n=5-65, ring n=16-48; unionfind, fastunionfind, blossom, sparseblossom, bposd, auto)
422422
- **42/42 syndrome-faithfulness cases** passed; **13 MCP tools** operational
423423
- **No speedup multiplier is claimed.** Apple-to-apple vs PyMatching (see `benchmarks/v1.0.0/VERIFIED_APPLE_TO_APPLE_REPORT.pdf`): comparable, with PyMatching often slightly ahead on the synchronized batch.
424424

425425
The previous `official_benchmark_results.*` (2026-08-01 circuit-level comparison,
426426
generated from a dirty working tree at `b436f04e`, carrying per-row
427-
speedup-vs-PyMatching multipliers) is **withdrawn** it is not part of the
427+
speedup-vs-PyMatching multipliers) is **withdrawn**: it is not part of the
428428
verified release and must not be cited.
429429

430430
> **Benchmark figures are not published beyond the verified set for this release.**
431431
> Decoder throughput and logical error rate depend on your hardware, code family,
432432
> distance and noise model, so any table printed here would describe a machine that
433433
> is not yours. The benchmark harness ships with the package and writes JSON carrying
434-
> its own environment and parameter block run it on your target hardware
434+
> its own environment and parameter block; run it on your target hardware
435435
> (`qector benchmark --verify` or `python -m qector.validate`) and compare decoders
436436
> under the conditions you actually care about.
437437
438438
**GPU accuracy depends on whether matching weights are supplied.**
439439
`CUDABatchDecoder` and `OpenCLBatchDecoder` accept an optional `edge_weights`
440440
argument. Omitting it selects topology-only cluster growth, whose logical error
441-
rate does not improve with code distance the signature of operation above
441+
rate does not improve with code distance: the signature of operation above
442442
threshold. Supplying the DEM's `log((1-p)/p)` weights restores distance scaling.
443443
The weighted path costs more per shot than the unweighted one.
444444
`docs/BENCHMARK_COMPETITIVE.md` records the same effect for unweighted
@@ -462,14 +462,14 @@ project lives in the archived datasets, not in this file:
462462

463463
| Record | What it establishes | Methodology |
464464
| --- | --- | --- |
465-
| [10.5281/zenodo.21501377](https://doi.org/10.5281/zenodo.21501377) Empirical benchmarks, v0.6.8 (CC-BY-4.0) | Archived empirical benchmark dataset for v0.6.8, including syndrome-faithfulness verification (`H·ê = s`) and matching parity against PyMatching | Circuit-level, single pipeline. Ships 5 raw JSON datasets, 6 repro scripts, and a `manifest.json` carrying the wheel SHA256 and pinned dependency versions. Host: HP dual-core, 3.1 GB RAM, AntiX live USB, Python 3.13.5, pymatching 2.4.0, stim/sinter 1.16.0 |
466-
| [10.5281/zenodo.21339300](https://doi.org/10.5281/zenodo.21339300)Workbench benchmark master report, v0.6.6 (CC-BY-4.0) | 1,858 measurements over 105 runs; latency, throughput and peak memory for `d = 319` across 6 topologies | `p = 0.05`. Reports QECTOR decoders against each other it is **not** a cross-library comparison |
465+
| [10.5281/zenodo.21501377](https://doi.org/10.5281/zenodo.21501377): Empirical benchmarks, v0.6.8 (CC-BY-4.0) | Archived empirical benchmark dataset for v0.6.8, including syndrome-faithfulness verification (`H·ê = s`) and matching parity against PyMatching | Circuit-level, single pipeline. Ships 5 raw JSON datasets, 6 repro scripts, and a `manifest.json` carrying the wheel SHA256 and pinned dependency versions. Host: HP dual-core, 3.1 GB RAM, AntiX live USB, Python 3.13.5, pymatching 2.4.0, stim/sinter 1.16.0 |
466+
| [10.5281/zenodo.21339300](https://doi.org/10.5281/zenodo.21339300): Workbench benchmark master report, v0.6.6 (CC-BY-4.0) | 1,858 measurements over 105 runs; latency, throughput and peak memory for `d = 3-19` across 6 topologies | `p = 0.05`. Reports QECTOR decoders against each other; it is **not** a cross-library comparison |
467467

468468
Both are one release behind the working tree (v0.6.8 and v0.6.6 against 1.0.0);
469469
read them as evidence about those versions.
470470

471471
Benchmark results are hardware, driver, compiler, and workload dependent.
472-
Regenerate before quoting performance numbers, and state the noise model
472+
Regenerate before quoting performance numbers, and state the noise model:
473473
code-capacity and circuit-level LERs are different quantities.
474474

475475
---
@@ -497,7 +497,7 @@ python scripts/gpu_extensive_test.py --distances 3 5 7 9 11 13 --batches 1 64 10
497497
python scripts/native_memory_profile.py --distances 5 9 13 --batch 16384
498498
```
499499

500-
These write into `benchmark_results/`, which is `.gitignore`d the output stays
500+
These write into `benchmark_results/`, which is `.gitignore`d; the output stays
501501
on the machine that produced it and is never committed. If you intend to publish
502502
a number, publish the artifact alongside it.
503503

@@ -544,15 +544,15 @@ For local experiments and controlled deployments only. Not hardened for public S
544544
## MCP server (stdio)
545545

546546
The package ships an **MCP server** (JSON-RPC 2.0 over stdio) in every published
547-
wheel no extra feature flag or install is needed:
547+
wheel, no extra feature flag or install is needed:
548548

549549
```bash
550550
python -c "import qector_decoder_v3; qector_decoder_v3.run_mcp_server()"
551551
```
552552

553553
A ready-made client configuration lives in `mcp.json` at the repository root
554554
(it launches `python -c "import qector_decoder_v3; qector_decoder_v3.run_mcp_server()"`
555-
with `QECTOR_SILENT=1`). Point your MCP client at that file e.g. Claude Code
555+
with `QECTOR_SILENT=1`). Point your MCP client at that file, e.g. Claude Code
556556
supports `mcp.add` with the `qector` server name. The server advertises 13
557557
tools, all verified on the released wheel:
558558

@@ -582,12 +582,12 @@ controlled use; like REST/gRPC, it is not hardened for public SaaS exposure.
582582
| Area | Boundary |
583583
| --- | --- |
584584
| MWPM latency | PyMatching remains faster than exact `BlossomDecoder` on standard surface-code MWPM. QECTOR's value is decoder breadth and qLDPC coverage, not beating PyMatching at its own workload |
585-
| Belief-matching | Accuracy/research mode can improve LER but much slower |
585+
| Belief-matching | Accuracy/research mode; can improve LER but much slower |
586586
| GPU accuracy | Unweighted GPU kernels trade logical accuracy for throughput; pass `edge_weights` or accept that |
587587
| GPU performance | Speedup is not universal, and the weighted kernel is currently slower than the weighted CPU path |
588588
| Benchmark tables | The pre-v0.7.0 comparison tables are withdrawn (see above). Cite the archived datasets or regenerate |
589589
| OpenCL | Depends on build configuration; confirm locally |
590-
| SparseBlossom | Near-optimal, not exact MWPM use `BlossomDecoder` for exact |
590+
| SparseBlossom | Near-optimal, not exact MWPM; use `BlossomDecoder` for exact |
591591
| UnionFind | Fast approximate path; not universal for arbitrary graphs |
592592
| REST/gRPC/MCP | Not hardened as public SaaS without separate security review |
593593

@@ -607,7 +607,7 @@ QECTOR Decoder v3 is **source-available** under the **PolyForm Noncommercial Lic
607607
- Performance benchmarks (v0.6.6): [10.5281/zenodo.21339300](https://doi.org/10.5281/zenodo.21339300)
608608
- Architecture whitepaper: [10.5281/zenodo.21320543](https://doi.org/10.5281/zenodo.21320543)
609609
- Empirical edge-hardware benchmarks (v0.6.8): [10.5281/zenodo.21501377](https://doi.org/10.5281/zenodo.21501377)
610-
- Workbench GUI v3.5.0: [10.5281/zenodo.21360433](https://doi.org/10.5281/zenodo.21360433)
610+
- Workbench GUI v0.5.3: [10.5281/zenodo.21360433](https://doi.org/10.5281/zenodo.21360433)
611611
- Provenance archive (restricted): [10.5281/zenodo.20825980](https://doi.org/10.5281/zenodo.20825980)
612612

613613
```bibtex

0 commit comments

Comments
 (0)