Skip to content

Commit 2ec8b88

Browse files
Guillaume Lessardclaude
andcommitted
release: v0.7.0 — ship specs and capabilities, publish no benchmark figures
Dates the 0.7.0 changelog heading and removes performance measurements from every public document. Why no figures: the published tables were measured before the Jul 31 CUDA kernel optimisation, so they describe a different binary; and every logical error rate produced before 6a1e44e was Blossom's number reported under other decoders' names (workbench.py::_ler ignored the decoder under test). Attaching either to a release would mean publishing numbers already known to be wrong, and retracting a claim is worse than never making one. Stripped: README.md (the PyPI long_description), RELEASE_NOTES.md, DISCOVERY.md, docs/BENCHMARK_COMPETITIVE.md, docs/BENCHMARK_THROUGHPUT.md. Capability statements replace them -- decoder families, API surface, backends, Stim/PyMatching/Sinter compatibility, supported platforms and wheels. Kept deliberately: the "Withdrawn: the pre-v0.7.0 comparison tables" section and the withdrawn 14.6M dec/s note in RELEASE_NOTES. Those quote figures in order to retract them, which is disclosure, not a claim. Packaging specs such as the 15-wheel matrix are kept -- they are not measurements. The benchmark harness ships with the package and writes JSON carrying its own environment block, so users measure on the hardware they actually run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent fe4200d commit 2ec8b88

6 files changed

Lines changed: 155 additions & 215 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ on [Keep a Changelog](https://keepachangelog.com/), and the project aims to foll
55
semantic versioning. Every benchmark artifact is stamped with the git commit and
66
environment so report figures trace back to a specific build.
77

8-
## [0.7.0]UNRELEASED
8+
## [0.7.0]2026-08-01
99

10-
The repo version is 0.7.0; the latest version on **PyPI is 0.6.9**. Nothing below
11-
has been published. `src/*.rs` is `.gitignore`d, so `git log v0.6.9..HEAD` shows
12-
none of the Rust work recorded here — it is verified by `cargo test` and by
13-
reading the tree.
10+
`src/*.rs` is `.gitignore`d, so `git log v0.6.9..HEAD` shows none of the Rust
11+
work recorded here — it is verified by `cargo test` and by reading the tree.
12+
13+
This release publishes **no benchmark figures**. Decoder performance is
14+
hardware-, code- and noise-dependent, and the previously published tables were
15+
measured against a different build of the core. The benchmark harness ships with
16+
the package; measure on your own hardware.
1417

1518
### Release pipeline — six blockers, found by running it instead of trusting it
1619
`release-build.yml` had never executed. A `workflow_dispatch` dry run with

DISCOVERY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ quantum-control
4646
reproducibility
4747

4848
### SEO & AI Agent Discovery Keywords
49-
quantum error correction decoder, QEC decoder, quantum decoder Python, Rust quantum error correction, PyMatching compatible decoder, Stim decoder workflow, BP-OSD decoder, qLDPC decoder, LDPC quantum code, surface code decoder, reproducible QEC benchmarks, QECTOR Decoder v3, commercial quantum decoder license, lab QEC decoder pricing, source-available quantum error correction, ultra-low latency QEC decoding.
49+
quantum error correction decoder, QEC decoder, quantum decoder Python, Rust quantum error correction, PyMatching compatible decoder, Stim decoder workflow, BP-OSD decoder, qLDPC decoder, LDPC quantum code, surface code decoder, reproducible QEC benchmarks, QECTOR Decoder v3, commercial quantum decoder license, lab QEC decoder pricing, source-available quantum error correction.

README.md

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -438,22 +438,21 @@ rather than estimated — is in `official_benchmark_results.md`.
438438
Findings apply to the cells listed above and are not generalised beyond them
439439
(see `docs/REPRODUCIBILITY_CHECKLIST.md`).
440440

441-
**Accuracy parity with PyMatching.** At `d = 3` and `d = 5`, `qector_blossom`
442-
and PyMatching 2 recorded identical logical-failure counts on identical sample
443-
sets — 1891 and 1596 in 100,000 shots respectively.
441+
**Accuracy parity with PyMatching.** At the distances where both decoders were
442+
measured on identical sample sets, `qector_blossom` and PyMatching 2 recorded
443+
identical logical-failure counts. The counts live in the artifact; they are not
444+
restated here because this release publishes no performance figures.
444445

445-
**Throughput.** PyMatching 2 leads at every distance measured here. This is
446+
**Throughput.** PyMatching 2 led at every distance measured in that run. This is
446447
consistent with the position recorded elsewhere in this project that PyMatching
447448
leads on plain MWPM.
448449

449450
**GPU accuracy depends on whether matching weights are supplied.**
450451
`CUDABatchDecoder` and `OpenCLBatchDecoder` accept an optional `edge_weights`
451-
argument. Omitting it selects topology-only cluster growth, and the resulting
452-
logical error rate does not improve with code distance — 0.061 at `d = 5`,
453-
0.043 at `d = 7`, 0.038 at `d = 15` — which is the signature of operation above
454-
threshold. Supplying the DEM's `log((1-p)/p)` weights restores distance
455-
scaling: 0.026 at `d = 5`, 0.010 at `d = 9`, 0.007 at `d = 13`. The weighted
456-
weighted path costs more per shot than the unweighted one.
452+
argument. Omitting it selects topology-only cluster growth, whose logical error
453+
rate does not improve with code distance — the signature of operation above
454+
threshold. Supplying the DEM's `log((1-p)/p)` weights restores distance scaling.
455+
The weighted path costs more per shot than the unweighted one.
457456
`docs/BENCHMARK_COMPETITIVE.md` records the same effect for unweighted
458457
Union-Find on CPU. See the quick-start above for the weighted construction.
459458

@@ -554,6 +553,42 @@ For local experiments and controlled deployments only. Not hardened for public S
554553

555554
---
556555

556+
## MCP server (stdio)
557+
558+
The package ships an **MCP server** (JSON-RPC 2.0 over stdio) in every published
559+
wheel — no extra feature flag or install is needed:
560+
561+
```bash
562+
python -c "import qector_decoder_v3; qector_decoder_v3.run_mcp_server()"
563+
```
564+
565+
A ready-made client configuration lives in `mcp.json` at the repository root
566+
(it launches `python -c "import qector_decoder_v3; qector_decoder_v3.run_mcp_server()"`
567+
with `QECTOR_SILENT=1`). Point your MCP client at that file — e.g. Claude Code
568+
supports `mcp.add` with the `qector` server name. The server advertises 13
569+
tools, all verified on the released wheel:
570+
571+
| Tool | Purpose |
572+
|---|---|
573+
| `decode_syndrome` | Decode a syndrome with any decoder family (Union-Find, Blossom, SparseBlossom, BP-OSD, Cascade, Hybrid, and more) |
574+
| `batch_decode` | Batch-decode multiple syndromes in parallel |
575+
| `decode_hyperedge` | Hyperedge / qLDPC decoding (bypasses graphlike Union-Find restrictions) |
576+
| `decode_syndrome_blossom` / `batch_decode_blossom` | Exact Blossom (MWPM) single and batch |
577+
| `decode_syndrome_cascade` | Hybrid cascading decoder (UF pre-filter escalating to Blossom) |
578+
| `benchmark_decoder` | Run a performance benchmark for a decoder family |
579+
| `run_ler_benchmark` | LER benchmark across code distances |
580+
| `get_decoder_info` | Decoder configuration, version info, family listing |
581+
| `get_backend_health` | Backend health status across the 7 fallback tiers |
582+
| `clear_decoder_cache` | Clear the decoder factory cache |
583+
| `get_server_env` | Effective QECTOR environment variables |
584+
| `recommend_decoder` | Decoder recommendation by code topology and priority |
585+
586+
The stdio reader enforces a 10 MB content limit and validates syndrome lengths
587+
and decoder types, returning JSON-RPC errors instead of crashing. For local and
588+
controlled use; like REST/gRPC, it is not hardened for public SaaS exposure.
589+
590+
---
591+
557592
## Limits and boundaries
558593

559594
| Area | Boundary |

RELEASE_NOTES.md

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ withdrawn rather than corrected, since there is nothing yet to correct it to.
258258
**Codename**: Lepton
259259

260260
### Fixed
261-
- **Blossom exactness at large distance**: `BlossomDecoder` now uses an adaptive candidate cap `k = max(12, 4·√n_defects)`, restoring exact-MWPM logical-error-rate parity with PyMatching through d=15.
261+
- **Blossom exactness at large distance**: `BlossomDecoder` now uses an adaptive candidate cap `k = max(12, 4·√n_defects)`, restoring exact-MWPM behaviour through d=15.
262262

263263
### Added
264264
- **QECTOR Workbench**: Headless, fully-tested controller for benchmark jobs and JSON/CSV/PDF report generation.
@@ -344,16 +344,13 @@ cross-validated against reference packages. See `docs/BEYOND_PYMATCHING.md`.
344344
> archived Zenodo datasets listed in `README.md`.
345345
346346
- **`belief_matching.BeliefMatching`** — sum-product BP on the hyperedge detector
347-
graph + QECTOR exact weighted MWPM on the edge graph (belief-matching). Achieves
348-
a **lower logical error rate than PyMatching** on Stim circuit-level shots
349-
(rotated surface, p=0.005): **25.5% LER reduction at d=5** (0.0062 vs 0.0083),
350-
parity at d=3. Verified directly and through Sinter; cross-checked against the
351-
reference `beliefmatching` package.
347+
graph + QECTOR exact weighted MWPM on the edge graph (belief-matching).
348+
Verified directly and through Sinter; cross-checked against the reference
349+
`beliefmatching` package.
352350
- **`bposd.BpOsdDecoder`** — self-contained sum-product BP + ordered-statistics
353351
(OSD-0 / OSD-w) for arbitrary GF(2) / LDPC check matrices, plus LDPC code
354-
families (`codes.bivariate_bicycle_code`, `codes.bicycle_code`). On the
355-
`[[72,12]]` BB code its logical error rate is within ~10% of the reference `ldpc`
356-
package (0.0370 vs 0.0340) and always syndrome-faithful.
352+
families (`codes.bivariate_bicycle_code`, `codes.bicycle_code`). Always
353+
syndrome-faithful, cross-validated against the reference `ldpc` package.
357354
- **`sinter_compat`**`qector_blossom` / `qector_belief` / `qector_unionfind`
358355
exposed as `sinter.Decoder`s, so QECTOR drops into the community-standard
359356
Monte-Carlo harness used to benchmark PyMatching and fusion-blossom.
@@ -385,11 +382,11 @@ This release delivers the complete QECTOR v3 decoder suite with 4 algorithmic ba
385382

386383
| Decoder | Status | Key Feature |
387384
|---------|--------|-------------|
388-
| `UnionFindDecoder` | Stable | Hot-path 1.6 µs, SIMD + pooled allocators |
385+
| `UnionFindDecoder` | Stable | SIMD + pooled allocators, hot-path optimised |
389386
| `BlossomDecoder` | Stable | Edmonds MWPM, exact for d≤7 |
390387
| `SparseBlossomDecoder` | Stable | Region-growing BFS, blossom contraction + shattering, exact DP n≤20 |
391-
| `BPOSDDecoder` | Stable | Belief propagation + ordered statistics, LER 0.086 @ d=5, p=0.05 |
392-
| `NeuralPredecoder` | Stable | MLP Xavier/ReLU, hybrid fallback 35-93% |
388+
| `BPOSDDecoder` | Stable | Belief propagation + ordered statistics (OSD-0/OSD-w) |
389+
| `NeuralPredecoder` | Stable | MLP Xavier/ReLU, hybrid fallback |
393390
| `GNNPredecoder` | Experimental | Message-passing + edge readout, forward pass OK |
394391
| `LookupTableDecoder` | Stable | Exact d=3,5,7 precomputed, SIMD fallback |
395392
| `HybridDecoder` | Stable | Auto-selection per syndrome difficulty |
@@ -405,25 +402,16 @@ This release delivers the complete QECTOR v3 decoder suite with 4 algorithmic ba
405402
- Observability: `consecutive_failures`, `total_failures`, `gpu_recoveries`, `degraded_calls`
406403
- Performance: the "14.6M dec/s @ d=5, batch=10000" figure is **withdrawn** — it
407404
is one of the rows under *Performance Highlights* below, which no surviving
408-
artifact backs. It has now been **replaced by a measurement**, taken through
409-
the same circuit-level pipeline as every other decoder
410-
(`ler.estimate_ler_circuit_level`, one DEM, one sample set, observable-space
411-
scoring) and recorded in `official_benchmark_results.*`:
412-
413-
| d | OpenCL dec/s | CUDA dec/s | GPU LER | PyMatching LER |
414-
|---:|---:|---:|---:|---:|
415-
| 3 | 1,331,565 | 1,285,174 | 0.02215 | 0.01891 |
416-
| 5 | 143,445 | 138,721 | 0.06094 | 0.01596 |
417-
| 11 | 8,153 | 13,405 | ~0.043 | 0.00647 |
418-
| 15 | 2,798 | 4,486 | 0.03760 | 0.00314 |
419-
420-
Read the two columns together. The kernels are genuinely fast — 1.3M dec/s at
421-
`d = 3` — but their logical error rate **stops improving as `d` grows**, which
422-
is the signature of a decoder above threshold: scaling the code does not help
423-
it. That is not a kernel defect. `CUDABatchDecoder`/`OpenCLBatchDecoder` accept
424-
`edge_weights`, and these rows were taken **without** them, so the kernels
425-
decoded topology-only. Pass the DEM's weights (see the README quick-start) for
426-
the accuracy path.
405+
artifact backs. **No measured replacement is published for v0.7.0**: the CUDA
406+
kernel optimisation landed after the last benchmark run, so any figure taken
407+
from that run would describe a different binary. What is documented instead is
408+
behaviour: the kernels accept optional `edge_weights` (the DEM's
409+
`log((1-p)/p)` matching weights), and the weighted configuration is the
410+
accuracy path — pass the weights for the accuracy path (see the README
411+
quick-start). The unweighted configuration is documented as operating above
412+
threshold; it decodes topology-only and its logical error rate does not
413+
improve with distance. No latency or throughput figure for either path is
414+
published with this release.
427415

428416
### Production Infrastructure
429417

@@ -456,19 +444,25 @@ This release delivers the complete QECTOR v3 decoder suite with 4 algorithmic ba
456444
> repeated rounds. Circuit-level LERs quoted elsewhere in this project, and every
457445
> number published by PyMatching, Stim, or Sinter, are a different quantity.
458446
> Placing the two in one table is the methodology error that caused the v0.7.0
459-
> benchmark withdrawal; these rows are retained as release history only. No
460-
> artifact backing them survives, and they must not be cited.
461-
462-
| Metric | Value | Conditions |
463-
|--------|-------|------------|
464-
| Single-shot latency | 1.6 µs | CPU `decode()`, d=5 |
465-
| GPU batch throughput | 14.6M dec/s | d=5, batch=10000, OpenCL |
466-
| CPU batch throughput | 4.1M dec/s | d=5, batch=10000, SIMD |
467-
| BP-OSD LER | 0.086 | d=5, p=0.05, 10k shots |
468-
| UnionFind LER | 0.321 | d=5, p=0.05, 10k shots |
469-
| Blossom LER | 0.198 | d=5, p=0.05, 10k shots |
470-
| Sparse vs Blossom bit-perfect | 100% | d=5, ring code, 100k trials |
471-
| All tests pass | 260+ (Python) + 72 (Rust) | Default + `full` features |
447+
> benchmark withdrawal. **No artifact backs any of the rows this section once
448+
> carried, and none of them may be cited — they are removed outright for
449+
> v0.7.0.** No performance figures are published with this release.
450+
451+
The decoder capabilities this section previously illustrated are:
452+
453+
| Capability | Where it lives |
454+
|------------|----------------|
455+
| CPU single-shot `decode()` with SIMD and pooled allocators | `UnionFindDecoder`, `FastUnionFindDecoder` |
456+
| GPU batch decoding on CUDA and OpenCL, with optional `edge_weights` | `CUDABatchDecoder`, `OpenCLBatchDecoder` |
457+
| CPU parallel batch decoding | `BatchDecoder`, `CPUBatchDecoder` |
458+
| BP-OSD for LDPC/qLDPC check matrices, OSD-0/OSD-w | `BPOSDDecoder`, `BpOsdDecoder` |
459+
| Exact weighted MWPM | `BlossomDecoder` |
460+
| Region-growing sparse MWPM | `SparseBlossomDecoder` |
461+
| Sparse-vs-exact agreement (bit-identical on ring-code trials) | cross-decoder test suite |
462+
463+
These are specifications of what the decoders do, not measurements of how fast
464+
they do it. Measure on your own hardware and archive the artifact before citing
465+
any figure.
472466

473467
---
474468

docs/BENCHMARK_COMPETITIVE.md

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
# Competitive Benchmark — QECTOR vs external decoders (circuit-level)
1+
# Competitive benchmark — QECTOR vs external decoders (circuit-level)
22

3-
Logical-error-rate and decode-latency comparison across rotated-surface-code
4-
memory experiments at circuit-level noise, against **PyMatching 2**, **ldpc BP-OSD**
5-
(OSD-CS, order 0, 30 BP iterations), and **BeliefMatching** (product-sum BP, 20 iters).
3+
> **Withdrawn: no accuracy or latency figures are published for v0.7.0.** The
4+
> result tables that previously lived here were produced on 2026-07-30 against a
5+
> core whose tracked fingerprint (`rust_core.sha256`) has moved twice since
6+
> (Jul 31, Aug 1), and the LER column of the newer workbench dataset was found
7+
> not to be attributable to the decoder named in each row (see the release
8+
> notes). A figure taken from a different binary, or attributed to the wrong
9+
> decoder, is worse than no figure. The methodology below is retained so the
10+
> comparison can be re-run and archived properly.
611
7-
## Setup
12+
## What the comparison covers
13+
14+
A circuit-level comparison of decoding behaviour on rotated-surface-code memory
15+
experiments against external reference decoders:
816

917
- **Circuit**: `stim.Circuit.generated("surface_code:rotated_memory_x", distance=d, rounds=d)`
1018
- **Noise**: circuit-level, `after_clifford_depolarization = before_measure_flip =
@@ -14,65 +22,23 @@ memory experiments at circuit-level noise, against **PyMatching 2**, **ldpc BP-O
1422
same detector pair become one min-weight edge.
1523
- **Decoders**:
1624
- *QECTOR-Blossom* — weighted exact polynomial MWPM (uses `log((1-p)/p)` edge weights).
17-
- *QECTOR-UF*`UnionFindDecoder` (fast, **unweighted** — the weighted variant is
18-
available but not yet used in this benchmark; UF's above-threshold behaviour at
19-
d≥5 is a known consequence of ignoring edge weights at circuit level).
25+
- *QECTOR-UF*`UnionFindDecoder` (fast, unweighted; the weighted variant is
26+
available on the GPU backends and in `uf_core::grow_weighted`).
2027
- *PyMatching*`pymatching.Matching.from_detector_error_model` (reference).
2128
- *ldpc BP-OSD* — external `ldpc.BpOsdDecoder`, OSD-CS order 0, 30 BP iterations.
22-
- *BeliefMatching* — external `beliefmatching.BeliefMatching`, product_sum BP, 20 iters.
23-
- **Shots**: 20 000 per distance for d ≤ 5; 10 000 for d = 7.
24-
LER intervals are Wilson 95%.
25-
- **Environment**: AMD Ryzen, Python 3.11, NumPy 2.2.6, Stim 1.16.0,
26-
PyMatching 2.4.0, ldpc 0.2.10+, beliefmatching 0.1.x.
27-
28-
## Results
29-
30-
| d | rounds | shots | det | QECTOR-Blossom LER | PyMatching LER | QECTOR-UF LER | ldpc BP-OSD LER | BeliefMatching LER | QB µs | PM µs | LDPC µs | BM µs |
31-
|---|--------|-------|-----|--------------------|----------------|---------------|------------------|---------------------|-------|-------|---------|-------|
32-
| 3 | 3 | 20000 | 24 | 0.01225 [0.01082, 0.01387] | 0.01225 [0.01082, 0.01387] | 0.01465 | 0.01225 [0.01082, 0.01387] | 0.00985 [0.00857, 0.01132] | 0.5 | 0.4 | 14.3 | 84.1 |
33-
| 5 | 5 | 20000 | 120 | 0.00745 [0.00635, 0.00874] | 0.00745 [0.00635, 0.00874] | 0.03845 | 0.00800 [0.00686, 0.00933] | 0.00575 [0.00479, 0.00690] | 9.0 | 2.8 | 341.1 | 2541.2 |
34-
| 7 | 7 | 10000 | 336 | 0.00430 [0.00319, 0.00579] | 0.00440 [0.00328, 0.00590] | 0.02000 | 0.00460 [0.00345, 0.00613] | 0.00290 [0.00202, 0.00416] | 44.6 | 8.1 | 2240.6 | 13953.1 |
35-
36-
### Higher distances (QECTOR-Blossom / PyMatching / QECTOR-UF only)
37-
38-
BP-based decoders become prohibitively slow beyond d = 7 on this machine.
39-
The table below reproduces the earlier head-to-head for reference:
40-
41-
| d | rounds | shots | det | QECTOR-Blossom LER | PyMatching LER | QECTOR-UF LER | QB µs | PM µs | UF µs |
42-
|---|--------|-------|-----|--------------------|----------------|---------------|-------|-------|-------|
43-
| 9 | 9 | 40000 | 786 | 0.0030 [0.0025, 0.0036] | 0.0031 [0.0026, 0.0036] | 0.0214 | 103.1 | 22.0 | 11.8 |
44-
| 11 | 11 | 40000 | 1470 | 0.0018 [0.0015, 0.0023] | 0.0018 [0.0015, 0.0023] | 0.0161 | 230.4 | 56.5 | 26.5 |
45-
46-
## What the data says
47-
48-
**Accuracy parity holds across all three MWPM decoders.** QECTOR-Blossom and
49-
PyMatching produce statistically identical LER at every distance (overlapping
50-
Wilson 95% intervals). **ldpc BP-OSD** matches within CI as well, with a slight
51-
edge at d = 3 but wider intervals. **BeliefMatching** shows numerically lower LER
52-
at all three distances (marginally overlapping CIs), consistent with the
53-
literature result that BP+post-processing can out-gate MWPM on surface codes
54-
when BP converges.
55-
56-
**UF is above threshold at circuit level.** Unweighted Union-Find's LER rises
57-
from 1.47 % (d = 3) to 3.85 % (d = 5), confirming that ignoring edge weights
58-
from `log((1-p)/p)` is catastrophic for circuit-level accuracy. The weighted UF
59-
variant (UF-01, available in the Rust core) would close most of this gap — the
60-
benchmark script has not yet been updated to use it (C2-04 tracks this).
61-
62-
**Latency spread is wide.** The four MWPM-class decoders span three orders of
63-
magnitude:
64-
| Decoder | d = 3 | d = 5 | d = 7 |
65-
|---------|-------|-------|-------|
66-
| QECTOR-UF | 0.3 µs | 1.5 µs | 4.3 µs |
67-
| PyMatching | 0.4 µs | 2.8 µs | 8.1 µs |
68-
| QECTOR-Blossom | 0.5 µs | 9.0 µs | 44.6 µs |
69-
| ldpc BP-OSD | 14.3 µs | 341.1 µs | 2240.6 µs |
70-
| BeliefMatching | 84.1 µs | 2541.2 µs | 13953.1 µs |
71-
72-
BP-based decoders are 10–300× slower than MWPM at circuit level, and the gap
73-
widens with distance as BP's O(edges × iters) cost grows faster than MWPM's
74-
O(detectors × mean-degree). BeliefMatching is an additional ~6× slower than
75-
ldpc BP-OSD at every distance.
29+
- *BeliefMatching* — external `beliefmatching.BeliefMatching`, product-sum BP, 20 iters.
30+
31+
## How results are produced
32+
33+
- LER is scored with Wilson 95% intervals; the shot counts per cell and the
34+
environment (Python version, NumPy, Stim, PyMatching, ldpc, beliefmatching
35+
versions, host CPU) are recorded with the artifact.
36+
- The long-standing qualitative findings of the earlier run are unchanged and
37+
are not withdrawn: unweighted Union-Find operates above threshold at
38+
circuit level (ignoring edge weights is known to cost accuracy — the weighted
39+
variant exists to close that gap), and PyMatching remains the latency
40+
reference for plain exact MWPM. No magnitude is claimed here; the artifacts
41+
must be re-measured before any number is quoted.
7642

7743
## Reproduce
7844

0 commit comments

Comments
 (0)