Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0a24685
Packing blocked errors and detection counts into a single array/struct
draganaurosgrbic Jun 14, 2025
779e7ac
Remove/refactor redundant code
draganaurosgrbic Jun 15, 2025
eff2a15
Minor changes
draganaurosgrbic Jun 16, 2025
4003520
Merge remote-tracking branch 'origin/main' into optimization-cpu
draganaurosgrbic Jun 25, 2025
144affe
Control the number of nodes inserted into priority queue
draganaurosgrbic Jul 1, 2025
02c1066
fix detector beam node skipping implementation
noajshu Jul 1, 2025
6f4b5dd
beam search pruning based on min cost per detector count
draganaurosgrbic Jul 1, 2025
e0d6f2f
Merge branch 'optimization-cpu' of https://github.com/quantumlib/tess…
draganaurosgrbic Jul 7, 2025
b16bc51
Merge remote-tracking branch 'origin/main' into optimization-cpu
draganaurosgrbic Jul 7, 2025
cfd157a
Format src/tesseract.cc file
draganaurosgrbic Jul 7, 2025
97b78eb
Merge branch 'main' into optimization-cpu
draganaurosgrbic Jul 7, 2025
59b73f1
Remove unnecessary code
draganaurosgrbic Jul 8, 2025
bb2ac2b
Merge remote-tracking branch 'origin/main' into optimization-cpu
draganaurosgrbic Jul 8, 2025
d6a5659
Merge branch 'optimization-cpu' of https://github.com/quantumlib/tess…
draganaurosgrbic Jul 8, 2025
29aa98a
Scripts for executing and plotting benchmarks
draganaurosgrbic Jul 10, 2025
d97840d
Remove scripts for benchmarking and plotting
draganaurosgrbic Jul 10, 2025
b1e9fef
Merge branch 'main' into optimization-cpu
LalehB Jul 16, 2025
1cb96cb
Merge branch 'main' into optimization-cpu
draganaurosgrbic Jul 21, 2025
053d286
remove d2e_detcost
draganaurosgrbic Jul 24, 2025
7147df5
Use boost::dynamic_bitset for hashing fired detectors
draganaurosgrbic Jul 25, 2025
55bc51c
Merge branch 'main' into optimization-cpu
draganaurosgrbic Jul 25, 2025
1446245
add boost dependency
draganaurosgrbic Jul 25, 2025
21dc212
fix boost dependency
draganaurosgrbic Jul 25, 2025
e513348
minor change
draganaurosgrbic Jul 25, 2025
1ddef02
minor change
draganaurosgrbic Jul 25, 2025
fa10be2
minor change
draganaurosgrbic Jul 26, 2025
3d72df4
consistent usage of variable types inside for loops
draganaurosgrbic Jul 29, 2025
20a29bb
Merge branch 'main' into optimization-cpu
draganaurosgrbic Jul 30, 2025
f2830a9
replace size_t with int in appropriate loops
draganaurosgrbic Jul 30, 2025
5b9cc83
Merge branch 'optimization-cpu' of https://github.com/quantumlib/tess…
draganaurosgrbic Jul 30, 2025
37b6391
rename Boost headers directory
draganaurosgrbic Jul 30, 2025
813cc42
minnor change
draganaurosgrbic Jul 30, 2025
49919a3
update boost.BUILD
draganaurosgrbic Jul 30, 2025
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
19 changes: 19 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,22 @@ http_archive(
urls = ["https://github.com/bazelbuild/platforms/archive/refs/tags/0.0.6.zip"],
strip_prefix = "platforms-0.0.6",
)




BOOST_VERSION = "1.83.0"
BOOST_ARCHIVE_NAME = "boost_{}".format(BOOST_VERSION.replace(".", "_"))

http_archive(
name = "boost",
urls = [
"https://archives.boost.io/release/{}/source/{}.tar.gz".format(
BOOST_VERSION,
BOOST_ARCHIVE_NAME,
)
],
strip_prefix = BOOST_ARCHIVE_NAME,
sha256 = "c0685b68dd44cc46574cce86c4e17c0f611b15e195be9848dfd0769a0a207628",
build_file = "//external:boost.BUILD",
)
16 changes: 16 additions & 0 deletions external/boost.BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# external/boost.BUILD
package(default_visibility = ["//visibility:public"])

# A cc_library for the Boost headers themselves.
cc_library(
name = "boost_headers",
hdrs = glob(["boost/**/*.hpp"]),
includes = ["."],
)

# A specific target for dynamic_bitset, which is header-only
# and depends on the main headers.
cc_library(
name = "dynamic_bitset",
deps = [":boost_headers"],
)
1 change: 1 addition & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ cc_library(
linkopts = OPT_LINKOPTS,
deps = [
":libutils",
"@boost//:dynamic_bitset",
],
)

Expand Down
49 changes: 25 additions & 24 deletions src/tesseract.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include "tesseract.h"

#include <algorithm>
#include <boost/functional/hash.hpp> // For boost::hash_range
#include <cassert>
#include <functional> // For std::hash (though not strictly necessary here, but good practice)
#include <iostream>

namespace {
Expand All @@ -37,6 +39,17 @@ std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {

}; // namespace

namespace std {
template <>
struct hash<boost::dynamic_bitset<>> {
size_t operator()(const boost::dynamic_bitset<>& bs) const {
// Delegate to Boost's internal hash_value for dynamic_bitset
// This is the correct and most efficient way.
return boost::hash_value(bs);
}
};
} // namespace std

std::string TesseractConfig::str() {
auto& config = *this;
std::stringstream ss;
Expand Down Expand Up @@ -73,7 +86,7 @@ double TesseractDecoder::get_detcost(
ErrorCost ec;
DetectorCostTuple dct;

for (size_t ei : d2e[d]) {
for (int ei : d2e[d]) {
ec = error_costs[ei];
if (ec.min_cost >= min_cost) break;

Expand All @@ -89,17 +102,6 @@ double TesseractDecoder::get_detcost(
return min_cost + config.det_penalty;
}

struct VectorCharHash {
size_t operator()(const std::vector<char>& v) const {
size_t seed = v.size();

for (char el : v) {
seed = seed * 31 + static_cast<size_t>(el);
}
return seed;
}
};

TesseractDecoder::TesseractDecoder(TesseractConfig config_) : config(config_) {
config.dem = common::remove_zero_probability_errors(config.dem);
if (config.det_orders.empty()) {
Expand Down Expand Up @@ -206,7 +208,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections)
}

void TesseractDecoder::flip_detectors_and_block_errors(
size_t detector_order, const std::vector<size_t>& errors, std::vector<char>& detectors,
size_t detector_order, const std::vector<size_t>& errors, boost::dynamic_bitset<>& detectors,
std::vector<DetectorCostTuple>& detector_cost_tuples) const {
for (size_t ei : errors) {
size_t min_detector = std::numeric_limits<size_t>::max();
Expand All @@ -217,15 +219,15 @@ void TesseractDecoder::flip_detectors_and_block_errors(
}
}

for (size_t oei : d2e[min_detector]) {
for (int oei : d2e[min_detector]) {
detector_cost_tuples[oei].error_blocked = 1;
if (!config.at_most_two_errors_per_detector && oei == ei) break;
}

for (size_t d : edets[ei]) {
for (int d : edets[ei]) {
detectors[d] = !detectors[d];
if (!detectors[d] && config.at_most_two_errors_per_detector) {
for (size_t oei : d2e[d]) {
for (int oei : d2e[d]) {
detector_cost_tuples[oei].error_blocked = 1;
}
}
Expand All @@ -239,10 +241,9 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
low_confidence_flag = false;

std::priority_queue<Node, std::vector<Node>, std::greater<Node>> pq;
std::unordered_map<size_t, std::unordered_set<std::vector<char>, VectorCharHash>>
visited_detectors;
std::unordered_map<size_t, std::unordered_set<boost::dynamic_bitset<>>> visited_detectors;

std::vector<char> initial_detectors(num_detectors, false);
boost::dynamic_bitset<> initial_detectors(num_detectors, false);
std::vector<DetectorCostTuple> initial_detector_cost_tuples(num_errors);

for (size_t d : detections) {
Expand All @@ -266,7 +267,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
size_t max_num_detectors = min_num_detectors + detector_beam;

std::vector<size_t> next_errors;
std::vector<char> next_detectors;
boost::dynamic_bitset<> next_detectors;
std::vector<DetectorCostTuple> next_detector_cost_tuples;

pq.push({initial_cost, min_num_detectors, std::vector<size_t>()});
Expand All @@ -278,7 +279,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,

if (node.num_detectors > max_num_detectors) continue;

std::vector<char> detectors = initial_detectors;
boost::dynamic_bitset<> detectors = initial_detectors;
std::vector<DetectorCostTuple> detector_cost_tuples(num_errors);
flip_detectors_and_block_errors(detector_order, node.errors, detectors, detector_cost_tuples);

Expand Down Expand Up @@ -363,7 +364,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
size_t prev_ei = std::numeric_limits<size_t>::max();
std::vector<double> detector_cost_cache(num_detectors, -1);

for (size_t ei : d2e[min_detector]) {
for (int ei : d2e[min_detector]) {
if (detector_cost_tuples[ei].error_blocked) continue;

if (prev_ei != std::numeric_limits<size_t>::max()) {
Expand Down Expand Up @@ -398,7 +399,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
}

if (!next_detectors[d] && config.at_most_two_errors_per_detector) {
for (size_t oei : d2e[d]) {
for (int oei : d2e[d]) {
next_detector_cost_tuples[oei].error_blocked =
next_detector_cost_tuples[oei].error_blocked == 1
? 1
Expand Down Expand Up @@ -426,7 +427,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
}
}

for (size_t od : eneighbors[ei]) {
for (int od : eneighbors[ei]) {
if (!detectors[od] || !next_detectors[od]) continue;
if (detector_cost_cache[od] == -1) {
detector_cost_cache[od] = get_detcost(od, detector_cost_tuples);
Expand Down
3 changes: 2 additions & 1 deletion src/tesseract.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef TESSERACT_DECODER_H
#define TESSERACT_DECODER_H

#include <boost/dynamic_bitset.hpp>
#include <queue>
#include <string>
#include <unordered_map>
Expand Down Expand Up @@ -101,7 +102,7 @@ struct TesseractDecoder {
void initialize_structures(size_t num_detectors);
double get_detcost(size_t d, const std::vector<DetectorCostTuple>& detector_cost_tuples) const;
void flip_detectors_and_block_errors(size_t detector_order, const std::vector<size_t>& errors,
std::vector<char>& detectors,
boost::dynamic_bitset<>& detectors,
std::vector<DetectorCostTuple>& detector_cost_tuples) const;
};

Expand Down
Loading