-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve stimcirq serialization #7192
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
Merged
dstrain115
merged 8 commits into
quantumlib:main
from
dstrain115:better_stimcirq_serialization
Apr 2, 2025
Merged
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
1f04aae
Better stimcirq serialization
dstrain115 b1d5ab8
Fix coverage and typing.
dstrain115 266c914
try again for typecheck
dstrain115 ddc52aa
Merge branch 'main' into better_stimcirq_serialization
dstrain115 d82b52a
Fix merge issues.
dstrain115 6532090
sort imports
dstrain115 7c0c25d
Merge branch 'main' of https://github.com/quantumlib/Cirq into better…
dstrain115 21c1101
Add serializer unit tests.
dstrain115 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
101 changes: 101 additions & 0 deletions
101
cirq-google/cirq_google/serialization/stimcirq_deserializer.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,101 @@ | ||
# Copyright 2019 The Cirq Developers | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import functools | ||
from typing import Any, Dict, List | ||
|
||
import cirq | ||
from cirq_google.api import v2 | ||
from cirq_google.serialization import arg_func_langs | ||
from cirq_google.serialization.op_deserializer import OpDeserializer | ||
|
||
|
||
@functools.cache | ||
def _stimcirq_json_resolvers(): | ||
"""Retrieves stimcirq JSON resolvers if stimcirq is installed. | ||
Returns an empty dict if not installed.""" | ||
try: | ||
import stimcirq | ||
|
||
return stimcirq.JSON_RESOLVERS_DICT | ||
except ModuleNotFoundError: # pragma: no cover | ||
return {} # pragma: no cover | ||
|
||
|
||
class StimCirqDeserializer(OpDeserializer): | ||
"""Describes how to serialize CircuitOperations.""" | ||
|
||
def can_deserialize_proto(self, proto: v2.program_pb2.Operation): | ||
return ( | ||
proto.WhichOneof('gate_value') == 'internalgate' | ||
and proto.internalgate.module == 'stimcirq' | ||
) | ||
|
||
def from_proto( | ||
self, | ||
proto: v2.program_pb2.Operation, | ||
*, | ||
constants: List[v2.program_pb2.Constant], | ||
deserialized_constants: List[Any], | ||
) -> cirq.Operation: | ||
"""Turns a cirq_google Operation proto into a stimcirq object. | ||
|
||
Args: | ||
proto: The proto object to be deserialized. | ||
constants: The list of Constant protos referenced by constant | ||
table indices in `proto`. This list should already have been | ||
parsed to produce 'deserialized_constants'. | ||
deserialized_constants: The deserialized contents of `constants`. | ||
|
||
Returns: | ||
The deserialized stimcirq object | ||
|
||
Raises: | ||
ValueError: If stimcirq is not installed or the object is not recognized. | ||
""" | ||
resolvers = _stimcirq_json_resolvers() | ||
cls_name = proto.internalgate.name | ||
|
||
if cls_name not in resolvers: | ||
raise ValueError(f"stimcirq object {proto} not recognized. (Is stimcirq installed?)") | ||
|
||
# Resolve each of the serialized arguments | ||
kwargs: Dict[str, Any] = {} | ||
for k, v in proto.internalgate.gate_args.items(): | ||
if k == "pauli": | ||
# Special Handling for pauli gate | ||
pauli = v.arg_value.string_value | ||
if pauli == "X": | ||
kwargs[k] = cirq.X | ||
elif pauli == "Y": | ||
kwargs[k] = cirq.Y | ||
elif pauli == "Z": | ||
kwargs[k] = cirq.Z | ||
else: | ||
raise ValueError(f"Unknown stimcirq pauli Gate {v}") | ||
continue | ||
|
||
arg = arg_func_langs.arg_from_proto(v) | ||
if arg is not None: | ||
kwargs[k] = arg | ||
|
||
# Instantiate the class from the stimcirq resolvers | ||
op = resolvers[cls_name](**kwargs) | ||
|
||
# If this operation has qubits, add them | ||
qubits = [deserialized_constants[q] for q in proto.qubit_constant_index] | ||
if qubits: | ||
op = op(*qubits) | ||
|
||
return op |
39 changes: 39 additions & 0 deletions
39
cirq-google/cirq_google/serialization/stimcirq_deserializer_test.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,39 @@ | ||
# Copyright 2025 The Cirq Developers | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import pytest | ||
|
||
from cirq_google.api import v2 | ||
from cirq_google.serialization.stimcirq_deserializer import StimCirqDeserializer | ||
|
||
|
||
def test_bad_stimcirq_op(): | ||
proto = v2.program_pb2.Operation() | ||
proto.internalgate.module = 'stimcirq' | ||
proto.internalgate.name = 'WolfgangPauli' | ||
|
||
with pytest.raises(ValueError, match='not recognized'): | ||
_ = StimCirqDeserializer().from_proto(proto, constants=[], deserialized_constants=[]) | ||
|
||
|
||
def test_bad_pauli_gate(): | ||
proto = v2.program_pb2.Operation() | ||
proto.internalgate.module = 'stimcirq' | ||
proto.internalgate.name = 'SweepPauli' | ||
proto.internalgate.gate_args['stim_sweep_bit_index'].arg_value.float_value = 1.0 | ||
proto.internalgate.gate_args['cirq_sweep_symbol'].arg_value.string_value = 't' | ||
proto.internalgate.gate_args['pauli'].arg_value.string_value = 'Q' | ||
|
||
with pytest.raises(ValueError, match='pauli'): | ||
_ = StimCirqDeserializer().from_proto(proto, constants=[], deserialized_constants=[]) |
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.
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.
year?
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.
Done