Skip to content

Commit a686e65

Browse files
noajshudandragona-dev
authored andcommitted
Update BUILD to remove "-march=native", for macOS builds
1 parent da5cc0f commit a686e65

File tree

2 files changed

+159
-53
lines changed

2 files changed

+159
-53
lines changed

src/py/tesseract_sinter_compat_test.py

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ def test_compile_decoder_for_dem(use_custom_config):
5151
""")
5252

5353
if use_custom_config:
54-
config = tesseract_decoder.tesseract.TesseractConfig()
55-
config.verbose = True
56-
decoder = tesseract_module.TesseractSinterDecoder(config=config)
54+
decoder = tesseract_module.TesseractSinterDecoder(
55+
verbose=True,
56+
)
5757
else:
5858
decoder = tesseract_module.TesseractSinterDecoder()
5959

@@ -247,9 +247,9 @@ def test_decode_via_files(use_custom_config):
247247
f.write(detection_events_np.tobytes())
248248

249249
if use_custom_config:
250-
config = tesseract_decoder.tesseract.TesseractConfig()
251-
config.verbose = True
252-
decoder = tesseract_module.TesseractSinterDecoder(config=config)
250+
decoder = tesseract_module.TesseractSinterDecoder(
251+
verbose=True,
252+
)
253253
else:
254254
decoder = tesseract_module.TesseractSinterDecoder()
255255

@@ -280,7 +280,7 @@ def test_decode_via_files(use_custom_config):
280280
if temp_dir.exists():
281281
shutil.rmtree(temp_dir)
282282

283-
assert decoder.config.verbose == use_custom_config
283+
assert decoder.verbose == use_custom_config
284284

285285

286286
def test_decode_via_files_multi_shot():
@@ -596,20 +596,25 @@ def test_decode_shots_bit_packed_vs_decode_batch(det_beam, beam_climbing, no_rev
596596
circuit = relabel_logical_observables(circuit=circuit, relabel_dict={0: 3})
597597
dem = circuit.detector_error_model()
598598

599-
# 2. Create the Tesseract configuration object with the parameterized values.
600-
config = tesseract_decoder.tesseract.TesseractConfig(
601-
dem=dem,
599+
# 2. Compile the Sinter-compatible decoder with the parameterized values for the DEM.
600+
sinter_decoder = tesseract_module.TesseractSinterDecoder(
601+
det_beam=det_beam,
602+
beam_climbing=beam_climbing,
603+
no_revisit_dets=no_revisit_dets,
604+
merge_errors=merge_errors,
602605
)
603-
config.det_beam = det_beam
604-
config.beam_climbing = beam_climbing
605-
config.no_revisit_dets = no_revisit_dets
606-
config.merge_errors = merge_errors
607606

608607
# 3. Compile the Sinter-compatible decoder.
609-
sinter_decoder = tesseract_module.TesseractSinterDecoder(config=config)
610608
compiled_sinter_decoder = sinter_decoder.compile_decoder_for_dem(dem=dem)
611609

612-
# 4. Compile the raw Tesseract decoder directly from the config.
610+
# 4. Obtain the compiled decoder from the config.
611+
config = tesseract_decoder.tesseract.TesseractConfig(
612+
dem=dem,
613+
det_beam=det_beam,
614+
beam_climbing=beam_climbing,
615+
no_revisit_dets=no_revisit_dets,
616+
merge_errors=merge_errors,
617+
)
613618
decoder = config.compile_decoder()
614619

615620
# 5. Generate a batch of shots and unpack them for comparison.
@@ -630,5 +635,51 @@ def test_decode_shots_bit_packed_vs_decode_batch(det_beam, beam_climbing, no_rev
630635
assert np.array_equal(predictions_sinter, predictions_decode_batch)
631636

632637

638+
def test_sinter_collect_different_dems():
639+
"""
640+
Ensures that Sinter tasks compile with different DEMs before collection.
641+
"""
642+
# Create a repetition code circuit to test the decoder.
643+
min_distance = 3
644+
max_distance = 7
645+
tasks = [
646+
sinter.Task(
647+
circuit=stim.Circuit.generated(
648+
"repetition_code:memory",
649+
distance=d,
650+
rounds=3,
651+
after_clifford_depolarization=0.1,
652+
),
653+
json_metadata={"d": d},
654+
)
655+
for d in range(min_distance, max_distance + 1, 2)
656+
]
657+
658+
# Initialize TesseractSinterDecoder with parameters for TesseractConfig and build_det_orders
659+
sinter_decoder = tesseract_module.TesseractSinterDecoder(
660+
det_beam=20,
661+
beam_climbing=True,
662+
pqlimit=1_000_000,
663+
no_revisit_dets=True,
664+
num_det_orders=21,
665+
det_order_method=tesseract_decoder.utils.DetOrder.DetIndex,
666+
seed=2384753,
667+
)
668+
669+
# Use sinter.collect to run the decoding task.
670+
all_results = sinter.collect(
671+
num_workers=1,
672+
tasks=tasks,
673+
decoders=["tesseract-long-beam"],
674+
max_shots=100, # Reduced max_shots for testing
675+
custom_decoders={"tesseract-long-beam": sinter_decoder},
676+
)
677+
678+
assert len(all_results) == len(tasks)
679+
expected_distances = [3,5,7]
680+
for i, results in enumerate(all_results):
681+
assert results.json_metadata['d'] == expected_distances[i]
682+
683+
633684
if __name__ == "__main__":
634685
raise SystemExit(pytest.main([__file__]))

src/tesseract_sinter_compat.pybind.h

Lines changed: 92 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,59 @@ struct TesseractSinterCompiledDecoder {
100100
// a decoder for a specific Detector Error Model (DEM).
101101
//--------------------------------------------------------------------------------------------------
102102
struct TesseractSinterDecoder {
103-
// Use TesseractConfig as an integrated property.
104-
TesseractConfig config;
103+
// Parameters for TesseractConfig
104+
int det_beam;
105+
bool beam_climbing;
106+
bool no_revisit_dets;
107+
bool verbose;
108+
bool merge_errors;
109+
size_t pqlimit;
110+
double det_penalty;
111+
bool create_visualization;
112+
113+
// Parameters for build_det_orders
114+
size_t num_det_orders;
115+
DetOrder det_order_method;
116+
uint64_t seed;
105117

106118
// Default constructor
107-
TesseractSinterDecoder() : config(TesseractConfig()) {}
108-
109-
// Constructor with TesseractConfig parameter
110-
TesseractSinterDecoder(const TesseractConfig& config_in) : config(config_in) {}
119+
TesseractSinterDecoder()
120+
: det_beam(DEFAULT_DET_BEAM),
121+
beam_climbing(false),
122+
no_revisit_dets(true),
123+
verbose(false),
124+
merge_errors(true),
125+
pqlimit(DEFAULT_PQLIMIT),
126+
det_penalty(0.0),
127+
create_visualization(false),
128+
num_det_orders(0),
129+
det_order_method(DetOrder::DetBFS),
130+
seed(2384753) {}
131+
132+
// Constructor with parameters
133+
TesseractSinterDecoder(int det_beam, bool beam_climbing, bool no_revisit_dets, bool verbose,
134+
bool merge_errors, size_t pqlimit, double det_penalty,
135+
bool create_visualization, size_t num_det_orders,
136+
DetOrder det_order_method, uint64_t seed)
137+
: det_beam(det_beam),
138+
beam_climbing(beam_climbing),
139+
no_revisit_dets(no_revisit_dets),
140+
verbose(verbose),
141+
merge_errors(merge_errors),
142+
pqlimit(pqlimit),
143+
det_penalty(det_penalty),
144+
create_visualization(create_visualization),
145+
num_det_orders(num_det_orders),
146+
det_order_method(det_order_method),
147+
seed(seed) {}
111148

112149
bool operator==(const TesseractSinterDecoder& other) const {
113-
return true;
150+
return det_beam == other.det_beam && beam_climbing == other.beam_climbing &&
151+
no_revisit_dets == other.no_revisit_dets && verbose == other.verbose &&
152+
merge_errors == other.merge_errors && pqlimit == other.pqlimit &&
153+
det_penalty == other.det_penalty && create_visualization == other.create_visualization &&
154+
num_det_orders == other.num_det_orders && det_order_method == other.det_order_method &&
155+
seed == other.seed;
114156
}
115157

116158
bool operator!=(const TesseractSinterDecoder& other) const {
@@ -121,8 +163,12 @@ struct TesseractSinterDecoder {
121163
TesseractSinterCompiledDecoder compile_decoder_for_dem(const py::object& dem) {
122164
const stim::DetectorErrorModel stim_dem(py::cast<std::string>(py::str(dem)).c_str());
123165

124-
TesseractConfig local_config = config;
125-
local_config.dem = stim_dem;
166+
std::vector<std::vector<size_t>> det_orders =
167+
build_det_orders(stim_dem, num_det_orders, det_order_method, seed);
168+
169+
TesseractConfig local_config = {
170+
stim_dem, det_beam, beam_climbing, no_revisit_dets, verbose,
171+
merge_errors, pqlimit, det_orders, det_penalty, create_visualization};
126172
auto decoder = std::make_unique<TesseractDecoder>(local_config);
127173

128174
return TesseractSinterCompiledDecoder{
@@ -151,9 +197,13 @@ struct TesseractSinterDecoder {
151197
dem_file.close();
152198

153199
// Construct TesseractDecoder.
154-
TesseractConfig local_config = config;
155200
const stim::DetectorErrorModel stim_dem(dem_content_str.c_str());
156-
local_config.dem = stim_dem;
201+
std::vector<std::vector<size_t>> det_orders =
202+
build_det_orders(stim_dem, num_det_orders, det_order_method, seed);
203+
204+
TesseractConfig local_config = {
205+
stim_dem, det_beam, beam_climbing, no_revisit_dets, verbose,
206+
merge_errors, pqlimit, det_orders, det_penalty, create_visualization};
157207
TesseractDecoder decoder(local_config);
158208

159209
// Calculate expected number of bytes per shot for detectors and observables.
@@ -254,14 +304,17 @@ void pybind_sinter_compat(py::module& root) {
254304
.def(py::init<>(), R"pbdoc(
255305
Initializes a new TesseractSinterDecoder instance with a default TesseractConfig.
256306
)pbdoc")
257-
.def(py::init<const TesseractConfig&>(), py::kw_only(), py::arg("config"),
258-
R"pbdoc(
259-
Initializes a new TesseractSinterDecoder instance with a custom TesseractConfig object.
260-
261-
:param config: A `TesseractConfig` object to configure the decoder.
262-
)pbdoc")
263-
.def_readwrite("config", &TesseractSinterDecoder::config,
264-
R"pbdoc(The TesseractConfig object for the decoder.)pbdoc")
307+
.def(
308+
py::init<int, bool, bool, bool, bool, size_t, double, bool, size_t, DetOrder, uint64_t>(),
309+
py::arg("det_beam") = DEFAULT_DET_BEAM, py::arg("beam_climbing") = false,
310+
py::arg("no_revisit_dets") = true, py::arg("verbose") = false,
311+
py::arg("merge_errors") = true, py::arg("pqlimit") = DEFAULT_PQLIMIT,
312+
py::arg("det_penalty") = 0.0, py::arg("create_visualization") = false,
313+
py::arg("num_det_orders") = 0, py::arg("det_order_method") = DetOrder::DetBFS,
314+
py::arg("seed") = 2384753,
315+
R"pbdoc(
316+
Initializes a new TesseractSinterDecoder instance with custom TesseractConfig parameters.
317+
)pbdoc")
265318
.def("compile_decoder_for_dem", &TesseractSinterDecoder::compile_decoder_for_dem,
266319
py::kw_only(), py::arg("dem"),
267320
R"pbdoc(
@@ -286,34 +339,36 @@ void pybind_sinter_compat(py::module& root) {
286339
bit-packed observable predictions will be written.
287340
:param tmp_dir: A temporary directory path. (Currently unused, but required by API)
288341
)pbdoc")
342+
.def_readwrite("det_beam", &TesseractSinterDecoder::det_beam)
343+
.def_readwrite("beam_climbing", &TesseractSinterDecoder::beam_climbing)
344+
.def_readwrite("no_revisit_dets", &TesseractSinterDecoder::no_revisit_dets)
345+
.def_readwrite("verbose", &TesseractSinterDecoder::verbose)
346+
.def_readwrite("merge_errors", &TesseractSinterDecoder::merge_errors)
347+
.def_readwrite("pqlimit", &TesseractSinterDecoder::pqlimit)
348+
.def_readwrite("det_penalty", &TesseractSinterDecoder::det_penalty)
349+
.def_readwrite("create_visualization", &TesseractSinterDecoder::create_visualization)
350+
.def_readwrite("num_det_orders", &TesseractSinterDecoder::num_det_orders)
351+
.def_readwrite("det_order_method", &TesseractSinterDecoder::det_order_method)
352+
.def_readwrite("seed", &TesseractSinterDecoder::seed)
289353
.def(py::self == py::self,
290354
R"pbdoc(Checks if two TesseractSinterDecoder instances are equal.)pbdoc")
291355
.def(py::self != py::self,
292356
R"pbdoc(Checks if two TesseractSinterDecoder instances are not equal.)pbdoc")
293357
.def(py::pickle(
294358
[](const TesseractSinterDecoder& self) -> py::tuple { // __getstate__
295-
return py::make_tuple(std::string(self.config.dem.str()), self.config.det_beam,
296-
self.config.beam_climbing, self.config.no_revisit_dets,
297-
self.config.verbose, self.config.merge_errors,
298-
self.config.pqlimit, self.config.det_orders,
299-
self.config.det_penalty, self.config.create_visualization);
359+
return py::make_tuple(self.det_beam, self.beam_climbing, self.no_revisit_dets,
360+
self.verbose, self.merge_errors, self.pqlimit, self.det_penalty,
361+
self.create_visualization, self.num_det_orders,
362+
self.det_order_method, self.seed);
300363
},
301364
[](py::tuple t) { // __setstate__
302-
if (t.size() != 10) {
365+
if (t.size() != 11) {
303366
throw std::runtime_error("Invalid state for TesseractSinterDecoder!");
304367
}
305-
TesseractConfig config;
306-
config.dem = stim::DetectorErrorModel(t[0].cast<std::string>());
307-
config.det_beam = t[1].cast<int>();
308-
config.beam_climbing = t[2].cast<bool>();
309-
config.no_revisit_dets = t[3].cast<bool>();
310-
config.verbose = t[4].cast<bool>();
311-
config.merge_errors = t[5].cast<bool>();
312-
config.pqlimit = t[6].cast<size_t>();
313-
config.det_orders = t[7].cast<std::vector<std::vector<size_t>>>();
314-
config.det_penalty = t[8].cast<double>();
315-
config.create_visualization = t[9].cast<bool>();
316-
return TesseractSinterDecoder(config);
368+
return TesseractSinterDecoder(
369+
t[0].cast<int>(), t[1].cast<bool>(), t[2].cast<bool>(), t[3].cast<bool>(),
370+
t[4].cast<bool>(), t[5].cast<size_t>(), t[6].cast<double>(), t[7].cast<bool>(),
371+
t[8].cast<size_t>(), t[9].cast<DetOrder>(), t[10].cast<uint64_t>());
317372
}));
318373

319374
// Add a function to create a dictionary of custom decoders

0 commit comments

Comments
 (0)