Repository navigation
feat(bp): add BP+OSD decoder package and wire into pipeline dispatcher - #9
Merged
Merged
Conversation
Belief propagation on the surface-code detector graph, via the `ldpc` library. Mirrors the public interface of the `mwpm` package so the two decoders can be swapped through decode_hardware_results(). By default build_bp_decoder() returns an ldpc.BpOsdDecoder with osd_order=2 (BP+OSD, the practical working point for QEC). Plain loopy BP converges to a stable but sub-optimal fixed point on surface codes because of short cycles; OSD post-processes the BP result and matches MWPM exactly at d=3, p=0.001. Set osd_order=0 to disable OSD and study the failure modes. Three public functions: - dem_to_pcm(circuit) -- stim DEM -> (H, O, channel_probs) - build_bp_decoder(circuit) -- returns (BpOsdDecoder, O); amortize. - decode_hardware_results_bp(syndromes, decoder=..., O=...) -> (ler, err, confidence). Confidence is a soft LLR-derived indicator, not a calibrated posterior. Smoke test (python -m bp.smoke_test) at d=3, 3 rounds, p=0.001, 5000 shots: - BP-OSD LER = 0.0012 +/- 0.0005 (6/5000) - MWPM LER = 0.0012 +/- 0.0005 (6/5000) - Identical. The package intentionally does not mirror diffqec's full file layout: there is no model, no training, no data.py, no soft confidence wrapper. Just two functions in one module. The README documents this in a comparison table, same as mwpm/README.md.
decode_hardware_results() now accepts decoder="bp". Two new kwargs (bp_decoder, bp_O) let callers pre-build the BpOsdDecoder and observable matrix, the LUMI-sweep pattern. The dispatcher ValueError message is updated to list all three supported decoders. ldpc>=2.4 is added to both requirements.txt and pyproject.toml; the BpOsdDecoder class is in ldpc v2.x and not in v1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
bp/package that decodes syndromes with belief propagation (BP+OSD) on the same stim DEM that MWPM uses. Mirrors the diffqec and mwpm pipeline contracts so all three decoders can be swapped throughdecode_hardware_results(decoder=...).bp/integrate.py:dem_to_pcm(circuit)(stim DEM -> (H, O, channel_probs)),build_bp_decoder(circuit)(returns aBpOsdDecoder+ observable matrix; amortize),decode_hardware_results_bp(syndromes, decoder=..., O=...)(decode + LER + soft confidence).bp/__init__.py: re-exports.bp/smoke_test.py: one-shot runnable with side-by-side BP-vs-MWPM comparison.bp/README.md: usage + the BP-vs-BP+OSD caveat + comparison table.run_on_hardware.py: fills thedecoder="bp"branch indecode_hardware_results, adds two kwargs (bp_decoder,bp_O) for the LUMI-sweep case.requirements.txt+pyproject.toml: addldpc>=2.4(BpOsdDecoder lives in v2.x).Why BP+OSD, not plain BP
Vanilla loopy BP converges to a stable but sub-optimal fixed point on surface codes because of short cycles in the factor graph. Empirically 3-4x worse than MWPM at d=3, p=0.001. BP+OSD with
osd_order=2post-processes the BP result and matches MWPM exactly. This is the standard practical fix in the QEC literature; the convergence issue on qLDPC codes is documented in Yao et al. 2023 (arXiv:2312.10950). Setosd_order=0to disable OSD and study the failure modes.Why BP+OSD, not just MWPM
Same factor graph as MWPM, but with soft outputs:
confidence[i, j]isP(observable_j = predicted_j | syndrome_i), derived from the LLR of the BP result projected onto the observable. This unlocks the analysis axes that the bonus criteria mention:Verification
Smoke test (d=3, 3 rounds, p=0.001, 5000 shots, stim built-in):
The dispatcher (
decode_hardware_results(decoder="bp", stim_circuit_noisy=...)anddecoder="bp", bp_decoder=..., bp_O=...)) was also tested and returns the same LER for both kwargs. Unknown decoder raisesValueError.On the diffqec mismatch
Like
mwpm/, this package does not mirror diffqec's full file layout: there is no model, no training, no data.py, no soft confidence wrapper. Just two functions in one module. The README documents this in a comparison table.Dependency chain
This PR is stacked on top of
feat/mwpm-decoder(PR #6) since therun_on_hardware.pychanges are layered. If PR #6 is merged first, this one can be rebased ontomaincleanly.