Skip to content
Merged
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
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ pybind11_add_module(tesseract_decoder MODULE ${TESSERACT_SRC_DIR}/tesseract.pybi
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)
# Keep statically linked HiGHS symbols private to this extension on every
# supported Unix platform. Mach-O uses an explicit export list because it has
# no ELF-style --exclude-libs option; otherwise highspy can resolve symbols to
# Tesseract's private HiGHS copy when both extensions share a process.
if(APPLE)
target_link_options(tesseract_decoder PRIVATE
"-Wl,-exported_symbols_list,${TESSERACT_SRC_DIR}/tesseract_decoder.exports")
elseif(UNIX)
target_link_options(tesseract_decoder PRIVATE "-Wl,--exclude-libs,ALL")
endif()
set_target_properties(tesseract_decoder PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/src
Expand Down
13 changes: 13 additions & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ pybind_extension(
"tesseract.pybind.cc",
],
copts = OPT_COPTS,
# Keep static-library symbols (notably HiGHS) private to this extension.
# Mach-O has no equivalent to ELF's --exclude-libs, so it needs an explicit
# export list; without it, highspy can see the linked HiGHS symbols.
additional_linker_inputs = ["tesseract_decoder.exports"],
linkopts = select({
"@platforms//os:osx": [
"-Wl,-exported_symbols_list,$(location :tesseract_decoder.exports)",
],
# The ELF equivalent also hides symbols pulled from static archives.
"@platforms//os:linux": ["-Wl,--exclude-libs,ALL"],
# The default also covers Windows and non-ELF toolchains.
"//conditions:default": [],
}),
deps = [
":tesseract_decoder_pybind",
],
Expand Down
8 changes: 8 additions & 0 deletions src/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <string>
#include <vector>

namespace {
Comment thread
supeterposition marked this conversation as resolved.

std::string vector_to_string(const std::vector<int>& vec) {
std::stringstream ss;
ss << "[";
Expand All @@ -34,6 +36,10 @@ std::string vector_to_string(const std::vector<int>& vec) {
return ss.str();
}

} // namespace

namespace tesseract_decoder {

std::string common::Symptom::str() const {
std::string s = "Symptom{detectors=";
s += vector_to_string(detectors);
Expand Down Expand Up @@ -255,3 +261,5 @@ stim::DetectorErrorModel common::dem_from_counts(const stim::DetectorErrorModel&
}
return out_dem;
}

} // namespace tesseract_decoder
2 changes: 2 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "stim.h"

namespace tesseract_decoder {
namespace common {

// Represents the effect of an error
Expand Down Expand Up @@ -113,5 +114,6 @@ stim::DetectorErrorModel dem_from_counts(const stim::DetectorErrorModel& orig_de
double merge_weights(double a, double b);

} // namespace common
} // namespace tesseract_decoder

#endif
4 changes: 4 additions & 0 deletions src/common.pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

namespace py = pybind11;

namespace tesseract_decoder {

void add_common_module(py::module& root) {
auto m = root.def_submodule("common", "classes commonly used by the decoder");

Expand Down Expand Up @@ -217,4 +219,6 @@ void add_common_module(py::module& root) {
)pbdoc");
}

} // namespace tesseract_decoder

#endif
6 changes: 6 additions & 0 deletions src/common.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "gtest/gtest.h"
#include "stim.h"

namespace tesseract_decoder {
namespace {

TEST(common, ErrorsStructFromDemInstruction) {
// Test a pathological DEM error instruction
stim::DetectorErrorModel dem("error(0.1) D0 ^ D0 D1 L0 L1 L1");
Expand Down Expand Up @@ -194,3 +197,6 @@ TEST(CommonTest, merge_indistinguishable_errors_two_errors) {
auto merged_dem4 = common::merge_indistinguishable_errors(dem4, error_index_map);
ASSERT_NEAR(get_merged_probability(merged_dem4), expected_merged_p, 1e-9);
}

} // namespace
} // namespace tesseract_decoder
4 changes: 4 additions & 0 deletions src/simplex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "io/HMPSIO.h"
#include "utils.h"

namespace tesseract_decoder {

constexpr size_t T_COORD = 2;

std::string SimplexConfig::str() {
Expand Down Expand Up @@ -401,3 +403,5 @@ void SimplexDecoder::decode_shots(std::vector<stim::SparseShot>& shots,
}

SimplexDecoder::~SimplexDecoder() {}

} // namespace tesseract_decoder
4 changes: 4 additions & 0 deletions src/simplex.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ struct HighsModel;
struct Highs;
enum class HighsStatus;

namespace tesseract_decoder {

struct SimplexConfig {
stim::DetectorErrorModel dem;
bool parallelize = false;
Expand Down Expand Up @@ -81,4 +83,6 @@ struct SimplexDecoder {
void init_ilp();
};

} // namespace tesseract_decoder

#endif // SIMPLEX_HPP
26 changes: 17 additions & 9 deletions src/simplex.pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

namespace py = pybind11;

namespace tesseract_decoder {
namespace {

// Helper function to compile the decoder.
std::unique_ptr<SimplexDecoder> _compile_simplex_decoder_helper(const SimplexConfig& self) {
return std::make_unique<SimplexDecoder>(self);
Expand All @@ -41,19 +43,27 @@ SimplexConfig simplex_config_maker(py::object dem, bool parallelize = false,
{input_dem, parallelize, window_length, window_slide_length, verbose, merge_errors});
}

}; // namespace
} // namespace

void add_simplex_module(py::module& root) {
auto m =
root.def_submodule("simplex", "Module containing the SimplexDecoder and related methods");

py::class_<SimplexConfig>(m, "SimplexConfig", R"pbdoc(
auto py_simplex_config = py::class_<SimplexConfig>(m, "SimplexConfig", R"pbdoc(
Configuration object for the `SimplexDecoder`.

This class holds all the parameters needed to initialize and configure a
Simplex decoder instance, including the detector error model and
decoding options.
)pbdoc")
)pbdoc");
auto py_simplex_decoder = py::class_<SimplexDecoder>(m, "SimplexDecoder", R"pbdoc(
A class that implements the Simplex decoding algorithm.

It can decode syndromes from a `stim.DetectorErrorModel` to predict
which observables have been flipped.
)pbdoc");

py_simplex_config
.def(py::init(&simplex_config_maker), py::arg("dem"), py::arg("parallelize") = false,
py::arg("window_length") = 0, py::arg("window_slide_length") = 0,
py::arg("verbose") = false, py::arg("merge_errors") = true, R"pbdoc(
Expand Down Expand Up @@ -101,12 +111,7 @@ void add_simplex_module(py::module& root) {
settings.
)pbdoc");

py::class_<SimplexDecoder>(m, "SimplexDecoder", R"pbdoc(
A class that implements the Simplex decoding algorithm.

It can decode syndromes from a `stim.DetectorErrorModel` to predict
which observables have been flipped.
)pbdoc")
py_simplex_decoder
.def(py::init<SimplexConfig>(), py::arg("config"), R"pbdoc(
The constructor for the `SimplexDecoder` class.

Expand Down Expand Up @@ -351,4 +356,7 @@ void add_simplex_module(py::module& root) {
(num_shots, num_observables).
)pbdoc");
}

} // namespace tesseract_decoder

#endif
2 changes: 2 additions & 0 deletions src/simplex_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "stim.h"
#include "utils.h"

using namespace tesseract_decoder;

struct Args {
std::string circuit_path;
std::string dem_path;
Expand Down
4 changes: 4 additions & 0 deletions src/stim_utils.pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "stim.h"

namespace tesseract_decoder {

namespace {
namespace py = pybind11;
}
Expand Down Expand Up @@ -66,4 +68,6 @@ void dem_setter(T& config, py::object dem) {
config.dem = parse_py_object<stim::DetectorErrorModel>(dem);
}

} // namespace tesseract_decoder

#endif
4 changes: 4 additions & 0 deletions src/tesseract.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ struct hash<boost::dynamic_bitset<>> {
};
} // namespace std

namespace tesseract_decoder {

std::string TesseractConfig::str() {
auto& config = *this;
std::stringstream ss;
Expand Down Expand Up @@ -733,3 +735,5 @@ void TesseractDecoder::build_sparse_d2e(const std::vector<uint64_t>& detections)
}
}
}

} // namespace tesseract_decoder
4 changes: 4 additions & 0 deletions src/tesseract.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "utils.h"
#include "visualization.h"

namespace tesseract_decoder {

constexpr size_t INF_DET_BEAM = std::numeric_limits<uint16_t>::max();
constexpr int DEFAULT_DET_BEAM = 5;
constexpr size_t DEFAULT_PQLIMIT = 200000;
Expand Down Expand Up @@ -144,4 +146,6 @@ struct TesseractDecoder {
const std::vector<std::vector<int>>& active_d2e);
};

} // namespace tesseract_decoder

#endif // TESSERACT_DECODER_H
2 changes: 2 additions & 0 deletions src/tesseract.perf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "stim.h"
#include "utils.h"

using namespace tesseract_decoder;

constexpr uint64_t test_data_seed = 752024;

template <typename Decoder>
Expand Down
1 change: 1 addition & 0 deletions src/tesseract.pybind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "visualization.pybind.h"

PYBIND11_MODULE(tesseract_decoder, tesseract) {
using namespace tesseract_decoder;
py::module::import("stim");

add_common_module(tesseract);
Expand Down
23 changes: 15 additions & 8 deletions src/tesseract.pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

namespace py = pybind11;

namespace tesseract_decoder {
namespace {

// Helper function to compile the decoder.
std::unique_ptr<TesseractDecoder> _compile_tesseract_decoder_helper(const TesseractConfig& self) {
return std::make_unique<TesseractDecoder>(self);
Expand Down Expand Up @@ -79,12 +81,20 @@ void add_tesseract_module(py::module& root) {
py::arg("num_detectors"), py::arg("sparsify_base_degree"),
"Returns the suggested number of optional high-degree errors to reactivate per shot.");

py::class_<TesseractConfig>(m, "TesseractConfig", R"pbdoc(
auto py_tesseract_config = py::class_<TesseractConfig>(m, "TesseractConfig", R"pbdoc(
Configuration object for the `TesseractDecoder`.

This class holds all the parameters needed to initialize and configure a
Tesseract decoder instance.
)pbdoc")
)pbdoc");
auto py_tesseract_decoder = py::class_<TesseractDecoder>(m, "TesseractDecoder", R"pbdoc(
A class that implements the Tesseract decoding algorithm.

It can decode syndromes from a `stim.DetectorErrorModel` to predict
which observables have been flipped.
)pbdoc");

py_tesseract_config
.def(py::init<>(), R"pbdoc(
Default constructor for TesseractConfig.
Creates a new instance with default parameter values.
Expand Down Expand Up @@ -239,12 +249,7 @@ void add_tesseract_module(py::module& root) {
`TesseractConfig` object.
)pbdoc");

py::class_<TesseractDecoder>(m, "TesseractDecoder", R"pbdoc(
A class that implements the Tesseract decoding algorithm.

It can decode syndromes from a `stim.DetectorErrorModel` to predict
which observables have been flipped.
)pbdoc")
py_tesseract_decoder
.def(py::init<TesseractConfig>(), py::arg("config"), R"pbdoc(
The constructor for the `TesseractDecoder` class.

Expand Down Expand Up @@ -522,4 +527,6 @@ void add_tesseract_module(py::module& root) {
"visualization of the algorithm");
}

} // namespace tesseract_decoder

#endif
6 changes: 6 additions & 0 deletions src/tesseract.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "stim.h"
#include "utils.h"

namespace tesseract_decoder {
namespace {

constexpr uint64_t test_data_seed = 752024;

bool simplex_test_compare(stim::DetectorErrorModel& dem, std::vector<stim::SparseShot>& shots) {
Expand Down Expand Up @@ -559,3 +562,6 @@ TEST(tesseract, MoreThan64Observables) {
ASSERT_EQ(flipped[i], i);
}
}

} // namespace
} // namespace tesseract_decoder
1 change: 1 addition & 0 deletions src/tesseract_decoder.exports
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_PyInit_tesseract_decoder
2 changes: 2 additions & 0 deletions src/tesseract_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "tesseract.h"
#include "utils.h"

using namespace tesseract_decoder;

struct Args {
std::string circuit_path;
std::string dem_path;
Expand Down
4 changes: 4 additions & 0 deletions src/tesseract_sinter_compat.pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

namespace py = pybind11;

namespace tesseract_decoder {

// These are the classes that will be exposed to Python.
struct TesseractSinterCompiledDecoder;
struct TesseractSinterDecoder;
Expand Down Expand Up @@ -495,3 +497,5 @@ void pybind_sinter_compat(py::module& root) {
root.attr("TesseractSinterDecoder") = m.attr("TesseractSinterDecoder");
root.attr("make_tesseract_sinter_decoders_dict") = m.attr("make_tesseract_sinter_decoders_dict");
}

} // namespace tesseract_decoder
4 changes: 4 additions & 0 deletions src/tesseract_trellis.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include "utils.h"

namespace tesseract_decoder {

struct TesseractTrellisWideKernelBase {
virtual ~TesseractTrellisWideKernelBase() = default;
virtual void decode_shot(TesseractTrellisDecoder* decoder,
Expand Down Expand Up @@ -1288,3 +1290,5 @@ void TesseractTrellisDecoder::decode_shots(std::vector<stim::SparseShot>& shots,
obs_predicted[i] = decode(shots[i].hits);
}
}

} // namespace tesseract_decoder
Loading
Loading