def from_proto( self, proto: v2.program_pb2.Operation, *, arg_function_language: str = '', constants: List[v2.program_pb2.Constant] = None, ) -> 'cirq.Operation': """Turns a cirq_google.api.v2.Operation proto into a GateOperation.""" qubits = [v2.qubit_from_proto_id(q.id) for q in proto.qubits] args = self._args_from_proto(proto, arg_function_language=arg_function_language) if self.num_qubits_param is not None: args[self.num_qubits_param] = len(qubits) gate = self.gate_constructor(**args) op = self.op_wrapper(gate.on(*qubits), proto) if self.deserialize_tokens: which = proto.WhichOneof('token') if which == 'token_constant_index': if not constants: raise ValueError( 'Proto has references to constants table ' 'but none was passed in, value =' f'{proto}' ) op = op.with_tags( CalibrationTag(constants[proto.token_constant_index].string_value) ) elif which == 'token_value': op = op.with_tags(CalibrationTag(proto.token_value)) return op
def from_proto( self, proto: v2.program_pb2.Operation, *, arg_function_language: str = '', constants: List[v2.program_pb2.Constant] = None, deserialized_constants: List[Any] = None, # unused ) -> cirq.Operation: """Turns a cirq_google.api.v2.Operation proto into a GateOperation. Args: proto: The proto object to be deserialized. arg_function_language: The `arg_function_language` field from `Program.Language`. constants: The list of Constant protos referenced by constant table indices in `proto`. deserialized_constants: Unused in this method. Returns: The deserialized GateOperation represented by `proto`. Raises: ValueError: If the proto references a missing constants table, or a required arg is missing. """ qubits = [v2.qubit_from_proto_id(q.id) for q in proto.qubits] args = self._args_from_proto( proto, arg_function_language=arg_function_language) if self._num_qubits_param is not None: args[self._num_qubits_param] = len(qubits) gate = self._gate_constructor(**args) op = self._op_wrapper(gate.on(*qubits), proto) if self._deserialize_tokens: which = proto.WhichOneof('token') if which == 'token_constant_index': if not constants: raise ValueError('Proto has references to constants table ' 'but none was passed in, value =' f'{proto}') op = op.with_tags( CalibrationTag( constants[proto.token_constant_index].string_value)) elif which == 'token_value': op = op.with_tags(CalibrationTag(proto.token_value)) return op
def _deserialize_gate_op( self, operation_proto: v2.program_pb2.Operation, *, arg_function_language: str = '', constants: Optional[List[v2.program_pb2.Constant]] = None, deserialized_constants: Optional[List[Any]] = None, ) -> cirq.Operation: """Deserialize an Operation from a cirq_google.api.v2.Operation. Args: operation_proto: A dictionary representing a cirq.google.api.v2.Operation proto. arg_function_language: The `arg_function_language` field from `Program.Language`. constants: The list of Constant protos referenced by constant table indices in `proto`. deserialized_constants: The deserialized contents of `constants`. cirq_google.api.v2.Operation proto. Returns: The deserialized Operation. """ if deserialized_constants is not None: qubits = [ deserialized_constants[q] for q in operation_proto.qubit_constant_index ] else: qubits = [] for q in operation_proto.qubits: # Preserve previous functionality in case # constants table was not used qubits.append(v2.qubit_from_proto_id(q.id)) which_gate_type = operation_proto.WhichOneof('gate_value') if which_gate_type == 'xpowgate': op = cirq.XPowGate(exponent=arg_func_langs.float_arg_from_proto( operation_proto.xpowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ))(*qubits) elif which_gate_type == 'ypowgate': op = cirq.YPowGate(exponent=arg_func_langs.float_arg_from_proto( operation_proto.ypowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ))(*qubits) elif which_gate_type == 'zpowgate': op = cirq.ZPowGate(exponent=arg_func_langs.float_arg_from_proto( operation_proto.zpowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ))(*qubits) if operation_proto.zpowgate.is_physical_z: op = op.with_tags(PhysicalZTag()) elif which_gate_type == 'phasedxpowgate': exponent = arg_func_langs.float_arg_from_proto( operation_proto.phasedxpowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ) phase_exponent = arg_func_langs.float_arg_from_proto( operation_proto.phasedxpowgate.phase_exponent, arg_function_language=arg_function_language, required_arg_name=None, ) op = cirq.PhasedXPowGate(exponent=exponent, phase_exponent=phase_exponent)(*qubits) elif which_gate_type == 'phasedxzgate': x_exponent = arg_func_langs.float_arg_from_proto( operation_proto.phasedxzgate.x_exponent, arg_function_language=arg_function_language, required_arg_name=None, ) z_exponent = arg_func_langs.float_arg_from_proto( operation_proto.phasedxzgate.z_exponent, arg_function_language=arg_function_language, required_arg_name=None, ) axis_phase_exponent = arg_func_langs.float_arg_from_proto( operation_proto.phasedxzgate.axis_phase_exponent, arg_function_language=arg_function_language, required_arg_name=None, ) op = cirq.PhasedXZGate( x_exponent=x_exponent, z_exponent=z_exponent, axis_phase_exponent=axis_phase_exponent, )(*qubits) elif which_gate_type == 'czpowgate': op = cirq.CZPowGate(exponent=arg_func_langs.float_arg_from_proto( operation_proto.czpowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ))(*qubits) elif which_gate_type == 'iswappowgate': op = cirq.ISwapPowGate( exponent=arg_func_langs.float_arg_from_proto( operation_proto.iswappowgate.exponent, arg_function_language=arg_function_language, required_arg_name=None, ))(*qubits) elif which_gate_type == 'fsimgate': theta = arg_func_langs.float_arg_from_proto( operation_proto.fsimgate.theta, arg_function_language=arg_function_language, required_arg_name=None, ) phi = arg_func_langs.float_arg_from_proto( operation_proto.fsimgate.phi, arg_function_language=arg_function_language, required_arg_name=None, ) if isinstance(theta, (float, sympy.Basic)) and isinstance( phi, (float, sympy.Basic)): op = cirq.FSimGate(theta=theta, phi=phi)(*qubits) else: raise ValueError( 'theta and phi must be specified for FSimGate') elif which_gate_type == 'measurementgate': key = arg_func_langs.arg_from_proto( operation_proto.measurementgate.key, arg_function_language=arg_function_language, required_arg_name=None, ) invert_mask = arg_func_langs.arg_from_proto( operation_proto.measurementgate.invert_mask, arg_function_language=arg_function_language, required_arg_name=None, ) if isinstance(invert_mask, list) and isinstance(key, str): op = cirq.MeasurementGate( num_qubits=len(qubits), key=key, invert_mask=tuple(invert_mask))(*qubits) else: raise ValueError( f'Incorrect types for measurement gate {invert_mask} {key}' ) elif which_gate_type == 'waitgate': total_nanos = arg_func_langs.float_arg_from_proto( operation_proto.waitgate.duration_nanos, arg_function_language=arg_function_language, required_arg_name=None, ) op = cirq.WaitGate(duration=cirq.Duration(nanos=total_nanos))( *qubits) else: raise ValueError( f'Unsupported serialized gate with type "{which_gate_type}".' f'\n\noperation_proto:\n{operation_proto}') which = operation_proto.WhichOneof('token') if which == 'token_constant_index': if not constants: raise ValueError('Proto has references to constants table ' 'but none was passed in, value =' f'{operation_proto}') op = op.with_tags( CalibrationTag(constants[ operation_proto.token_constant_index].string_value)) elif which == 'token_value': op = op.with_tags(CalibrationTag(operation_proto.token_value)) return op
def _serialize_gate_op( self, op: cirq.Operation, msg: v2.program_pb2.Operation, *, constants: List[v2.program_pb2.Constant], raw_constants: Dict[Any, int], arg_function_language: Optional[str] = '', ) -> v2.program_pb2.Operation: """Serialize an Operation to cirq_google.api.v2.Operation proto. Args: op: The operation to serialize. msg: An optional proto object to populate with the serialization results. arg_function_language: The `arg_function_language` field from `Program.Language`. constants: The list of previously-serialized Constant protos. raw_constants: A map raw objects to their respective indices in `constants`. Returns: The cirq.google.api.v2.Operation proto. """ gate = op.gate if isinstance(gate, cirq.XPowGate): arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.xpowgate.exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.YPowGate): arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.ypowgate.exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.ZPowGate): arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.zpowgate.exponent, arg_function_language=arg_function_language, ) if any(isinstance(tag, PhysicalZTag) for tag in op.tags): msg.zpowgate.is_physical_z = True elif isinstance(gate, cirq.PhasedXPowGate): arg_func_langs.float_arg_to_proto( gate.phase_exponent, out=msg.phasedxpowgate.phase_exponent, arg_function_language=arg_function_language, ) arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.phasedxpowgate.exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.PhasedXZGate): arg_func_langs.float_arg_to_proto( gate.x_exponent, out=msg.phasedxzgate.x_exponent, arg_function_language=arg_function_language, ) arg_func_langs.float_arg_to_proto( gate.z_exponent, out=msg.phasedxzgate.z_exponent, arg_function_language=arg_function_language, ) arg_func_langs.float_arg_to_proto( gate.axis_phase_exponent, out=msg.phasedxzgate.axis_phase_exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.CZPowGate): arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.czpowgate.exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.ISwapPowGate): arg_func_langs.float_arg_to_proto( gate.exponent, out=msg.iswappowgate.exponent, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.FSimGate): arg_func_langs.float_arg_to_proto( gate.theta, out=msg.fsimgate.theta, arg_function_language=arg_function_language, ) arg_func_langs.float_arg_to_proto( gate.phi, out=msg.fsimgate.phi, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.MeasurementGate): arg_func_langs.arg_to_proto( gate.key, out=msg.measurementgate.key, arg_function_language=arg_function_language, ) arg_func_langs.arg_to_proto( gate.invert_mask, out=msg.measurementgate.invert_mask, arg_function_language=arg_function_language, ) elif isinstance(gate, cirq.WaitGate): arg_func_langs.float_arg_to_proto( gate.duration.total_nanos(), out=msg.waitgate.duration_nanos, arg_function_language=arg_function_language, ) else: raise ValueError( f'Cannot serialize op {op!r} of type {type(gate)}') for qubit in op.qubits: if qubit not in raw_constants: constants.append( v2.program_pb2.Constant(qubit=v2.program_pb2.Qubit( id=v2.qubit_to_proto_id(qubit)))) raw_constants[qubit] = len(constants) - 1 msg.qubit_constant_index.append(raw_constants[qubit]) for tag in op.tags: if isinstance(tag, CalibrationTag): constant = v2.program_pb2.Constant() constant.string_value = tag.token if tag.token in raw_constants: msg.token_constant_index = raw_constants[tag.token] else: # Token not found, add it to the list msg.token_constant_index = len(constants) constants.append(constant) if raw_constants is not None: raw_constants[tag.token] = msg.token_constant_index return msg