-
Notifications
You must be signed in to change notification settings - Fork 17
Allow TesseractSinterDecoder to be compiled with different DEMs #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Allow TesseractSinterDecoder to be compiled with different DEMs #130
Conversation
e8dc93e to
a686e65
Compare
|
Thank you, this looks excellent! I wonder if it might worth including the |
|
We could also add a small example of how to use Tesseract with sinter in the main Tesseract README.md at the root of the directory (as is done in the chromobius repo, for example). This would make it much easier for new users to get started. |
|
Sounds good, I'll add those suggestions in! |
a686e65 to
2168aa5
Compare
README.md
Outdated
| ``` | ||
| ## Using Tesseract with Sinter | ||
|
|
||
| Tesseract can be easily integrated into [Sinter](https://github.com/quantumlib/Sinter) workflows. Sinter is a tool for running and organizing quantum error correction simulations. The `tesseract_sinter_compat` module provides the necessary interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Tesseract can be easily integrated into [Sinter](https://github.com/quantumlib/Sinter) workflows. Sinter is a tool for running and organizing quantum error correction simulations. The `tesseract_sinter_compat` module provides the necessary interface. | |
| Tesseract can be easily integrated into [sinter](https://github.com/quantumlib/Stim/tree/main/glue/sample) workflows. Sinter is a tool for running and organizing quantum error correction simulations. The `tesseract_sinter_compat` module provides the necessary interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks.
README.md
Outdated
| # Logical error rate: 0.0153 | ||
| ``` | ||
|
|
||
| This example runs simulations for a repetition code with different distances [3, 5, 7] with different Tesseract default decoders. Sinter efficiently manages the execution of these tasks, and Tesseract is used for decoding. For more usage examples, see the tests in `src/py/tesseract_sinter_compat_test.py`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could add a command line example here too, e.g.:
This example runs simulations for a repetition code with different distances [3, 5, 7] with different Tesseract default decoders.
Sinter can also be used at the command line. Here is an example of this using Tesseract:
sinter collect \
--circuits "example_circuit.stim" \
--decoders tesseract-long-beam \
--custom_decoders_module_function "tesseract_decoder:make_tesseract_sinter_decoders_dict" \
--max_shots 100_000 \
--max_errors 100
--processes auto \
--save_resume_filepath "stats.csv" \
Sinter efficiently manages the execution of these tasks, and Tesseract is used for decoding. For more usage examples, see the tests in src/py/tesseract_sinter_compat_test.py.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SG I'll add that in.
TesseractSinterDecoder visible from the root module.
85b3230 to
a1a42f3
Compare
README.md
Outdated
| tasks=tasks, | ||
| max_shots=10000, | ||
| decoders=decoders, | ||
| custom_decoders=tesseract_module.make_tesseract_sinter_decoders_dict(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| custom_decoders=tesseract_module.make_tesseract_sinter_decoders_dict(), | |
| custom_decoders=make_tesseract_sinter_decoders_dict(), |
README.md
Outdated
| decoders=decoders, | ||
| custom_decoders=tesseract_module.make_tesseract_sinter_decoders_dict(), | ||
| ) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be good to include one example of using the tesseract_decoder.TesseractSinterDecoder constructor with a full set of custom arguments. E.g. here's a full example (though maybe could be made more concise if combined with the example above):
import stim
import sinter
from tesseract_decoder import TesseractSinterDecoder
import tesseract_decoder
if __name__ == "__main__":
custom_sinter_decoder = TesseractSinterDecoder(
det_beam=10,
beam_climbing=True,
no_revisit_dets=True,
merge_errors=True,
pqlimit=1_000,
num_det_orders=5,
det_order_method=tesseract_decoder.utils.DetOrder.DetIndex,
seed=2384753,
)
p = 0.005
tasks = [
sinter.Task(
circuit=stim.Circuit.generated(
"surface_code:rotated_memory_x",
distance=d,
rounds=d,
after_clifford_depolarization=p,
),
json_metadata={"d": d, "r": d, "p": p},
)
for d in (3, 5)
]
results = sinter.collect(
num_workers=2,
tasks=tasks,
max_shots=10_000,
decoders=["custom-tesseract-decoder"],
custom_decoders={"custom-tesseract-decoder": custom_sinter_decoder},
print_progress=True,
)
README.md
Outdated
| decoder=decoders[i], | ||
| json_metadata={"d": distance, "decoder": decoders[i]}, | ||
| )) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that from here on needs to be after an:
if __name__ == "__main__":
Might be worth making sure that the example code works right away after copy-pasting (e.g. without the above fix the sinter error can be a bit confusing...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made some tweaks and tested it in a standalone python file.
bit of a refactor to make the code more concise. Tested it in a standalone python file as well.
README.md
Outdated
| for result in results: | ||
| print(f"task metadata = {result.json_metadata}") | ||
| print(f" Shots run: {result.shots}") | ||
| print(f" Observed errors: {result.errors}") | ||
| print(f" Logical error rate: {result.errors / result.shots}") | ||
|
|
||
| # Should get something like: | ||
| # task metadata = {'d': 3, 'decoder': 'tesseract'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 48 | ||
| # Logical error rate: 0.0048 | ||
| # task metadata = {'d': 3, 'decoder': 'custom-tesseract-decoder'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 64 | ||
| # Logical error rate: 0.0064 | ||
| # task metadata = {'d': 5, 'decoder': 'tesseract-short-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 13 | ||
| # Logical error rate: 0.0013 | ||
| # task metadata = {'d': 5, 'decoder': 'custom-tesseract-decoder'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 12 | ||
| # Logical error rate: 0.0012 | ||
| # task metadata = {'d': 3, 'decoder': 'tesseract-long-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 42 | ||
| # Logical error rate: 0.0042 | ||
| # task metadata = {'d': 3, 'decoder': 'tesseract-short-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 39 | ||
| # Logical error rate: 0.0039 | ||
| # task metadata = {'d': 5, 'decoder': 'tesseract'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 15 | ||
| # Logical error rate: 0.0015 | ||
| # task metadata = {'d': 5, 'decoder': 'tesseract-long-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 13 | ||
| # Logical error rate: 0.0013 | ||
| # task metadata = {'d': 7, 'decoder': 'tesseract'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 5 | ||
| # Logical error rate: 0.0005 | ||
| # task metadata = {'d': 7, 'decoder': 'tesseract-long-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 1 | ||
| # Logical error rate: 0.0001 | ||
| # task metadata = {'d': 7, 'decoder': 'tesseract-short-beam'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 3 | ||
| # Logical error rate: 0.0003 | ||
| # task metadata = {'d': 7, 'decoder': 'custom-tesseract-decoder'} | ||
| # Shots run: 10000 | ||
| # Observed errors: 3 | ||
| # Logical error rate: 0.0003 | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, just a nit: maybe we could just print out the csv instead as that will take up less vertical space on the README:
| for result in results: | |
| print(f"task metadata = {result.json_metadata}") | |
| print(f" Shots run: {result.shots}") | |
| print(f" Observed errors: {result.errors}") | |
| print(f" Logical error rate: {result.errors / result.shots}") | |
| # Should get something like: | |
| # task metadata = {'d': 3, 'decoder': 'tesseract'} | |
| # Shots run: 10000 | |
| # Observed errors: 48 | |
| # Logical error rate: 0.0048 | |
| # task metadata = {'d': 3, 'decoder': 'custom-tesseract-decoder'} | |
| # Shots run: 10000 | |
| # Observed errors: 64 | |
| # Logical error rate: 0.0064 | |
| # task metadata = {'d': 5, 'decoder': 'tesseract-short-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 13 | |
| # Logical error rate: 0.0013 | |
| # task metadata = {'d': 5, 'decoder': 'custom-tesseract-decoder'} | |
| # Shots run: 10000 | |
| # Observed errors: 12 | |
| # Logical error rate: 0.0012 | |
| # task metadata = {'d': 3, 'decoder': 'tesseract-long-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 42 | |
| # Logical error rate: 0.0042 | |
| # task metadata = {'d': 3, 'decoder': 'tesseract-short-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 39 | |
| # Logical error rate: 0.0039 | |
| # task metadata = {'d': 5, 'decoder': 'tesseract'} | |
| # Shots run: 10000 | |
| # Observed errors: 15 | |
| # Logical error rate: 0.0015 | |
| # task metadata = {'d': 5, 'decoder': 'tesseract-long-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 13 | |
| # Logical error rate: 0.0013 | |
| # task metadata = {'d': 7, 'decoder': 'tesseract'} | |
| # Shots run: 10000 | |
| # Observed errors: 5 | |
| # Logical error rate: 0.0005 | |
| # task metadata = {'d': 7, 'decoder': 'tesseract-long-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 1 | |
| # Logical error rate: 0.0001 | |
| # task metadata = {'d': 7, 'decoder': 'tesseract-short-beam'} | |
| # Shots run: 10000 | |
| # Observed errors: 3 | |
| # Logical error rate: 0.0003 | |
| # task metadata = {'d': 7, 'decoder': 'custom-tesseract-decoder'} | |
| # Shots run: 10000 | |
| # Observed errors: 3 | |
| # Logical error rate: 0.0003 | |
| ``` | |
| # Print samples as CSV data. | |
| print(sinter.CSV_HEADER) | |
| for sample in results: | |
| print(sample.to_csv_line()) |
should get something like:
shots, errors, discards, seconds,decoder,strong_id,json_metadata,custom_counts
10000, 42, 0, 0.071,tesseract,1b3fce6286e438f38c00c8f6a5005947373515ab08e6446a7dd9ecdbef12d4cc,"{""d"":3,""decoder"":""tesseract""}",
10000, 49, 0, 0.546,custom-tesseract-decoder,7b082bec7541be858e239d7828a432e329cd448356bbdf051b8b8aa76c86625a,"{""d"":3,""decoder"":""custom-tesseract-decoder""}",
10000, 13, 0, 7.64,tesseract-long-beam,217a3542f56319924576658a6da7081ea2833f5167cf6d77fbc7071548e386a9,"{""d"":5,""decoder"":""tesseract-long-beam""}",
10000, 42, 0, 0.743,tesseract-short-beam,cf4a4b0ce0e4c7beec1171f58eddffe403ed7359db5016fca2e16174ea577057,"{""d"":3,""decoder"":""tesseract-short-beam""}",
10000, 34, 0, 0.924,tesseract-long-beam,8cfa0f2e4061629e13bc98fe213285dc00eb90f21bba36e08c76bcdf213a1c09,"{""d"":3,""decoder"":""tesseract-long-beam""}",
10000, 10, 0, 0.439,tesseract,8274ea5ffec15d6e71faed5ee1057cdd7e497cbaee4c6109784f8a74669d7f96,"{""d"":5,""decoder"":""tesseract""}",
10000, 8, 0, 3.93,custom-tesseract-decoder,8e4f5ab5dde00fec74127eea39ea52d5a98ae6ccfc277b5d9be450f78acc1c45,"{""d"":5,""decoder"":""custom-tesseract-decoder""}",
10000, 10, 0, 5.74,tesseract-short-beam,bf696535d62a25720c3a0c624ec5624002efe3f6cb0468963eee702efb48abc1,"{""d"":5,""decoder"":""tesseract-short-beam""}",
10000, 5, 0, 1.27,tesseract,3f94c61f1503844df6cf0d200b74ac01bfbc5e29e70cedbfc2faad67047e7887,"{""d"":7,""decoder"":""tesseract""}",
10000, 4, 0, 25.0,tesseract-long-beam,4d510f0acf511e24a833a93c956b683346696d8086866fadc73063fb09014c23,"{""d"":7,""decoder"":""tesseract-long-beam""}",
10000, 1, 0, 18.6,tesseract-short-beam,75782ce4593022fcedad4c73104711f05c9c635db92869531f78da336945b121,"{""d"":7,""decoder"":""tesseract-short-beam""}",
10000, 4, 0, 11.6,custom-tesseract-decoder,48f256a28fff47c58af7bffdf98fdee1d41a721751ee965c5d3c5712ac795dc8,"{""d"":7,""decoder"":""custom-tesseract-decoder""}",
build_det_orders() is now called within compile_decoder_for_dem() to ensure the right configuration (for the DEM) is being used in each Sinter task. Previously, the TesseractConfig would always be using a single
det_ordersdespite it depending upon the DEM for the task.TesseractSinterDecoderrequires DEM to be configured correctly #129.num_det_orders,det_order_method, andseed.