Add boundary-aware overloads for canonicalize_for_rounds and sliding window decoder#656
Add boundary-aware overloads for canonicalize_for_rounds and sliding window decoder#656eliotheinrich wants to merge 6 commits into
Conversation
… window decoder Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
| const std::vector<double> &weights, | ||
| std::uint32_t num_syndromes_per_round = 0); | ||
|
|
||
| namespace details { |
There was a problem hiding this comment.
Can you please move this section to a .cpp file? I don't think it needs to be in a public header file if we are calling it an "internal helper".
There was a problem hiding this comment.
I can, but I deliberately left it accessible here so that the round layout logic can be shared here and in the sliding window decoder (and perhaps other places that may need a mapping between rounds and detector indices): https://github.com/NVIDIA/cudaqx/pull/656/changes#diff-30af01af4513a257ae4040df674193bc2cce9d3ce09e81adc3493db11a0dba4dR60.
Open to moving it to a .cpp file if we'd rather not expose it.
There was a problem hiding this comment.
In that case, I'd recommend 2 things.
- Pull them into a private header file (not in the
libs/qec/includedirectory because that entire directly should only contain our public interfaces that we are committed to maintaining some form of backwards compatibility on). I'd recommendlibs/qec/lib. - Only put the declarations in header files and put implementations in .cpp files. Implementations in header files can lead to duplicate symbols and general compilation bloat since every target compilation unit must recompile the source code. We should only do that when it is trivial code or needed by for templates.
If you do the above 2 things, I believe the sliding window decoder and other internal code can use it.
Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
Signed-off-by: Eliot Heinrich <eheinrich@nvidia.com>
Description
Closes #649
The addition of boundary detectors offsets the syndromes output by memory circuit experiments by introducing
num_boundary_syndromesat the beginning and end of the syndrome block. The means thatcanonicalize_for_roundsstraddles the new boundaries between rounds, leading to error mechanisms being associated to incorrect rounds when the boundary syndromes have a different length than the inter-round syndromes. This is a cosmetic error for PCMs representing entire memory circuits, but is incorrect when followed up withget_pcm_for_roundsfor the purpose of, i.e., the sliding window decoder.This PR adds round-aware overloads to
canonicalize_for_roundsand the sliding window decoder, bringing them up-to-date with syndrome format.canonicalize_for_roundshas a new overload which acceptsnum_boundary_syndromes, which appropriately treats the first and lastnum_boundary_syndromescolumns as distinct rounds for the purpose of round-based topological sorting.The sliding window decoder now takes an additional parameter
num_boundary_syndromes(default 0). The PCM of the decoder is zero-padded to have uniform widthnum_syndromes_per_round. Syndromes passed to the decoder are automatically padded to the uniform length. Ifnum_boundary_syndromesis 0, then the boundary syndromes are presumed to be the same width as the interior syndromes (as is the case in X/Z-only experiments).New tests:
test_qec.cpp:PCMUtilsTester.checkGetSortedColumnIndicesWithBoundary: Verifies the boundary-aware column sort orderstest_qec.cpp:DetectorErrorModelTest.CanonicalizeBoundaryRejectsWideBoundary: Assertrscanonicalize_for_rounds(S, B, ...)throws when the boundary is wider than the interior (B > S).test_decoders.cpp::SlidingWindowDecoder.PreparePcmRejectsBadBoundaryLayout: Confirms the sliding-window decoder throws during construction for inconsistent boundary layouts (B > S, or a row count that can't fit[B | K·S | B]).test_qec_stim.cpp::QECCodeTester.checkDemFromMemoryCircuitShor9: Checks the Shor [[9,1,3]] full DEM has the expected non-uniform shape, consistent column counts, and correct round ordering.test_qec_stim.cpp::QECCodeTester.checkSlidingWindowShor9Boundary: A single all-rounds window decoding the Shor boundary DEM must match a full decoder for every DEM column.test_qec_stim.cpp:QECCodeTester.checkSlidingWindowShor9Streaming: Streams variable-width detector layers for X(Z) (6(2) at boundaries, 8 interior) through a sliding config (window=2, step=1) and requires results to match a full decoder.test_sliding_window.py::test_sliding_window_boundary_layout: Parametrized over 3 codes × 3 window counts; injects errors over 300 shots and asserts sliding-window observable predictions match a single_error_lut full decoder.Runtime / performance impact
N/A
Self-review checklist
Please confirm each item before requesting review. Check
[x]or strikethrough and explain.
Before requesting review
Scope and size
(if so, an issue has been raised).
Tests
just when it is missing.
EXPECT_*/assertchecks areinsufficient for algorithmic correctness.
Documentation
tracked.
Code style
snake_casevscamelCase) forthe area being modified.
Dependencies
OSRB tickets filed.