Ejemplo n.º 1
0
    def parse_result(self,
                     result: CalibrationResult) -> PhasedFSimCalibrationResult:
        decoded: Dict[int, Dict[str,
                                Any]] = collections.defaultdict(lambda: {})
        for keys, values in result.metrics['angles'].items():
            for key, value in zip(keys, values):
                match = re.match(r'(\d+)_(.+)', str(key))
                if not match:
                    raise ValueError(f'Unknown metric name {key}')
                index = int(match[1])
                name = match[2]
                decoded[index][name] = value

        parsed = {}
        for data in decoded.values():
            a = v2.qubit_from_proto_id(data['qubit_a'])
            b = v2.qubit_from_proto_id(data['qubit_b'])
            parsed[(a, b)] = PhasedFSimCharacterization(
                theta=data.get('theta_est', None),
                zeta=data.get('zeta_est', None),
                chi=data.get('chi_est', None),
                gamma=data.get('gamma_est', None),
                phi=data.get('phi_est', None),
            )

        return PhasedFSimCalibrationResult(parameters=parsed,
                                           gate=self.gate,
                                           options=self.options)
def load_sample_device_zphase(processor_id: str) -> util.ZPhaseDataType:
    """Loads sample Z phase errors for the given device.

    Args:
        processor_id: name of the processor to simulate.

    Returns:
        Z phases in the form {gate_type: {angle_type: {qubit_pair: error}}},
        where gate_type is "syc" or "sqrt_iswap", angle_type is "zeta" or
        "gamma", and "qubit_pair" is a tuple of qubits.

    Raises:
        ValueError: if processor_id is not a supported QCS processor.
    """
    zphase_name = ZPHASE_DATA.get(processor_id, None)
    if zphase_name is None:
        raise ValueError(
            f"Got processor_id={processor_id}, but no Z phase data is defined for that processor."
        )
    path = pathlib.Path(__file__).parent.parent.resolve()
    with path.joinpath('devices', 'calibrations', zphase_name).open() as f:
        raw_data = json.load(f)

        nested_data: util.ZPhaseDataType = {
            gate_type: {
                angle:
                {(v2.qubit_from_proto_id(q0), v2.qubit_from_proto_id(q1)): vals
                 for q0, q1, vals in triples}
                for angle, triples in angles.items()
            }
            for gate_type, angles in raw_data.items()
        }
    return nested_data
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    def deserialize(
        self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None
    ) -> cirq.Circuit:
        """Deserialize a Circuit from a cirq_google.api.v2.Program.

        Args:
            proto: A dictionary representing a cirq_google.api.v2.Program proto.
            device: If the proto is for a schedule, a device is required
                Otherwise optional.

        Returns:
            The deserialized Circuit, with a device if device was not None.

        Raises:
            ValueError: If the given proto has no language or the langauge gate set mismatches
                that specified in as the name of this serialized gate set. Also if deserializing
                a schedule is attempted.
            NotImplementedError: If the program proto does not contain a circuit or schedule.
        """
        if not proto.HasField('language') or not proto.language.gate_set:
            raise ValueError('Missing gate set specification.')
        if proto.language.gate_set != self.name:
            raise ValueError(
                'Gate set in proto was {} but expected {}'.format(
                    proto.language.gate_set, self.name
                )
            )
        which = proto.WhichOneof('program')
        arg_func_language = (
            proto.language.arg_function_language or arg_func_langs.MOST_PERMISSIVE_LANGUAGE
        )

        if which == 'circuit':
            deserialized_constants: List[Any] = []
            for constant in proto.constants:
                which_const = constant.WhichOneof('const_value')
                if which_const == 'string_value':
                    deserialized_constants.append(constant.string_value)
                elif which_const == 'circuit_value':
                    circuit = self._deserialize_circuit(
                        constant.circuit_value,
                        arg_function_language=arg_func_language,
                        constants=proto.constants,
                        deserialized_constants=deserialized_constants,
                    )
                    deserialized_constants.append(circuit.freeze())
                elif which_const == 'qubit':
                    deserialized_constants.append(v2.qubit_from_proto_id(constant.qubit.id))
            circuit = self._deserialize_circuit(
                proto.circuit,
                arg_function_language=arg_func_language,
                constants=proto.constants,
                deserialized_constants=deserialized_constants,
            )
            return circuit if device is None else circuit.with_device(device)
        if which == 'schedule':
            raise ValueError('Deserializing a schedule is no longer supported.')

        raise NotImplementedError('Program proto does not contain a circuit.')
Ejemplo n.º 5
0
    def parse_result(
            self,
            result: CalibrationResult,
            job: Optional[EngineJob] = None) -> PhasedFSimCalibrationResult:
        if result.code != v2.calibration_pb2.SUCCESS:
            raise PhasedFSimCalibrationError(result.error_message)

        decoded: Dict[int, Dict[str,
                                Any]] = collections.defaultdict(lambda: {})
        for keys, values in result.metrics['angles'].items():
            for key, value in zip(keys, values):
                match = re.match(r'(\d+)_(.+)', str(key))
                if not match:
                    raise ValueError(f'Unknown metric name {key}')
                index = int(match[1])
                name = match[2]
                decoded[index][name] = value

        parsed = {}
        for data in decoded.values():
            a = v2.qubit_from_proto_id(data['qubit_a'])
            b = v2.qubit_from_proto_id(data['qubit_b'])
            parsed[(a, b)] = PhasedFSimCharacterization(
                theta=data.get('theta_est', None),
                zeta=data.get('zeta_est', None),
                chi=data.get('chi_est', None),
                gamma=data.get('gamma_est', None),
                phi=data.get('phi_est', None),
            )

        return PhasedFSimCalibrationResult(
            parameters=parsed,
            gate=self.gate,
            options=self.options,
            project_id=None if job is None else job.project_id,
            program_id=None if job is None else job.program_id,
            job_id=None if job is None else job.job_id,
        )
Ejemplo n.º 6
0
def test_generic_qubit_from_proto_id():
    assert v2.qubit_from_proto_id('1_2') == cirq.GridQubit(1, 2)
    assert v2.qubit_from_proto_id('1') == cirq.LineQubit(1)
    assert v2.qubit_from_proto_id('a') == cirq.NamedQubit('a')

    # Despite the fact that int(1_2_3) = 123, only pure numbers are parsed into
    # LineQubits.
    assert v2.qubit_from_proto_id('1_2_3') == cirq.NamedQubit('1_2_3')

    # All non-int-parseable names are converted to NamedQubits.
    assert v2.qubit_from_proto_id('a') == cirq.NamedQubit('a')
    assert v2.qubit_from_proto_id('1_b') == cirq.NamedQubit('1_b')
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    def from_proto(
        self,
        proto: v2.program_pb2.CircuitOperation,
        *,
        arg_function_language: str = '',
        constants: List[v2.program_pb2.Constant] = None,
        deserialized_constants: List[Any] = None,
    ) -> cirq.CircuitOperation:
        """Turns a cirq.google.api.v2.CircuitOperation proto into a CircuitOperation.

        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`. This list should already have been
                parsed to produce 'deserialized_constants'.
            deserialized_constants: The deserialized contents of `constants`.

        Returns:
            The deserialized CircuitOperation represented by `proto`.
        """
        if constants is None or deserialized_constants is None:
            raise ValueError(
                'CircuitOp deserialization requires a constants list and a corresponding list of '
                'post-deserialization values (deserialized_constants).'
            )
        if len(deserialized_constants) <= proto.circuit_constant_index:
            raise ValueError(
                f'Constant index {proto.circuit_constant_index} in CircuitOperation '
                'does not appear in the deserialized_constants list '
                f'(length {len(deserialized_constants)}).'
            )
        circuit = deserialized_constants[proto.circuit_constant_index]
        if not isinstance(circuit, cirq.FrozenCircuit):
            raise ValueError(
                f'Constant at index {proto.circuit_constant_index} was expected to be a circuit, '
                f'but it has type {type(circuit)} in the deserialized_constants list.'
            )

        which_rep_spec = proto.repetition_specification.WhichOneof('repetition_value')
        if which_rep_spec == 'repetition_count':
            rep_ids = None
            repetitions = proto.repetition_specification.repetition_count
        elif which_rep_spec == 'repetition_ids':
            rep_ids = proto.repetition_specification.repetition_ids.ids
            repetitions = len(rep_ids)
        else:
            rep_ids = None
            repetitions = 1

        qubit_map = {
            v2.qubit_from_proto_id(entry.key.id): v2.qubit_from_proto_id(entry.value.id)
            for entry in proto.qubit_map.entries
        }
        measurement_key_map = {
            entry.key.string_key: entry.value.string_key
            for entry in proto.measurement_key_map.entries
        }
        arg_map = {
            arg_func_langs.arg_from_proto(
                entry.key, arg_function_language=arg_function_language
            ): arg_func_langs.arg_from_proto(
                entry.value, arg_function_language=arg_function_language
            )
            for entry in proto.arg_map.entries
        }

        for arg in arg_map.keys():
            if not isinstance(arg, (str, sympy.Symbol)):
                raise ValueError(
                    'Invalid key parameter type in deserialized CircuitOperation. '
                    f'Expected str or sympy.Symbol, found {type(arg)}.'
                    f'\nFull arg: {arg}'
                )

        for arg in arg_map.values():
            if not isinstance(arg, (str, sympy.Symbol, float, int)):
                raise ValueError(
                    'Invalid value parameter type in deserialized CircuitOperation. '
                    f'Expected str, sympy.Symbol, or number; found {type(arg)}.'
                    f'\nFull arg: {arg}'
                )

        return cirq.CircuitOperation(
            circuit,
            repetitions,
            qubit_map,
            measurement_key_map,
            arg_map,  # type: ignore
            rep_ids,
        )