Skip to content

Commit 07966e4

Browse files
committed
docs: neutral technical register for the GPU and benchmark sections
Rewrites the README findings and the CHANGELOG GPU entry as declarative statements of what was measured, removing editorial framing. Corrects a factual error introduced earlier in this cycle: the README asserted that CUDABatchDecoder and OpenCLBatchDecoder take no edge_weights argument. They accept one. Omitting it is a configuration choice that selects topology-only cluster growth, which is what produces the above-threshold behaviour reported in the same section - not an absent capability. The corrected text states both configurations and their measured cost.
1 parent e8af8f3 commit 07966e4

2 files changed

Lines changed: 42 additions & 36 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ reading the tree.
2020
the CPU backends — not from a separate harness. This produces the weighted-GPU
2121
logical error rate that the README previously recorded as unquotable for want
2222
of a surviving artifact.
23-
- **What the measurement says.** Unweighted GPU is fast and *above threshold*:
24-
its LER stops improving as `d` grows (0.059 at `d = 5`, 0.048 at 9, 0.035 at
25-
13), so scaling the code does not help it. Weighted GPU is below threshold —
26-
0.026 → 0.010 → 0.007 over the same range — at roughly 32x the cost. Quote a
27-
GPU throughput number together with its LER or not at all.
23+
- **Measured behaviour.** The unweighted configuration operates above threshold:
24+
its logical error rate does not improve as `d` grows (0.059 at `d = 5`, 0.048
25+
at 9, 0.035 at 13), so increasing code distance does not help it. The weighted
26+
configuration is below threshold — 0.026 → 0.010 → 0.007 over the same range —
27+
at roughly 32× the cost per shot. GPU throughput and GPU logical error rate
28+
should be cited together.
2829
- **Weighted growth kernel: 1.40x–1.57x faster, bit-identical output.** Per round
2930
the weighted loop ran an O(n_checks) scan plus three O(E) sweeps for up to
3031
`E+N+2` rounds, and passes A and B each walked two parent chains per edge with
@@ -36,12 +37,13 @@ reading the tree.
3637
Verified by capturing every correction from the pre-change build across
3738
`d = 5/9/13` × 2048 shots and asserting byte-equality after: *bit-identical
3839
across 12 arrays*, with CUDA-vs-CPU agreement unchanged to the digit.
39-
- **Known and not hidden:** weighted GPU is *not* bit-identical to weighted CPU,
40-
and diverges further with distance (67% → 14% → 0.24% shot agreement at
41-
`d = 5/9/13`). The kernel grows in `f32` and `uf_core::grow_weighted` in `f64`,
42-
so `dt` differences compound over thousands of rounds into different — often
43-
equally valid — fusion orders. Pre-existing, unrelated to the optimisation
44-
above, and stated here rather than left for a user to discover.
40+
- **Numerical divergence from the CPU path.** Weighted GPU output is not
41+
bit-identical to weighted CPU, and the two diverge further with distance
42+
(67% → 14% → 0.24% per-shot agreement at `d = 5/9/13`). The kernel grows in
43+
`f32` and `uf_core::grow_weighted` in `f64`, so `dt` differences compound over
44+
thousands of rounds into different — and frequently equally valid — fusion
45+
orders. This behaviour pre-dates, and is unrelated to, the optimisation
46+
described above.
4547

4648
### Benchmarks — corrected artifacts, and what they say
4749
- **`official_benchmark_results.{json,csv,md,pdf}` were regenerated.** The first

README.md

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -468,31 +468,35 @@ The full 137-row table — every shot count, plus the 73 cells that exceeded the
468468
per-cell budget and were therefore *not measured* — is in
469469
`official_benchmark_results.md`.
470470

471-
Findings, stated per-cell and not generalised (see
472-
`docs/REPRODUCIBILITY_CHECKLIST.md`):
473-
474-
- **`qector_blossom` matches PyMatching exactly.** At `d = 3` and `d = 5` both
475-
returned the same number of logical failures on the same 100,000 samples —
476-
1891 and 1596. Identical to the digit, which is a checkable claim.
477-
- **PyMatching leads on throughput at every distance measured**, consistent
478-
with the long-standing note elsewhere in this project that it leads on plain
479-
MWPM. Not a regression, and not hidden.
480-
- **The GPU kernels are fast and above threshold.** `qector_cuda` reaches
481-
1.29M dec/s at `d = 3`, but its LER *stops improving with distance*: 0.061 at
482-
`d = 5`, 0.043 at `d = 7`, 0.038 at `d = 15`, against PyMatching's 0.016 →
483-
0.012 → 0.0031 over the same range. A decoder whose logical error rate
484-
plateaus while `d` grows is above threshold — scaling the code does not help
485-
it. The cause is not the kernel: `CUDABatchDecoder`/`OpenCLBatchDecoder` take
486-
`(check_to_qubits, n_qubits)` and no `edge_weights`, so they decode
487-
topology-only. `docs/BENCHMARK_COMPETITIVE.md` records the same effect for
488-
unweighted Union-Find on CPU. Weighted UF (UF-01) exists in the Rust core and
489-
is the path to closing it.
490-
- CUDA and OpenCL returned identical logical-failure counts wherever both ran
491-
the same cell, consistent with the bit-identity claim made elsewhere.
492-
493-
**Do not quote a GPU throughput figure without its LER.** The two GPU columns
494-
above are the reason: on speed alone they look like the headline result, and on
495-
accuracy they are not yet usable for scaling a surface code.
471+
Findings apply to the cells listed above and are not generalised beyond them
472+
(see `docs/REPRODUCIBILITY_CHECKLIST.md`).
473+
474+
**Accuracy parity with PyMatching.** At `d = 3` and `d = 5`, `qector_blossom`
475+
and PyMatching 2 recorded identical logical-failure counts on identical sample
476+
sets — 1891 and 1596 in 100,000 shots respectively.
477+
478+
**Throughput.** PyMatching 2 leads at every distance measured here. This is
479+
consistent with the position recorded elsewhere in this project that PyMatching
480+
leads on plain MWPM.
481+
482+
**GPU accuracy depends on whether matching weights are supplied.**
483+
`CUDABatchDecoder` and `OpenCLBatchDecoder` accept an optional `edge_weights`
484+
argument. Omitting it selects topology-only cluster growth, and the resulting
485+
logical error rate does not improve with code distance — 0.061 at `d = 5`,
486+
0.043 at `d = 7`, 0.038 at `d = 15` — which is the signature of operation above
487+
threshold. Supplying the DEM's `log((1-p)/p)` weights restores distance
488+
scaling: 0.026 at `d = 5`, 0.010 at `d = 9`, 0.007 at `d = 13`. The weighted
489+
path costs roughly 32× the throughput of the unweighted one.
490+
`docs/BENCHMARK_COMPETITIVE.md` records the same effect for unweighted
491+
Union-Find on CPU. See the quick-start above for the weighted construction.
492+
493+
**Backend agreement.** CUDA and OpenCL returned identical logical-failure counts
494+
in every cell where both ran, consistent with the bit-identity property recorded
495+
elsewhere in this project.
496+
497+
GPU throughput and GPU logical error rate should be cited together. The
498+
unweighted configuration is the fastest column in the table and simultaneously
499+
the least accurate; either figure alone misrepresents it.
496500

497501
Neither finding generalises beyond the cells above. Regenerate on quiesced
498502
hardware, and state the noise model, before any number here is used in a claim.

0 commit comments

Comments
 (0)