예제 #1
0
def default_compilation_pass(self, optimisation_level: int = 1) -> BasePass:
    """
    A suggested compilation pass that will guarantee the resulting circuit
    will be suitable to run on this backend with as few preconditions as
    possible.

    :param optimisation_level: The level of optimisation to perform during
        compilation. Level 0 just solves the device constraints without
        optimising. Level 1 additionally performs some light optimisations.
        Level 2 adds more intensive optimisations that can increase compilation
        time for large circuits. Defaults to 1.
    :type optimisation_level: int, optional
    :return: Compilation pass guaranteeing required predicates.
    :rtype: BasePass
    """
    assert optimisation_level in range(3)
    cx_circ = Circuit(2)
    cx_circ.Sdg(0)
    cx_circ.V(1)
    cx_circ.Sdg(1)
    cx_circ.Vdg(1)
    cx_circ.add_gate(OpType.ZZMax, [0, 1])
    cx_circ.Vdg(1)
    cx_circ.Sdg(1)
    cx_circ.add_phase(0.5)

    def sq(a, b, c):
        circ = Circuit(1)
        if c != 0:
            circ.Rz(c, 0)
        if b != 0:
            circ.Rx(b, 0)
        if a != 0:
            circ.Rz(a, 0)
        return circ

    rebase = RebaseCustom({OpType.ZZMax}, cx_circ,
                          {OpType.Rx, OpType.Ry, OpType.Rz}, sq)
    squash = SquashCustom({OpType.Rz, OpType.Rx, OpType.Ry}, sq)
    seq = [DecomposeBoxes()]  # Decompose boxes into basic gates
    if optimisation_level == 1:
        seq.append(SynthesiseIBM())  # Optional fast optimisation
    elif optimisation_level == 2:
        seq.append(FullPeepholeOptimise())  # Optional heavy optimisation
    seq.append(rebase)  # Map to target gate set
    if optimisation_level != 0:
        seq.append(
            squash)  # Optionally simplify 1qb gate chains within this gate set
    return SequencePass(seq)
예제 #2
0
def add_operator_term(circuit: Circuit, term: QubitPauliString, angle: float):
    qubits = []
    for q, p in term.to_dict().items():
        if p != Pauli.I:
            qubits.append(q)
            if p == Pauli.X:
                circuit.H(q)
            elif p == Pauli.Y:
                circuit.V(q)
    for i in range(len(qubits) - 1):
        circuit.CX(i, i + 1)
    circuit.Rz(angle, len(qubits) - 1)
    for i in reversed(range(len(qubits) - 1)):
        circuit.CX(i, i + 1)
    for q, p in term.to_dict().items():
        if p == Pauli.X:
            circuit.H(q)
        elif p == Pauli.Y:
            circuit.Vdg(q)