Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ user.bazelrc
src/tesseract_decoder*.so

MODULE.bazel.lock
build/
_core.so
*.egg-info/
5 changes: 5 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ config_setting(
"@platforms//cpu:x86_64",
],
)
filegroup(
name = "testdata",
srcs = glob(["testdata/**/*"]),
visibility = ["//visibility:public"],
)
63 changes: 52 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ project(tesseract_decoder LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include cstdint")

include(FetchContent)
find_package(Threads REQUIRED)
Expand Down Expand Up @@ -73,7 +74,7 @@ FetchContent_Declare(
FetchContent_MakeAvailable(googletest)


set(OPT_COPTS -Ofast -fno-fast-math -march=native)
set(OPT_COPTS -Ofast -fno-fast-math -march=native -include cstdint)

set(TESSERACT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)

Expand All @@ -93,6 +94,30 @@ 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(bern_utils ${TESSERACT_SRC_DIR}/bern_utils.cc ${TESSERACT_SRC_DIR}/bern_utils.h)
target_include_directories(bern_utils PUBLIC ${TESSERACT_SRC_DIR})
target_compile_options(bern_utils PRIVATE ${OPT_COPTS})

add_library(error_correlations ${TESSERACT_SRC_DIR}/error_correlations.cc ${TESSERACT_SRC_DIR}/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}/tanner_graph.cc ${TESSERACT_SRC_DIR}/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}/dem_decomposition.cc ${TESSERACT_SRC_DIR}/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 bern_utils libstim)

add_library(multi_pass_tesseract_decoder ${TESSERACT_SRC_DIR}/multi_pass_tesseract_decoder.cc ${TESSERACT_SRC_DIR}/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 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,16 +139,16 @@ target_compile_options(simplex_bin PRIVATE ${OPT_COPTS})
target_link_libraries(simplex_bin PRIVATE common simplex argparse::argparse nlohmann_json::nlohmann_json)

# === Python module ===
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)
set_target_properties(tesseract_decoder PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${PROJECT_SOURCE_DIR}/src
pybind11_add_module(_core MODULE ${TESSERACT_SRC_DIR}/tesseract.pybind.cc)
target_compile_options(_core PRIVATE ${OPT_COPTS})
target_include_directories(_core PRIVATE ${TESSERACT_SRC_DIR})
target_link_libraries(_core PRIVATE common utils simplex tesseract_lib multi_pass_tesseract_decoder)
set_target_properties(_core PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/tesseract_decoder
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/tesseract_decoder
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/tesseract_decoder
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${PROJECT_SOURCE_DIR}/tesseract_decoder
LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${PROJECT_SOURCE_DIR}/tesseract_decoder
)

# === Tests ===
Expand All @@ -137,3 +162,19 @@ add_executable(tesseract_test ${TESSERACT_SRC_DIR}/tesseract.test.cc)
target_link_libraries(tesseract_test PRIVATE tesseract_lib simplex GTest::gtest_main)
add_test(NAME tesseract_test COMMAND tesseract_test)

add_executable(dem_decomposition_test ${TESSERACT_SRC_DIR}/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}/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}/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_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)

39 changes: 39 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from setuptools import setup, find_packages
import subprocess
import os
import sys

def build_with_bazel():
print("Building C++ extension with Bazel...")
try:
subprocess.check_call(["bazel", "build", "//src/py:tesseract_decoder"])
# Copy the output .so file to the package directory
src = "bazel-bin/src/py/tesseract_decoder/_core.so"
dst = "src/py/tesseract_decoder/_core.so"
print(f"Copying {src} to {dst}...")
os.makedirs(os.path.dirname(dst), exist_ok=True)
subprocess.check_call(["cp", src, dst])
except Exception as e:
print(f"Warning: Failed to build C++ extension with Bazel: {e}")
print("You may need to build it manually using 'bazel build //src/py:tesseract_decoder'")

# Always attempt to build with bazel.
# Bazel's own incremental build logic will ensure this is fast if no changes occurred.
build_with_bazel()

setup(
name="tesseract_decoder",
version="0.1.1",
package_dir={"": "src/py"},
packages=find_packages(where="src/py"),
install_requires=[
"stim",
"sinter",
"numpy",
],
package_data={
"tesseract_decoder": ["_core.so"],
},
include_package_data=True,
zip_safe=False,
)
122 changes: 113 additions & 9 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,20 @@ pybind_library(
"visualization.pybind.h",
"tesseract.pybind.h",
"tesseract_sinter_compat.pybind.h",
"multi_pass_sinter_compat.pybind.h",
],
copts = OPT_COPTS,
deps = [
":libcommon",
":libutils",
":libsimplex",
":libtesseract",
":libmulti_pass_tesseract_decoder",
],
)

pybind_extension(
name = "tesseract_decoder",
name = "_core",
srcs = [
"tesseract.pybind.cc",
],
Expand All @@ -92,14 +94,6 @@ pybind_extension(
],
)

py_library(
name="lib_tesseract_decoder",
deps=[
":tesseract_decoder",
"//src/py/_tesseract_py_util:_tesseract_py_util",
],
)


cc_library(
name = "libutils",
Expand Down Expand Up @@ -140,6 +134,116 @@ cc_library(
],
)

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

cc_test(
name = "multi_pass_tesseract_decoder_tests",
srcs = ["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 = ["error_correlations.cc"],
hdrs = ["error_correlations.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
"@stim//:stim_lib",
],
)

cc_test(
name = "error_correlations_tests",
srcs = ["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 = ["tanner_graph.cc"],
hdrs = ["tanner_graph.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
deps = [
"@stim//:stim_lib",
],
)

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

cc_library(
name = "libbern_utils",
srcs = ["bern_utils.cc"],
hdrs = ["bern_utils.h"],
copts = OPT_COPTS,
linkopts = OPT_LINKOPTS,
)

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

cc_test(
name = "dem_decomposition_tests",
srcs = ["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"],
Expand Down
21 changes: 21 additions & 0 deletions src/bern_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "bern_utils.h"
#include <cmath>
#include <limits>

namespace tesseract {

double bernoulli_xor(double p1, double p2) {
return p1 * (1 - p2) + p2 * (1 - p1);
}

double to_weight(double probability) {
if (probability >= 1.0) {
return -std::numeric_limits<double>::infinity();
}
if (probability <= 0) {
return std::numeric_limits<double>::infinity();
}
return std::log((1 - probability) / probability);
}

} // namespace two_pass_decoding
17 changes: 17 additions & 0 deletions src/bern_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef BERN_UTILS_H
#define BERN_UTILS_H

namespace tesseract {

// Calculates the probability of an odd number of independent events with
// probabilities p1 and p2 occurring: p1*(1-p2) + p2*(1-p1).
double bernoulli_xor(double p1, double p2);

// Converts a probability to a log-likelihood ratio weight.
// The weight is calculated as w = ln((1-p)/p).
double to_weight(double probability);

} // namespace two_pass_decoding

#endif // BERN_UTILS_H

Loading
Loading