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)
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)