3838 op_deserializer ,
3939 op_serializer ,
4040 serializer ,
41+ stimcirq_deserializer ,
42+ stimcirq_serializer ,
4143 tag_deserializer ,
4244 tag_serializer ,
4345)
4749# CircuitSerializer is the dedicated serializer for the v2.5 format.
4850_SERIALIZER_NAME = 'v2_5'
4951
50- # Package name for stimcirq
51- _STIMCIRQ_MODULE = "stimcirq"
52-
5352
5453class CircuitSerializer (serializer .Serializer ):
5554 """A class for serializing and deserializing programs and operations.
@@ -93,6 +92,8 @@ def __init__(
9392 self .op_deserializer = op_deserializer
9493 self .tag_serializer = tag_serializer
9594 self .tag_deserializer = tag_deserializer
95+ self .stimcirq_serializer = stimcirq_serializer .StimCirqSerializer ()
96+ self .stimcirq_deserializer = stimcirq_deserializer .StimCirqDeserializer ()
9697
9798 def serialize (
9899 self , program : cirq .AbstractCircuit , msg : Optional [v2 .program_pb2 .Program ] = None
@@ -160,6 +161,10 @@ def _serialize_circuit(
160161 self .op_serializer .to_proto (
161162 op , op_pb , constants = constants , raw_constants = raw_constants
162163 )
164+ elif self .stimcirq_serializer .can_serialize_operation (op ):
165+ self .stimcirq_serializer .to_proto (
166+ op , op_pb , constants = constants , raw_constants = raw_constants
167+ )
163168 else :
164169 self ._serialize_gate_op (
165170 op , op_pb , constants = constants , raw_constants = raw_constants
@@ -174,6 +179,10 @@ def _serialize_circuit(
174179 self .op_serializer .to_proto (
175180 op , op_pb , constants = constants , raw_constants = raw_constants
176181 )
182+ elif self .stimcirq_serializer .can_serialize_operation (op ):
183+ self .stimcirq_serializer .to_proto (
184+ op , op_pb , constants = constants , raw_constants = raw_constants
185+ )
177186 else :
178187 self ._serialize_gate_op (
179188 op , op_pb , constants = constants , raw_constants = raw_constants
@@ -277,30 +286,6 @@ def _serialize_gate_op(
277286 arg_func_langs .float_arg_to_proto (
278287 gate .q1_detune_mhz , out = msg .couplerpulsegate .q1_detune_mhz
279288 )
280- elif getattr (op , "__module__" , "" ).startswith (_STIMCIRQ_MODULE ) or getattr (
281- gate , "__module__" , ""
282- ).startswith (_STIMCIRQ_MODULE ):
283- # Special handling for stimcirq objects, which can be both operations and gates.
284- stimcirq_obj = (
285- op if getattr (op , "__module__" , "" ).startswith (_STIMCIRQ_MODULE ) else gate
286- )
287- if stimcirq_obj is not None and hasattr (stimcirq_obj , '_json_dict_' ):
288- # All stimcirq gates currently have _json_dict_defined
289- msg .internalgate .name = type (stimcirq_obj ).__name__
290- msg .internalgate .module = _STIMCIRQ_MODULE
291- if isinstance (stimcirq_obj , cirq .Gate ):
292- msg .internalgate .num_qubits = stimcirq_obj .num_qubits ()
293- else :
294- msg .internalgate .num_qubits = len (stimcirq_obj .qubits )
295-
296- # Store json_dict objects in gate_args
297- for k , v in stimcirq_obj ._json_dict_ ().items ():
298- arg_func_langs .arg_to_proto (value = v , out = msg .internalgate .gate_args [k ])
299- else :
300- # New stimcirq op without a json dict has been introduced
301- raise ValueError (
302- f'Cannot serialize stimcirq { op !r} :{ type (gate )} '
303- ) # pragma: no cover
304289 else :
305290 raise ValueError (f'Cannot serialize op { op !r} of type { type (gate )} ' )
306291
@@ -438,6 +423,12 @@ def deserialize(self, proto: v2.program_pb2.Program) -> cirq.Circuit:
438423 constants = proto .constants ,
439424 deserialized_constants = deserialized_constants ,
440425 )
426+ elif self .stimcirq_deserializer .can_deserialize_proto (constant .operation_value ):
427+ op_pb = self .stimcirq_deserializer .from_proto (
428+ constant .operation_value ,
429+ constants = proto .constants ,
430+ deserialized_constants = deserialized_constants ,
431+ )
441432 else :
442433 op_pb = self ._deserialize_gate_op (
443434 constant .operation_value ,
@@ -517,6 +508,10 @@ def _deserialize_moment(
517508 gate_op = self .op_deserializer .from_proto (
518509 op , constants = constants , deserialized_constants = deserialized_constants
519510 )
511+ elif self .stimcirq_deserializer .can_deserialize_proto (op ):
512+ gate_op = self .stimcirq_deserializer .from_proto (
513+ op , constants = constants , deserialized_constants = deserialized_constants
514+ )
520515 else :
521516 gate_op = self ._deserialize_gate_op (
522517 op , constants = constants , deserialized_constants = deserialized_constants
@@ -718,20 +713,7 @@ def _deserialize_gate_op(
718713 op = cirq .ResetChannel (dimension = dimensions )(* qubits )
719714 elif which_gate_type == 'internalgate' :
720715 msg = operation_proto .internalgate
721- if msg .module == _STIMCIRQ_MODULE and msg .name in _stimcirq_json_resolvers ():
722- # special handling for stimcirq
723- # Use JSON resolver to instantiate the object
724- kwargs = {}
725- for k , v in msg .gate_args .items ():
726- arg = arg_func_langs .arg_from_proto (v )
727- if arg is not None :
728- kwargs [k ] = arg
729- op = _stimcirq_json_resolvers ()[msg .name ](** kwargs )
730- if qubits :
731- op = op (* qubits )
732- else :
733- # all other internal gates
734- op = arg_func_langs .internal_gate_from_proto (msg )(* qubits )
716+ op = arg_func_langs .internal_gate_from_proto (msg )(* qubits )
735717 elif which_gate_type == 'couplerpulsegate' :
736718 gate = CouplerPulse (
737719 hold_time = cirq .Duration (
0 commit comments