Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d09d691
Restructure Python packaging
oscarhiggott May 21, 2026
fc6cf81
Add update_internal_costs to TesseractDecoder
oscarhiggott May 21, 2026
4b473c6
Add multi-pass infrastructure libraries
oscarhiggott May 21, 2026
c182767
Add multi-pass Tesseract decoder
oscarhiggott May 21, 2026
c699816
feat(multipass): C++ multi-pass engine fixes, degenerate error mappin…
aria-googler Jul 28, 2026
fe6d8ba
fix: address PR #256 review comments on timing and test restoration
aria-googler Jul 29, 2026
56b667f
build: link multi_pass_tesseract_decoder in CMake tesseract target
aria-googler Jul 29, 2026
ac142ec
fix(tesseract): handle empty detector sets and bounds check in update…
aria-googler Jul 29, 2026
b4d966a
build: fix CI VM instruction crash by defaulting to -march=x86-64-v3
aria-googler Jul 29, 2026
7dbd1b8
fix(cli/multipass): address reviewer comments on multi-pass decoding
aria-googler Jul 29, 2026
c367e9b
fix(multipass): fix method call to cost_from_errors and dem_out_fname…
aria-googler Jul 29, 2026
fbfe35a
cleanup for making the PR leaner
arshpreetmaan Jul 29, 2026
7c86012
Restore existing Python package structure
arshpreetmaan Jul 31, 2026
53b9779
fix(bug): reject zero-pass multipass decoders
arshpreetmaan Jul 31, 2026
05063ad
fix: address clang-format issue
arshpreetmaan Jul 31, 2026
175f0e8
fix(multipass): enforce supported pass count
arshpreetmaan Aug 9, 2026
f2d3a5c
fix(multipass): validate cached detector assignments
arshpreetmaan Aug 9, 2026
9b72ab4
fix(multipass): reject inconsistent observable decompositions
arshpreetmaan Aug 9, 2026
ef76d41
fix(multipass): preserve observable identity in correlations
arshpreetmaan Aug 9, 2026
a83c68a
feat(multipass): expose execution plan
arshpreetmaan Aug 9, 2026
c9bdc7a
Merge remote-tracking branch 'upstream/main' into PR-256-fixes
arshpreetmaan Aug 9, 2026
74db462
fix(multipass): report final-pass cost
arshpreetmaan Aug 9, 2026
f4cc070
fix(multipass): tighten decode API
arshpreetmaan Aug 9, 2026
7d9eea0
fix(multipass): default to causal scheduling
arshpreetmaan Aug 9, 2026
f1b91d7
fix(cli): remove wall-clock timing field
arshpreetmaan Aug 10, 2026
2824cbd
Merge latest main build fixes into multi-pass decoding
arshpreetmaan Aug 16, 2026
365f748
feat(multipass): add measure_basis tag support to detector classifier
Aug 17, 2026
2b8556a
Fix multipass metadata classifier fallbacks
arshpreetmaan Aug 17, 2026
58a3275
Report multipass component matrix statistics
arshpreetmaan Aug 17, 2026
adf1bf4
Simplify multipass plan statistics
arshpreetmaan Aug 17, 2026
4415ca0
Enforce strict X/Z detector metadata
arshpreetmaan Aug 18, 2026
3cca16d
Collect multipass plan statistics only when requested
arshpreetmaan Aug 18, 2026
f0493cc
Standardize detector ordering on DetIndex
arshpreetmaan Aug 20, 2026
8f07c64
Clarify multipass execution plan statistics
arshpreetmaan Aug 20, 2026
6097f65
Clarify long-beam multipass Sinter configurations
arshpreetmaan Aug 21, 2026
3f120f4
Remove redundant Bernoulli merge utilities
arshpreetmaan Aug 21, 2026
95a9e10
Document supported multipass interfaces
arshpreetmaan Aug 21, 2026
aa0a891
Merge branch 'main' into multi-pass-decoding
noajshu Aug 21, 2026
860114a
Refactor multipass sources into a dedicated subfolder
arshpreetmaan Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ py_wheel(
deps=[
"//src:tesseract_decoder",
"//src/py:generated_stubs",
"//src/py:multi_pass_sinter_decoders",
"//src/py/_tesseract_py_util:_tesseract_py_util",
":package_data",
],
version = "$(VERSION)",
requires=[
"numpy",
"scipy",
"sinter",
"stim",
],
python_tag="$(TARGET_VERSION)",
Expand All @@ -51,3 +53,9 @@ config_setting(
"@platforms//cpu:arm64",
],
)

filegroup(
name = "testdata",
srcs = glob(["testdata/**/*"]),
visibility = ["//visibility:public"],
)
41 changes: 39 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ target_include_directories(visualization PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(visualization PRIVATE ${OPT_COPTS})
target_link_libraries(visualization PUBLIC common boost_headers)

add_library(error_correlations ${TESSERACT_SRC_DIR}/multi_pass/error_correlations.cc ${TESSERACT_SRC_DIR}/multi_pass/error_correlations.h)
target_include_directories(error_correlations PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(error_correlations PRIVATE ${OPT_COPTS})
target_link_libraries(error_correlations PUBLIC libstim)

add_library(tanner_graph ${TESSERACT_SRC_DIR}/multi_pass/tanner_graph.cc ${TESSERACT_SRC_DIR}/multi_pass/tanner_graph.h)
target_include_directories(tanner_graph PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(tanner_graph PRIVATE ${OPT_COPTS})
target_link_libraries(tanner_graph PUBLIC libstim)

add_library(dem_decomposition ${TESSERACT_SRC_DIR}/multi_pass/dem_decomposition.cc ${TESSERACT_SRC_DIR}/multi_pass/dem_decomposition.h)
target_include_directories(dem_decomposition PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(dem_decomposition PRIVATE ${OPT_COPTS})
target_link_libraries(dem_decomposition PUBLIC libstim)

add_library(multi_pass_tesseract_decoder ${TESSERACT_SRC_DIR}/multi_pass/multi_pass_tesseract_decoder.cc ${TESSERACT_SRC_DIR}/multi_pass/multi_pass_tesseract_decoder.h)
target_include_directories(multi_pass_tesseract_decoder PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(multi_pass_tesseract_decoder PRIVATE ${OPT_COPTS})
target_link_libraries(multi_pass_tesseract_decoder PUBLIC common tesseract_lib tanner_graph error_correlations dem_decomposition libstim)

add_library(tesseract_lib ${TESSERACT_SRC_DIR}/tesseract.cc ${TESSERACT_SRC_DIR}/tesseract.h)
target_include_directories(tesseract_lib PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(tesseract_lib PRIVATE ${OPT_COPTS})
Expand All @@ -114,7 +134,7 @@ target_link_libraries(simplex PUBLIC common utils tesseract_lib highs libstim Th
# === Executables ===
add_executable(tesseract ${TESSERACT_SRC_DIR}/tesseract_main.cc)
target_compile_options(tesseract PRIVATE ${OPT_COPTS})
target_link_libraries(tesseract PRIVATE tesseract_lib argparse::argparse nlohmann_json::nlohmann_json)
target_link_libraries(tesseract PRIVATE tesseract_lib multi_pass_tesseract_decoder argparse::argparse nlohmann_json::nlohmann_json)

add_executable(tesseract_trellis ${TESSERACT_SRC_DIR}/tesseract_trellis_main.cc)
target_compile_options(tesseract_trellis PRIVATE ${OPT_COPTS})
Expand All @@ -131,7 +151,7 @@ target_link_libraries(simplex_bin PRIVATE common simplex argparse::argparse nloh
pybind11_add_module(tesseract_decoder MODULE ${TESSERACT_SRC_DIR}/tesseract.pybind.cc)
target_compile_options(tesseract_decoder PRIVATE ${OPT_COPTS})
target_include_directories(tesseract_decoder PRIVATE ${TESSERACT_SRC_DIR})
target_link_libraries(tesseract_decoder PRIVATE common utils simplex tesseract_lib)
target_link_libraries(tesseract_decoder PRIVATE common utils simplex tesseract_lib multi_pass_tesseract_decoder)
set_target_properties(tesseract_decoder PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/src
Expand All @@ -154,3 +174,20 @@ add_test(NAME tesseract_test COMMAND tesseract_test)
add_executable(tesseract_trellis_test ${TESSERACT_SRC_DIR}/tesseract_trellis.test.cc)
target_link_libraries(tesseract_trellis_test PRIVATE tesseract_trellis_lib GTest::gtest_main)
add_test(NAME tesseract_trellis_test COMMAND tesseract_trellis_test)

add_executable(dem_decomposition_test ${TESSERACT_SRC_DIR}/multi_pass/dem_decomposition.test.cc)
target_link_libraries(dem_decomposition_test PRIVATE dem_decomposition GTest::gtest_main libstim)
add_test(NAME dem_decomposition_test COMMAND dem_decomposition_test)

add_executable(tanner_graph_test ${TESSERACT_SRC_DIR}/multi_pass/tanner_graph.test.cc)
target_link_libraries(tanner_graph_test PRIVATE tanner_graph GTest::gtest_main libstim)
add_test(NAME tanner_graph_test COMMAND tanner_graph_test)

add_executable(error_correlations_test ${TESSERACT_SRC_DIR}/multi_pass/error_correlations.test.cc)
target_link_libraries(error_correlations_test PRIVATE error_correlations GTest::gtest_main libstim)
add_test(NAME error_correlations_test COMMAND error_correlations_test)

add_executable(multi_pass_tesseract_decoder_test ${TESSERACT_SRC_DIR}/multi_pass/multi_pass_tesseract_decoder.test.cc)
target_link_libraries(multi_pass_tesseract_decoder_test PRIVATE multi_pass_tesseract_decoder GTest::gtest_main libstim)
add_test(NAME multi_pass_tesseract_decoder_test COMMAND multi_pass_tesseract_decoder_test)
set_tests_properties(multi_pass_tesseract_decoder_test PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,67 @@ errors are not capped by degree.
* *DEM usage frequency output*: if `--dem-out` is specified, outputs estimated error frequencies.
* *Statistics output*: includes number of shots, errors, low confidence shots, and processing time.

---

## Multi-Pass Graph Shattering

Multi-pass graph shattering partitions a correlated detector error model into two detector
components and decodes the smaller component models separately. With two passes, predictions from
the first pass update error priors used during the final pass. The current implementation requires
exactly two components and accepts one or two passes.

### Detector classification

The CLI classifier checks the following detector annotations in order:

1. A `"measure_basis"` field in the detector's JSON metadata tag, first at the top level and then
under `"md"`.
2. A `"basis"` field in the same locations.
3. A fourth detector coordinate using the Chromobius-style `color + 3 * basis` convention:
values `0`–`2` select component 0 and values `3`–`5` select component 1.

Metadata basis values must be strings exactly equal to `"X"` or `"Z"`. An invalid metadata value
does not fall back to another field or to coordinates. Multi-pass decoding fails if any detector
cannot be classified or if the resulting classification does not contain exactly two components.
The Python wrapper can instead be given a custom detector classifier.

### CLI options

* `--multipass`: Enables multi-pass graph shattering.
* `--num-passes`, `--num_passes`: Selects one or two passes (default: 2). One pass performs no
inter-pass prior update; two passes perform one round of prior propagation. Other values are
rejected.
* `--multipass-strategy`, `--multipass_strategy`: Selects `causal` (default), which derives the pass
schedule from component dependencies, or experimental `static`, which schedules both components
in every pass.
* `--print-multipass-plan`: Prints the monolithic and component model statistics, dependencies, and
pass schedule to standard error. It requires `--multipass`; these statistics are calculated only
when this flag is present.

`--dem-out` is not supported with `--multipass`.

### CLI example

This example uses a coordinate-annotated color-code circuit and the long-beam settings:

```bash
./bazel-bin/src/tesseract \
--circuit testdata/colorcodes/r=5,d=5,p=0.003,noise=si1000,c=midout_color_code_X,q=23,gates=cz.stim \
--sample-num-shots 1000 \
--multipass \
--num-passes 2 \
--multipass-strategy causal \
--pqlimit 1000000 \
--beam 20 \
--beam-climbing \
--no-revisit-dets \
--num-det-orders 21 \
--print-multipass-plan \
--print-stats
```

---

## Python Interface

[Full Python wrapper documentation](src/py/README.md)
Expand Down
105 changes: 105 additions & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,15 @@ pybind_library(
"visualization.pybind.h",
"tesseract.pybind.h",
"tesseract_sinter_compat.pybind.h",
"multi_pass/multi_pass_sinter_compat.pybind.h",
],
copts = OPT_COPTS,
deps = [
":libcommon",
":libutils",
":libsimplex",
":libtesseract",
":libmulti_pass_tesseract_decoder",
],
)

Expand Down Expand Up @@ -171,13 +173,116 @@ cc_library(
],
)

cc_library(
name = "libmulti_pass_tesseract_decoder",
srcs = ["multi_pass/multi_pass_tesseract_decoder.cc"],
hdrs = ["multi_pass/multi_pass_tesseract_decoder.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
":libcommon",
":libtesseract",
":libtanner_graph",
":liberror_correlations",
":libdem_decomposition",
"@stim//:stim_lib",
],
)

cc_test(
name = "multi_pass_tesseract_decoder_tests",
srcs = ["multi_pass/multi_pass_tesseract_decoder.test.cc"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
data = ["//:testdata"],
deps = [
":libmulti_pass_tesseract_decoder",
"@gtest",
"@gtest//:gtest_main",
"@stim//:stim_lib",
],
)

cc_library(
name = "liberror_correlations",
srcs = ["multi_pass/error_correlations.cc"],
hdrs = ["multi_pass/error_correlations.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
"@stim//:stim_lib",
],
)

cc_test(
name = "error_correlations_tests",
srcs = ["multi_pass/error_correlations.test.cc"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
":liberror_correlations",
"@gtest",
"@gtest//:gtest_main",
"@stim//:stim_lib",
],
)

cc_library(
name = "libtanner_graph",
srcs = ["multi_pass/tanner_graph.cc"],
hdrs = ["multi_pass/tanner_graph.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
"@stim//:stim_lib",
],
)

cc_test(
name = "tanner_graph_tests",
srcs = ["multi_pass/tanner_graph.test.cc"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
":libtanner_graph",
"@gtest",
"@gtest//:gtest_main",
"@stim//:stim_lib",
],
)

cc_library(
name = "libdem_decomposition",
srcs = ["multi_pass/dem_decomposition.cc"],
hdrs = ["multi_pass/dem_decomposition.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
"@stim//:stim_lib",
],
)

cc_test(
name = "dem_decomposition_tests",
srcs = ["multi_pass/dem_decomposition.test.cc"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
":libdem_decomposition",
"@gtest",
"@gtest//:gtest_main",
"@stim//:stim_lib",
],
)

cc_binary(
name = "tesseract",
srcs = ["tesseract_main.cc"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
":libtesseract",
":libmulti_pass_tesseract_decoder",
"@argparse",
"@nlohmann_json//:json",
"@stim//:stim_lib",
Expand Down
Loading
Loading