예제 #1
0
    def optimization_at(self, circuit: Circuit, index: int,
                        op: Operation) -> Optional[PointOptimizationSummary]:

        if isinstance(op.gate, (MeasurementGate, SingleQubitGate, WaitGate)):
            new_op = op
        else:
            if op.gate is None:
                raise IncompatibleMomentError(
                    f'Operation {op} has a missing gate')
            translated_gate = self._simulator.gates_translator(op.gate)
            if translated_gate is None:
                raise IncompatibleMomentError(
                    f'Moment contains non-single qubit operation '
                    f'{op} with unsupported gate')
            a, b = op.qubits
            new_op = self._simulator.create_gate_with_drift(
                a, b, translated_gate).on(a, b)

        return PointOptimizationSummary(clear_span=1,
                                        clear_qubits=op.qubits,
                                        new_operations=new_op)
예제 #2
0
파일: workflow.py 프로젝트: zchen088/Cirq
def _make_zeta_chi_gamma_compensation(
    circuit_with_calibration: CircuitWithCalibration,
    characterizations: List[PhasedFSimCalibrationResult],
    gates_translator: Callable[[Gate], Optional[PhaseCalibratedFSimGate]],
    permit_mixed_moments: bool,
) -> CircuitWithCalibration:

    if permit_mixed_moments:
        raise NotImplementedError(
            'Mixed moments compensation ist supported yet')

    if len(circuit_with_calibration.circuit) != len(
            circuit_with_calibration.moment_to_calibration):
        raise ValueError('Moment allocations does not match circuit length')

    default_phases = PhasedFSimCharacterization(zeta=0.0, chi=0.0, gamma=0.0)

    compensated = Circuit()
    compensated_moment_to_calibration: List[Optional[int]] = []
    for moment, characterization_index in zip(
            circuit_with_calibration.circuit,
            circuit_with_calibration.moment_to_calibration):
        parameters = None
        if characterization_index is not None:
            parameters = characterizations[characterization_index]

        decompositions: List[Tuple[Tuple[Operation, ...], ...]] = []
        other: List[Operation] = []
        new_moment_moment_to_calibration: Optional[List[Optional[int]]] = None
        for op in moment:
            if not isinstance(op, GateOperation):
                raise IncompatibleMomentError(
                    'Moment contains operation different than GateOperation')

            if isinstance(op.gate, _CALIBRATION_IRRELEVANT_GATES):
                other.append(op)
                continue

            a, b = op.qubits
            translated = gates_translator(op.gate)
            if translated is None:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains unsupported non-single qubit operation {op}'
                )

            if parameters is None:
                raise ValueError(
                    f'Missing characterization data for moment {moment}')

            pair_parameters = parameters.get_parameters(a, b)
            if pair_parameters is None:
                raise ValueError(
                    f'Missing characterization data for pair {(a, b)} in {parameters}'
                )
            pair_parameters = pair_parameters.merge_with(default_phases)

            corrections = FSimPhaseCorrections.from_characterization(
                (a, b),
                translated,
                pair_parameters,
                characterization_index,
            )
            decompositions.append(corrections.operations)

            if new_moment_moment_to_calibration is None:
                new_moment_moment_to_calibration = corrections.moment_to_calibration
            else:
                assert (
                    new_moment_moment_to_calibration ==
                    corrections.moment_to_calibration
                ), f'Inconsistent decompositions with a moment {moment}'

        if other and decompositions:
            raise IncompatibleMomentError(
                f'Moment {moment} contains mixed operations')
        elif other:
            compensated += Moment(other)
            compensated_moment_to_calibration.append(characterization_index)
        elif decompositions:
            for operations in itertools.zip_longest(*decompositions,
                                                    fillvalue=()):
                compensated += Moment(operations)
            assert new_moment_moment_to_calibration is not None  # Required for mypy
            compensated_moment_to_calibration += new_moment_moment_to_calibration

    return CircuitWithCalibration(compensated,
                                  compensated_moment_to_calibration)
예제 #3
0
파일: workflow.py 프로젝트: zchen088/Cirq
def _list_moment_pairs_to_characterize(
    moment: Moment,
    gates_translator: Callable[[Gate], Optional[PhaseCalibratedFSimGate]],
    canonicalize_pairs: bool,
    permit_mixed_moments: bool,
) -> Optional[Tuple[List[Tuple[Qid, Qid]], Gate]]:
    """Describes a given moment in terms of a Floquet characterization request.

    Args:
        moment: Moment to characterize.
        gates_translator: Function that translates a gate to a supported FSimGate which will undergo
            characterization.
        canonicalize_pairs: Whether to sort each of the qubit pair so that the first qubit
            is always lower than the second.
        permit_mixed_moments: Whether to allow a mix of two-qubit gates with other irrelevant
            single-qubit gates.

    Returns:
        Tuple with list of pairs to characterize and gate that should be used for characterization,
        or None when no gate to characterize exists in a given moment.

    Raises:
        IncompatibleMomentError when a moment contains operations other than the operations matched
        by gates_translator, or it mixes a single qubit and two qubit gates.
    """
    other_operation = False
    gate: Optional[FSimGate] = None
    pairs = []

    for op in moment:
        if not isinstance(op, GateOperation):
            raise IncompatibleMomentError(
                'Moment contains operation different than GateOperation')

        if isinstance(op.gate, _CALIBRATION_IRRELEVANT_GATES):
            other_operation = True
        else:
            translated = gates_translator(op.gate)
            if translated is None:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains unsupported non-single qubit operation {op}'
                )

            if gate is not None and gate != translated.engine_gate:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains operations resolved to two different gates {gate} '
                    f'and {translated.engine_gate}')
            else:
                gate = translated.engine_gate

            pair = cast(
                Tuple[Qid, Qid],
                tuple(sorted(op.qubits) if canonicalize_pairs else op.qubits))
            pairs.append(pair)

    if gate is None:
        # Either empty, single-qubit or measurement moment.
        return None
    elif not permit_mixed_moments and other_operation:
        raise IncompatibleMomentError(
            f'Moment contains mixed two-qubit operations and either single-qubit measurement or '
            f'wait operations.')

    return pairs, gate
예제 #4
0
def make_floquet_request_for_moment(
    moment: Moment,
    options: FloquetPhasedFSimCalibrationOptions,
    gates_translator: Callable[
        [Gate], Optional[FSimGate]] = try_convert_sqrt_iswap_to_fsim,
    canonicalize_pairs: bool = False,
    sort_pairs: bool = False,
) -> Optional[FloquetPhasedFSimCalibrationRequest]:
    """Describes a given moment in terms of a Floquet characterization request.

    Args:
        moment: Moment to characterize.
        options: Options that are applied to each characterized gate within a moment.
        gates_translator: Function that translates a gate to a supported FSimGate which will undergo
            characterization. Defaults to sqrt_iswap_gates_translator.
        canonicalize_pairs: Whether to sort each of the qubit pair so that the first qubit
            is always lower than the second.
        sort_pairs: Whether to sort all the qutibt pairs extracted from the moment which will
            undergo characterization.

    Returns:
        Instance of FloquetPhasedFSimCalibrationRequest that characterizes a given moment, or None
        when it is an empty, measurement or single-qubit gates only moment.

    Raises:
        IncompatibleMomentError when a moment contains operations other than the operations matched
        by gates_translator, or it mixes a single qubit and two qubit gates.
    """

    measurement = False
    single_qubit = False
    gate: Optional[FSimGate] = None
    pairs = []

    for op in moment:
        if not isinstance(op, GateOperation):
            raise IncompatibleMomentError(
                'Moment contains operation different than GateOperation')

        if isinstance(op.gate, MeasurementGate):
            measurement = True
        elif isinstance(op.gate, SingleQubitGate):
            single_qubit = True
        else:
            translated_gate = gates_translator(op.gate)
            if translated_gate is None:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains unsupported non-single qubit operation {op}'
                )
            elif gate is not None and gate != translated_gate:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains operations resolved to two different gates {gate} '
                    f'and {translated_gate}')
            else:
                gate = translated_gate
            pair = cast(
                Tuple[Qid, Qid],
                tuple(sorted(op.qubits) if canonicalize_pairs else op.qubits))
            pairs.append(pair)

    if gate is None:
        # Either empty, single-qubit or measurement moment.
        return None

    if gate is not None and (measurement or single_qubit):
        raise IncompatibleMomentError(
            f'Moment contains mixed two-qubit operations and '
            f'single-qubit operations or measurement operations.')

    return FloquetPhasedFSimCalibrationRequest(
        pairs=tuple(sorted(pairs) if sort_pairs else pairs),
        gate=gate,
        options=options)
예제 #5
0
def zeta_chi_gamma_calibration_for_moments(
    circuit_with_calibration: CircuitWithCalibration,
    characterizations: List[PhasedFSimCalibrationResult],
    gates_translator: Callable[[Gate], Optional[FSimGate]] = try_convert_sqrt_iswap_to_fsim,
) -> CircuitWithCalibration:
    """Compensates circuit against errors in zeta, chi and gamma angles.

    This method creates a new circuit with a single-qubit Z gates added in a such way so that
    zeta, chi and gamma angles discovered by characterizations are cancelled-out and set to 0.

    This function preserves a moment structure of the circuit. All single qubit gates appear on new
    moments in the final circuit.

    Args:
        circuit_with_calibration: A CircuitWithCalibration (likely returned from run_calibrations)
            whose mapping argument corresponds to the results in the characterizations argument.
        characterizations: List of characterization results (likely returned from run_calibrations).
            This should correspond to the circuit and mapping in the circuit_with_calibration
            argument.
        gates_translator: Function that translates a gate to a supported FSimGate which will undergo
            characterization. Defaults to sqrt_iswap_gates_translator.

    Returns:
        Calibrated circuit together with its calibration metadata in CircuitWithCalibration object.
        The calibrated circuit has single-qubit Z gates added which compensates for the true gates
        imperfections.
        The moment to calibration mapping is updated for the new circuit so that successive
        calibrations could be applied.
    """
    if len(circuit_with_calibration.circuit) != len(circuit_with_calibration.moment_to_calibration):
        raise ValueError('Moment allocations does not match circuit length')

    default_phases = PhasedFSimCharacterization(zeta=0.0, chi=0.0, gamma=0.0)

    compensated = Circuit()
    compensated_moment_to_calibration: List[Optional[int]] = []
    for moment, characterization_index in zip(
        circuit_with_calibration.circuit, circuit_with_calibration.moment_to_calibration
    ):
        parameters = None
        if characterization_index is not None:
            parameters = characterizations[characterization_index]

        decompositions: List[Tuple[Tuple[Operation, ...], ...]] = []
        other: List[Operation] = []
        new_moment_moment_to_calibration: Optional[List[Optional[int]]] = None
        for op in moment:
            if not isinstance(op, GateOperation):
                raise IncompatibleMomentError(
                    'Moment contains operation different than GateOperation'
                )

            if isinstance(op.gate, (MeasurementGate, SingleQubitGate)):
                other.append(op)
                continue

            a, b = op.qubits
            translated_gate = gates_translator(op.gate)
            if translated_gate is None:
                raise IncompatibleMomentError(
                    f'Moment {moment} contains unsupported non-single qubit operation {op}'
                )

            if parameters is None:
                raise ValueError(f'Missing characterization data for moment {moment}')

            pair_parameters = parameters.get_parameters(a, b)
            if pair_parameters is None:
                raise ValueError(f'Missing characterization data for pair {(a, b)} in {parameters}')
            pair_parameters = pair_parameters.merge_with(default_phases)

            corrections = FSimPhaseCorrections.from_characterization(
                (a, b), translated_gate, pair_parameters, characterization_index
            )
            decompositions.append(corrections.operations)

            if new_moment_moment_to_calibration is None:
                new_moment_moment_to_calibration = corrections.moment_to_calibration
            else:
                assert (
                    new_moment_moment_to_calibration == corrections.moment_to_calibration
                ), f'Inconsistent decompositions with a moment {moment}'

        if other and decompositions:
            raise IncompatibleMomentError(f'Moment {moment} contains mixed operations')
        elif other:
            compensated += Moment(other)
            compensated_moment_to_calibration.append(characterization_index)
        elif decompositions:
            for operations in zip_longest(*decompositions, fillvalue=()):
                compensated += Moment(operations)
            assert new_moment_moment_to_calibration is not None  # Required for mypy
            compensated_moment_to_calibration += new_moment_moment_to_calibration

    return CircuitWithCalibration(compensated, compensated_moment_to_calibration)