From 6379a823e76e342f9bc0ff5db3c7af4d603ec3f9 Mon Sep 17 00:00:00 2001 From: Dragana Grbic Date: Thu, 14 Aug 2025 17:05:52 -0700 Subject: [PATCH 1/4] Better default arguments for Tesseract config --- src/py/tesseract_test.py | 10 ++++----- src/tesseract.h | 8 ++++--- src/tesseract.pybind.h | 46 +++++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/py/tesseract_test.py b/src/py/tesseract_test.py index ac40f11a..eefaa0d1 100644 --- a/src/py/tesseract_test.py +++ b/src/py/tesseract_test.py @@ -49,7 +49,7 @@ def test_create_node(): def test_create_tesseract_config(): assert ( str(tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL)) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=65535, no_revisit_dets=0, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=18446744073709551615, det_orders=[], det_penalty=0, create_visualization=0)" + == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0, create_visualization=0)" ) assert ( tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL).dem @@ -66,7 +66,7 @@ def test_create_tesseract_config_with_dem(): # Assert the string representation matches the expected format. assert ( str(config) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=65535, no_revisit_dets=0, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=18446744073709551615, det_orders=[], det_penalty=0, create_visualization=0)" + == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0, create_visualization=0)" ) # Assert that the `dem` attribute is correctly set. @@ -93,7 +93,7 @@ def test_create_tesseract_config_with_dem_and_custom_args(): # Assert the string representation is as expected. assert ( str(config) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=100, no_revisit_dets=0, at_most_two_errors_per_detector=0, verbose=0, merge_errors=0, pqlimit=18446744073709551615, det_orders=[], det_penalty=0.5, create_visualization=0)" + == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=100, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=0, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0.5, create_visualization=0)" ) def test_compile_decoder_for_dem_basic_functionality(): @@ -164,7 +164,7 @@ def test_create_tesseract_config_no_dem(): # Assert that the string representation shows the default values. assert ( str(config_default) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=65535, no_revisit_dets=0, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=18446744073709551615, det_orders=[], det_penalty=0, create_visualization=0)" + == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[], det_penalty=0, create_visualization=0)" ) def test_create_tesseract_config_no_dem_with_custom_args(): @@ -184,7 +184,7 @@ def test_create_tesseract_config_no_dem_with_custom_args(): # Assert that the string representation reflects the custom values. assert ( str(config_custom) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=15, no_revisit_dets=0, at_most_two_errors_per_detector=0, verbose=1, merge_errors=1, pqlimit=18446744073709551615, det_orders=[], det_penalty=0, create_visualization=0)" + == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=15, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=1, merge_errors=1, pqlimit=200000, det_orders=[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []], det_penalty=0, create_visualization=0)" ) diff --git a/src/tesseract.h b/src/tesseract.h index 9a3806e9..ead2b2ac 100644 --- a/src/tesseract.h +++ b/src/tesseract.h @@ -28,16 +28,18 @@ #include "visualization.h" constexpr size_t INF_DET_BEAM = std::numeric_limits::max(); +constexpr int DEFAULT_DET_BEAM = 5; +constexpr size_t DEFAULT_PQLIMIT = 200000; struct TesseractConfig { stim::DetectorErrorModel dem; - int det_beam = INF_DET_BEAM; + int det_beam = DEFAULT_DET_BEAM; bool beam_climbing = false; - bool no_revisit_dets = false; + bool no_revisit_dets = true; bool at_most_two_errors_per_detector = false; bool verbose = false; bool merge_errors = true; - size_t pqlimit = std::numeric_limits::max(); + size_t pqlimit = DEFAULT_PQLIMIT; std::vector> det_orders; double det_penalty = 0; bool create_visualization = false; diff --git a/src/tesseract.pybind.h b/src/tesseract.pybind.h index 0724b605..5ee2124d 100644 --- a/src/tesseract.pybind.h +++ b/src/tesseract.pybind.h @@ -23,6 +23,7 @@ #include "stim_utils.pybind.h" #include "tesseract.h" +#include "utils.h" namespace py = pybind11; @@ -32,30 +33,35 @@ std::unique_ptr _compile_tesseract_decoder_helper(const Tesser return std::make_unique(self); } -TesseractConfig tesseract_config_maker_no_dem( - int det_beam = INF_DET_BEAM, bool beam_climbing = false, bool no_revisit_dets = false, - bool at_most_two_errors_per_detector = false, bool verbose = false, bool merge_errors = true, - size_t pqlimit = std::numeric_limits::max(), - std::vector> det_orders = std::vector>(), - double det_penalty = 0.0, bool create_visualization = false) { +TesseractConfig tesseract_config_maker_no_dem(int det_beam, bool beam_climbing, + bool no_revisit_dets, + bool at_most_two_errors_per_detector, bool verbose, + bool merge_errors, size_t pqlimit, + std::vector> det_orders, + double det_penalty, bool create_visualization) { stim::DetectorErrorModel empty_dem; + if (det_orders.empty()) { + det_orders = build_det_orders(empty_dem, 20, true, 2384753); + } return TesseractConfig({empty_dem, det_beam, beam_climbing, no_revisit_dets, at_most_two_errors_per_detector, verbose, merge_errors, pqlimit, det_orders, det_penalty, create_visualization}); } -TesseractConfig tesseract_config_maker( - py::object dem, int det_beam = INF_DET_BEAM, bool beam_climbing = false, - bool no_revisit_dets = false, bool at_most_two_errors_per_detector = false, - bool verbose = false, bool merge_errors = true, - size_t pqlimit = std::numeric_limits::max(), - std::vector> det_orders = std::vector>(), - double det_penalty = 0.0, bool create_visualization = false) { - stim::DetectorErrorModel input_dem = parse_py_object(dem); +TesseractConfig tesseract_config_maker(py::object dem_obj, int det_beam, bool beam_climbing, + bool no_revisit_dets, bool at_most_two_errors_per_detector, + bool verbose, bool merge_errors, size_t pqlimit, + std::vector> det_orders, + double det_penalty, bool create_visualization) { + stim::DetectorErrorModel input_dem = parse_py_object(dem_obj); + if (det_orders.empty()) { + det_orders = build_det_orders(input_dem, 20, true, 2384753); + } return TesseractConfig({input_dem, det_beam, beam_climbing, no_revisit_dets, at_most_two_errors_per_detector, verbose, merge_errors, pqlimit, det_orders, det_penalty, create_visualization}); } + }; // namespace void add_tesseract_module(py::module& root) { auto m = root.def_submodule("tesseract", "Module containing the tesseract algorithm"); @@ -73,10 +79,10 @@ void add_tesseract_module(py::module& root) { Default constructor for TesseractConfig. Creates a new instance with default parameter values. )pbdoc") - .def(py::init(&tesseract_config_maker_no_dem), py::arg("det_beam") = INF_DET_BEAM, - py::arg("beam_climbing") = false, py::arg("no_revisit_dets") = false, + .def(py::init(&tesseract_config_maker_no_dem), py::arg("det_beam") = 5, + py::arg("beam_climbing") = false, py::arg("no_revisit_dets") = true, py::arg("at_most_two_errors_per_detector") = false, py::arg("verbose") = false, - py::arg("merge_errors") = true, py::arg("pqlimit") = std::numeric_limits::max(), + py::arg("merge_errors") = true, py::arg("pqlimit") = 200000, py::arg("det_orders") = std::vector>(), py::arg("det_penalty") = 0.0, py::arg("create_visualization") = false, R"pbdoc( @@ -108,10 +114,10 @@ void add_tesseract_module(py::module& root) { create_visualization: bool, defualt=False Whether to record the information needed to create a visualization or not. )pbdoc") - .def(py::init(&tesseract_config_maker), py::arg("dem"), py::arg("det_beam") = INF_DET_BEAM, - py::arg("beam_climbing") = false, py::arg("no_revisit_dets") = false, + .def(py::init(&tesseract_config_maker), py::arg("dem"), py::arg("det_beam") = 5, + py::arg("beam_climbing") = false, py::arg("no_revisit_dets") = true, py::arg("at_most_two_errors_per_detector") = false, py::arg("verbose") = false, - py::arg("merge_errors") = true, py::arg("pqlimit") = std::numeric_limits::max(), + py::arg("merge_errors") = true, py::arg("pqlimit") = 200000, py::arg("det_orders") = std::vector>(), py::arg("det_penalty") = 0.0, py::arg("create_visualization") = false, R"pbdoc( From 42c019d4054c1280f1fd7fd31d9325272d548135 Mon Sep 17 00:00:00 2001 From: Dragana Grbic Date: Thu, 14 Aug 2025 17:35:31 -0700 Subject: [PATCH 2/4] Minor change --- src/tesseract.pybind.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/tesseract.pybind.h b/src/tesseract.pybind.h index 5ee2124d..851df33b 100644 --- a/src/tesseract.pybind.h +++ b/src/tesseract.pybind.h @@ -33,12 +33,12 @@ std::unique_ptr _compile_tesseract_decoder_helper(const Tesser return std::make_unique(self); } -TesseractConfig tesseract_config_maker_no_dem(int det_beam, bool beam_climbing, - bool no_revisit_dets, - bool at_most_two_errors_per_detector, bool verbose, - bool merge_errors, size_t pqlimit, - std::vector> det_orders, - double det_penalty, bool create_visualization) { +TesseractConfig tesseract_config_maker_no_dem( + int det_beam = INF_DET_BEAM, bool beam_climbing = false, bool no_revisit_dets = false, + bool at_most_two_errors_per_detector = false, bool verbose = false, bool merge_errors = true, + size_t pqlimit = std::numeric_limits::max(), + std::vector> det_orders = std::vector>(), + double det_penalty = 0.0, bool create_visualization = false) { stim::DetectorErrorModel empty_dem; if (det_orders.empty()) { det_orders = build_det_orders(empty_dem, 20, true, 2384753); @@ -48,12 +48,14 @@ TesseractConfig tesseract_config_maker_no_dem(int det_beam, bool beam_climbing, det_orders, det_penalty, create_visualization}); } -TesseractConfig tesseract_config_maker(py::object dem_obj, int det_beam, bool beam_climbing, - bool no_revisit_dets, bool at_most_two_errors_per_detector, - bool verbose, bool merge_errors, size_t pqlimit, - std::vector> det_orders, - double det_penalty, bool create_visualization) { - stim::DetectorErrorModel input_dem = parse_py_object(dem_obj); +TesseractConfig tesseract_config_maker( + py::object dem, int det_beam = INF_DET_BEAM, bool beam_climbing = false, + bool no_revisit_dets = false, bool at_most_two_errors_per_detector = false, + bool verbose = false, bool merge_errors = true, + size_t pqlimit = std::numeric_limits::max(), + std::vector> det_orders = std::vector>(), + double det_penalty = 0.0, bool create_visualization = false) { + stim::DetectorErrorModel input_dem = parse_py_object(dem); if (det_orders.empty()) { det_orders = build_det_orders(input_dem, 20, true, 2384753); } From a42cbaacd0dc0ea684a523feb9e96044b4dd40ce Mon Sep 17 00:00:00 2001 From: Dragana Grbic Date: Thu, 14 Aug 2025 17:47:31 -0700 Subject: [PATCH 3/4] Replace string representation comparison with fields comparison --- src/py/tesseract_test.py | 95 +++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/src/py/tesseract_test.py b/src/py/tesseract_test.py index eefaa0d1..0129105e 100644 --- a/src/py/tesseract_test.py +++ b/src/py/tesseract_test.py @@ -47,14 +47,18 @@ def test_create_node(): def test_create_tesseract_config(): - assert ( - str(tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL)) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0, create_visualization=0)" - ) - assert ( - tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL).dem - == _DETECTOR_ERROR_MODEL - ) + config = tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL) + assert config.dem == _DETECTOR_ERROR_MODEL + assert config.det_beam == 5 + assert config.no_revisit_dets is True + assert config.at_most_two_errors_per_detector is False + assert config.verbose is False + assert config.merge_errors is True + assert config.pqlimit == 200000 + assert config.det_penalty == 0 + assert config.create_visualization is False + assert len(config.det_orders) == 20 + def test_create_tesseract_config_with_dem(): """ @@ -63,14 +67,16 @@ def test_create_tesseract_config_with_dem(): config = tesseract_decoder.tesseract.TesseractConfig(_DETECTOR_ERROR_MODEL) - # Assert the string representation matches the expected format. - assert ( - str(config) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0, create_visualization=0)" - ) - - # Assert that the `dem` attribute is correctly set. assert config.dem == _DETECTOR_ERROR_MODEL + assert config.det_beam == 5 + assert config.no_revisit_dets is True + assert config.at_most_two_errors_per_detector is False + assert config.verbose is False + assert config.merge_errors is True + assert config.pqlimit == 200000 + assert config.det_penalty == 0 + assert config.create_visualization is False + assert len(config.det_orders) == 20 def test_create_tesseract_config_with_dem_and_custom_args(): """ @@ -84,17 +90,17 @@ def test_create_tesseract_config_with_dem_and_custom_args(): det_penalty=0.5 ) - # Assert that the `dem` and custom arguments are correctly set. assert config.dem == _DETECTOR_ERROR_MODEL assert config.det_beam == 100 + assert config.no_revisit_dets is True + assert config.at_most_two_errors_per_detector is False + assert config.verbose is False assert config.merge_errors is False + assert config.pqlimit == 200000 assert config.det_penalty == 0.5 + assert config.create_visualization is False + assert len(config.det_orders) == 20 - # Assert the string representation is as expected. - assert ( - str(config) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=100, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=0, pqlimit=200000, det_orders=[[1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0], [1, 0], [0, 1], [1, 0], [1, 0], [1, 0], [0, 1], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1], [1, 0], [1, 0]], det_penalty=0.5, create_visualization=0)" - ) def test_compile_decoder_for_dem_basic_functionality(): """ @@ -155,37 +161,34 @@ def test_create_tesseract_config_no_dem(): Tests the new constructor that does not require a `dem` argument. """ # Create an instance with no arguments. - config_default = tesseract_decoder.tesseract.TesseractConfig() - - # Assert that the `dem` attribute defaults to an empty DetectorErrorModel. - empty_dem = stim.DetectorErrorModel() - assert config_default.dem == empty_dem - - # Assert that the string representation shows the default values. - assert ( - str(config_default) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=5, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=0, merge_errors=1, pqlimit=200000, det_orders=[], det_penalty=0, create_visualization=0)" - ) + config = tesseract_decoder.tesseract.TesseractConfig() + + assert config.dem == stim.DetectorErrorModel() + assert config.det_beam == 5 + assert config.no_revisit_dets is True + assert config.at_most_two_errors_per_detector is False + assert config.verbose is False + assert config.merge_errors is True + assert config.pqlimit == 200000 + assert config.det_penalty == 0.0 + assert config.create_visualization is False def test_create_tesseract_config_no_dem_with_custom_args(): """ Tests the new constructor with custom arguments to ensure they are passed correctly. """ # Create an instance with no dem but a custom det_beam. - config_custom = tesseract_decoder.tesseract.TesseractConfig(det_beam=15, verbose=True) - - # Assert that the `det_beam` and `verbose` attributes are correctly set. - assert config_custom.det_beam == 15 - assert config_custom.verbose is True - - # Assert that the `dem` attribute still defaults to an empty DetectorErrorModel. - assert config_custom.dem == stim.DetectorErrorModel() - - # Assert that the string representation reflects the custom values. - assert ( - str(config_custom) - == "TesseractConfig(dem=DetectorErrorModel_Object, det_beam=15, no_revisit_dets=1, at_most_two_errors_per_detector=0, verbose=1, merge_errors=1, pqlimit=200000, det_orders=[[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []], det_penalty=0, create_visualization=0)" - ) + config = tesseract_decoder.tesseract.TesseractConfig(det_beam=15, verbose=True) + + assert config.dem == stim.DetectorErrorModel() + assert config.det_beam == 15 + assert config.no_revisit_dets is True + assert config.at_most_two_errors_per_detector is False + assert config.verbose is True + assert config.merge_errors is True + assert config.pqlimit == 200000 + assert config.det_penalty == 0.0 + assert config.create_visualization is False def test_create_tesseract_decoder(): From 7cb713695b2a4212fa036915e4ea932b2be6c5aa Mon Sep 17 00:00:00 2001 From: Noah Shutty Date: Thu, 21 Aug 2025 14:16:10 -0700 Subject: [PATCH 4/4] Update src/tesseract.pybind.h --- src/tesseract.pybind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tesseract.pybind.h b/src/tesseract.pybind.h index 851df33b..ec9c883e 100644 --- a/src/tesseract.pybind.h +++ b/src/tesseract.pybind.h @@ -41,7 +41,7 @@ TesseractConfig tesseract_config_maker_no_dem( double det_penalty = 0.0, bool create_visualization = false) { stim::DetectorErrorModel empty_dem; if (det_orders.empty()) { - det_orders = build_det_orders(empty_dem, 20, true, 2384753); + det_orders = build_det_orders(empty_dem, 20, /*det_order_bfs=*/true, 2384753); } return TesseractConfig({empty_dem, det_beam, beam_climbing, no_revisit_dets, at_most_two_errors_per_detector, verbose, merge_errors, pqlimit,