Skip to content

Commit ad65b82

Browse files
Make Tesseract compatible with Sinter (#88)
Address issue #55 --------- Co-authored-by: Oscar Higgott <[email protected]>
1 parent 2a62de2 commit ad65b82

File tree

10 files changed

+1750
-5
lines changed

10 files changed

+1750
-5
lines changed

src/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pybind_library(
7272
"simplex.pybind.h",
7373
"visualization.pybind.h",
7474
"tesseract.pybind.h",
75+
"tesseract_sinter_compat.pybind.h",
7576
],
7677
deps = [
7778
":libcommon",
@@ -91,7 +92,6 @@ pybind_extension(
9192
],
9293
)
9394

94-
9595
py_library(
9696
name="lib_tesseract_decoder",
9797
imports=["src"],

src/py/BUILD

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ py_test(
7272
":shared_decoding_tests",
7373
],
7474
)
75+
py_test(
76+
name = "tesseract_sinter_compat_test",
77+
srcs = ["tesseract_sinter_compat_test.py"],
78+
visibility = ["//:__subpackages__"],
79+
deps = [
80+
"@pypi//pytest",
81+
"@pypi//stim",
82+
"@pypi//sinter",
83+
"//src:lib_tesseract_decoder",
84+
],
85+
)
86+
7587

7688
compile_pip_requirements(
7789
name = "requirements",

src/py/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,91 @@ print("\nEstimated DEM:")
481481
print(estimated_dem)
482482
# Expected probabilities: D0 -> 100/1000 = 0.1, D1 -> 250/1000 = 0.25, D2 -> 40/1000 = 0.04
483483
```
484+
485+
### Sinter Integration
486+
The Tesseract Python interface is compatible with the Sinter framework, which is a powerful tool for large-scale decoding, benchmarking, and error-rate estimation.
487+
488+
#### The TesseractSinterDecoder Object
489+
All Sinter examples rely on this utility function to provide the Sinter-compatible Tesseract decoder.
490+
491+
```python
492+
import sinter
493+
import stim
494+
from sinter._decoding._decoding import sample_decode
495+
496+
from src.tesseract_decoder import tesseract_sinter_compat as tesseract_module
497+
from src import tesseract_decoder
498+
499+
# Define a function that returns a dictionary mapping a decoder name to its
500+
# Sinter-compatible decoder object.
501+
def get_tesseract_decoder_for_sinter():
502+
return tesseract_module.make_tesseract_sinter_decoders_dict()
503+
```
504+
505+
#### Decoding with `sinter.collect`
506+
`sinter.collect` is a powerful function for running many decoding jobs in parallel and collecting the results for large-scale benchmarking.
507+
508+
```python
509+
# Create a repetition code circuit to test the decoder.
510+
circuit = stim.Circuit.generated(
511+
'repetition_code:memory',
512+
distance=3,
513+
rounds=3,
514+
after_clifford_depolarization=0.01
515+
)
516+
517+
# Use sinter.collect to run the decoding task.
518+
results, = sinter.collect(
519+
num_workers=1,
520+
tasks=[sinter.Task(circuit=circuit)],
521+
decoders=["tesseract"],
522+
max_shots=1000,
523+
custom_decoders=get_tesseract_decoder_for_sinter(),
524+
)
525+
526+
# Print a summary of the decoding results.
527+
print("Basic Repetition Code Decoding Results:")
528+
print(f"Shots run: {results.shots}")
529+
print(f"Observed errors: {results.errors}")
530+
print(f"Logical error rate: {results.errors / results.shots}")
531+
```
532+
533+
#### Running with multiple workers
534+
This example demonstrates how to use multiple worker threads to speed up the simulation.
535+
```python
536+
# Use sinter.collect with multiple workers for faster decoding.
537+
results, = sinter.collect(
538+
num_workers=4,
539+
tasks=[sinter.Task(circuit=circuit)],
540+
decoders=["tesseract"],
541+
max_shots=10000,
542+
custom_decoders=get_tesseract_decoder_for_sinter(),
543+
)
544+
545+
print("\nDecoding with 4 worker threads:")
546+
print(f"Shots run: {results.shots}")
547+
print(f"Observed errors: {results.errors}")
548+
print(f"Logical error rate: {results.errors / results.shots}")
549+
```
550+
551+
#### Decoding with `sinter.sample_decode`
552+
`sinter.sample_decode` is a simpler, non-parallel function for directly decoding a single circuit. It's useful for quick tests and debugging without the overhead of the `sinter.collect` framework.
553+
554+
```python
555+
# Create a repetition code circuit.
556+
circuit = stim.Circuit.generated('repetition_code:memory', distance=5, rounds=5)
557+
558+
# Use sinter.sample_decode for a direct decoding run.
559+
result = sample_decode(
560+
circuit_obj=circuit,
561+
dem_obj=circuit.detector_error_model(),
562+
num_shots=1000,
563+
decoder="tesseract",
564+
custom_decoders=get_tesseract_decoder_for_sinter(),
565+
)
566+
567+
print("Basic sample_decode Results:")
568+
print(f"Shots run: {result.shots}")
569+
print(f"Observed errors: {result.errors}")
570+
print(f"Logical error rate: {result.errors / result.shots}")
571+
```

src/py/requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
stim
22
pytest
3+
sinter

src/py/requirements_lock.txt

Lines changed: 475 additions & 3 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)