-
Notifications
You must be signed in to change notification settings - Fork 180
Add correlated_pymatching decoder to sinter builtin decoder list
#985
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
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
94252e5
Add `correlated_pymatching` decoder to `sinter` builtin decoder list
inmzhang 6983344
Merge branch 'main' into sinter-correlated-pymatching
inmzhang 588d065
Bump required pymatching version for correlated matching to v2.3.1
inmzhang 6f1d93b
Use error probability smaller than 0.5 to avoid exception from correl…
inmzhang 6d43398
Merge branch 'main' into sinter-correlated-pymatching
inmzhang e36ec51
Merge branch 'main' into sinter-correlated-pymatching
inmzhang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
glue/sample/src/sinter/_decoding/_decoding_correlated_pymatching.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| from packaging import version | ||
|
|
||
| from sinter._decoding._decoding_decoder_class import Decoder, CompiledDecoder | ||
|
|
||
|
|
||
| class CorrelatedPyMatchingCompiledDecoder(CompiledDecoder): | ||
| def __init__(self, matcher: "pymatching.Matching"): | ||
| self.matcher = matcher | ||
|
|
||
| def decode_shots_bit_packed( | ||
| self, | ||
| *, | ||
| bit_packed_detection_event_data: "np.ndarray", | ||
| ) -> "np.ndarray": | ||
| return self.matcher.decode_batch( | ||
| shots=bit_packed_detection_event_data, | ||
| bit_packed_shots=True, | ||
| bit_packed_predictions=True, | ||
| return_weights=False, | ||
| ) | ||
|
|
||
|
|
||
| class CorrelatedPyMatchingDecoder(Decoder): | ||
| """Use correlated pymatching to predict observables from detection events.""" | ||
|
|
||
| def compile_decoder_for_dem( | ||
| self, *, dem: "stim.DetectorErrorModel" | ||
| ) -> CompiledDecoder: | ||
| try: | ||
| import pymatching | ||
| except ImportError as ex: | ||
| raise ImportError( | ||
| "The decoder 'pymatching' isn't installed\n" | ||
| "To fix this, install the python package 'pymatching' into your environment.\n" | ||
| "For example, if you are using pip, run `pip install pymatching`.\n" | ||
| ) from ex | ||
|
|
||
| # correlated matching requires pymatching 2.3.1 or later | ||
| if version.parse(pymatching.__version__) < version.parse("2.3.1"): | ||
| raise ValueError(""" | ||
| The correlated pymatching decoder requires pymatching 2.3.1 or later. | ||
|
|
||
| If you're using pip to install packages, this can be fixed by running | ||
| ``` | ||
| pip install "pymatching~=2.3.1" --upgrade | ||
| ``` | ||
| """) | ||
|
|
||
| return CorrelatedPyMatchingCompiledDecoder( | ||
| pymatching.Matching.from_detector_error_model(dem, enable_correlations=True) | ||
| ) | ||
|
|
||
| def decode_via_files( | ||
| self, | ||
| *, | ||
| num_shots: int, | ||
| num_dets: int, | ||
| num_obs: int, | ||
| dem_path: "pathlib.Path", | ||
| dets_b8_in_path: "pathlib.Path", | ||
| obs_predictions_b8_out_path: "pathlib.Path", | ||
| tmp_dir: "pathlib.Path", | ||
| ) -> None: | ||
| try: | ||
| import pymatching | ||
| except ImportError as ex: | ||
| raise ImportError( | ||
| "The decoder 'pymatching' isn't installed\n" | ||
| "To fix this, install the python package 'pymatching' into your environment.\n" | ||
| "For example, if you are using pip, run `pip install pymatching`.\n" | ||
| ) from ex | ||
|
|
||
| # correlated matching requires pymatching 2.3.1 or later | ||
| if version.parse(pymatching.__version__) < version.parse("2.3.1"): | ||
| raise ValueError(""" | ||
| The correlated pymatching decoder requires pymatching 2.3.1 or later. | ||
|
|
||
| If you're using pip to install packages, this can be fixed by running | ||
| ``` | ||
| pip install "pymatching~=2.3.1" --upgrade | ||
| ``` | ||
| """) | ||
|
|
||
| if num_dets == 0: | ||
| with open(obs_predictions_b8_out_path, "wb") as f: | ||
| f.write(b"\0" * (num_obs * num_shots)) | ||
| return | ||
|
|
||
| result = pymatching.cli( | ||
| command_line_args=[ | ||
| "predict", | ||
| "--dem", | ||
| str(dem_path), | ||
| "--in", | ||
| str(dets_b8_in_path), | ||
| "--in_format", | ||
| "b8", | ||
| "--out", | ||
| str(obs_predictions_b8_out_path), | ||
| "--out_format", | ||
| "b8", | ||
| "--enable_correlations", | ||
| ] | ||
| ) | ||
| if result: | ||
| raise ValueError("pymatching.cli returned a non-zero exit code") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,11 @@ def get_test_decoders() -> Tuple[List[str], Dict[str, sinter.Decoder]]: | |
| custom_decoders = {} | ||
| try: | ||
| import pymatching | ||
| from packaging import version | ||
|
|
||
| if version.parse(pymatching.__version__) < version.parse("2.3.0"): | ||
| available_decoders.remove('correlated_pymatching') | ||
|
|
||
| except ImportError: | ||
| available_decoders.remove('pymatching') | ||
| try: | ||
|
|
@@ -234,7 +239,7 @@ def test_no_detectors_with_post_mask(decoder: str, force_streaming: Optional[boo | |
| @pytest.mark.parametrize('decoder,force_streaming', DECODER_CASES) | ||
| def test_post_selection(decoder: str, force_streaming: Optional[bool]): | ||
| circuit = stim.Circuit(""" | ||
| X_ERROR(0.6) 0 | ||
| X_ERROR(0.4) 0 | ||
| M 0 | ||
| DETECTOR(2, 0, 0, 1) rec[-1] | ||
| OBSERVABLE_INCLUDE(0) rec[-1] | ||
|
|
@@ -243,7 +248,7 @@ def test_post_selection(decoder: str, force_streaming: Optional[bool]): | |
| M 1 | ||
| DETECTOR(1, 0, 0) rec[-1] | ||
| OBSERVABLE_INCLUDE(0) rec[-1] | ||
|
|
||
| X_ERROR(0.1) 2 | ||
| M 2 | ||
| OBSERVABLE_INCLUDE(0) rec[-1] | ||
|
|
@@ -259,9 +264,9 @@ def test_post_selection(decoder: str, force_streaming: Optional[bool]): | |
| __private__unstable__force_decode_on_disk=force_streaming, | ||
| custom_decoders=TEST_CUSTOM_DECODERS, | ||
| ) | ||
| assert 1050 <= result.discards <= 1350 | ||
| assert 650 <= result.discards <= 950 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this changed to a non-overlapping range? |
||
| if 'vacuous' not in decoder: | ||
| assert 40 <= result.errors <= 160 | ||
| assert 60 <= result.errors <= 240 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this changed? |
||
|
|
||
|
|
||
| @pytest.mark.parametrize('decoder,force_streaming', DECODER_CASES) | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
This was potentially intentionally testing the ability to handle probabilities larger than 0.5. Why was it changed?
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.
If the correlated version of pymatching can't support errors larger than 50% yet, then I don't think it's ready to be added as a default supported decoder yet.
Uh oh!
There was an error while loading. Please reload this page.
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.
Fair enough, but is it not still useful to include even if it doesn't support this? Surely p>0.5 errors are a much rarer property of practical stim circuits than matchability? I can look into supporting negative edge weights with correlations but it's possible it will require a major refactor. The approach I took in #1012 was to skip this test for pymatching-correlated.