From 907783ef615cdf52b37f38117ef25303da4de622 Mon Sep 17 00:00:00 2001 From: Daniel Gaskins Date: Fri, 14 Aug 2026 16:13:03 -0700 Subject: [PATCH] Handle strided arrays in Sinter decoding --- src/py/tesseract_sinter_compat_test.py | 38 ++++++++++++++++++++++++++ src/tesseract_sinter_compat.pybind.h | 13 ++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/py/tesseract_sinter_compat_test.py b/src/py/tesseract_sinter_compat_test.py index 1fc3413c..8842e557 100644 --- a/src/py/tesseract_sinter_compat_test.py +++ b/src/py/tesseract_sinter_compat_test.py @@ -162,6 +162,44 @@ def test_decode_shots_bit_packed_multi_shot(): assert np.array_equal(predictions, expected_predictions) +def test_decode_shots_bit_packed_with_strided_input(): + dem = stim.DetectorErrorModel(""" + error(0.1) D0 D1 L0 + error(0.1) D8 L1 + detector D0 + detector D1 + detector D2 + detector D3 + detector D4 + detector D5 + detector D6 + detector D7 + detector D8 + """) + compiled_decoder = TesseractSinterDecoder().compile_decoder_for_dem(dem=dem) + + storage = np.zeros((2, 4), dtype=np.uint8) + detections = storage[:, ::2] + assert not detections.flags.c_contiguous + detections[0] = [0b00000011, 0] + detections[1] = [0, 0b00000001] + + predictions = compiled_decoder.decode_shots_bit_packed( + bit_packed_detection_event_data=detections + ) + + assert np.array_equal( + predictions, + np.array( + [ + [0b00000001], + [0b00000010], + ], + dtype=np.uint8, + ), + ) + + def test_decode_via_files_sanity_check(): """ Tests the 'decode_via_files' method by simulating a small circuit and diff --git a/src/tesseract_sinter_compat.pybind.h b/src/tesseract_sinter_compat.pybind.h index aecaa6b8..e1fb09a0 100644 --- a/src/tesseract_sinter_compat.pybind.h +++ b/src/tesseract_sinter_compat.pybind.h @@ -62,23 +62,20 @@ struct TesseractSinterCompiledDecoder { py::array_t({(py::ssize_t)num_shots, (py::ssize_t)num_observable_bytes}); auto result_buffer = result_array.mutable_data(); - const uint8_t* detections_data = bit_packed_detection_event_data.data(); - const size_t detections_stride = bit_packed_detection_event_data.strides(0); + auto detections = bit_packed_detection_event_data.unchecked<2>(); // Loop through each shot and decode it with TesseractDecoder. for (size_t shot = 0; shot < num_shots; ++shot) { - const uint8_t* single_shot_data = detections_data + shot * detections_stride; - // Unpack the shot data into a vector of indices of fired detectors. - std::vector detections; + std::vector fired_detectors; for (uint64_t i = 0; i < num_detectors; ++i) { - if ((single_shot_data[i / 8] >> (i % 8)) & 1) { - detections.push_back(i); + if ((detections(shot, i / 8) >> (i % 8)) & 1) { + fired_detectors.push_back(i); } } // Decode with TesseractDecoder. - std::vector predictions = decoder->decode(detections); + std::vector predictions = decoder->decode(fired_detectors); // Store predictions into the output buffer uint8_t* single_result_buffer = result_buffer + shot * num_observable_bytes;