def test_ilo() -> None: b = AerBackend() bs = AerStateBackend() bu = AerUnitaryBackend() c = Circuit(2) c.X(1) assert (bs.get_state(c) == np.asarray([0, 1, 0, 0])).all() assert (bs.get_state(c, basis=BasisOrder.dlo) == np.asarray([0, 0, 1, 0])).all() assert (bu.get_unitary(c) == np.asarray([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])).all() assert (bu.get_unitary(c, basis=BasisOrder.dlo) == np.asarray([[0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0]])).all() c.measure_all() assert (b.get_shots(c, 2) == np.asarray([[0, 1], [0, 1]])).all() assert (b.get_shots(c, 2, basis=BasisOrder.dlo) == np.asarray([[1, 0], [1, 0]])).all() assert b.get_counts(c, 2) == {(0, 1): 2} assert b.get_counts(c, 2, basis=BasisOrder.dlo) == {(1, 0): 2}
def test_unitary() -> None: qc = circuit_gen() b = AerUnitaryBackend() for comp in (None, b.default_compilation_pass()): tb = TketBackend(b, comp) job = execute(qc, tb) u = job.result().get_unitary() qb = Aer.get_backend("unitary_simulator") job2 = execute(qc, qb) u2 = job2.result().get_unitary() assert np.allclose(u, u2)
def test_rebase_CX() -> None: circ = Circuit(2) circ.CX(0, 1) orig_circ = circ.copy() _aqt_rebase().apply(circ) # TODO use tketsim for this test once available u1 = AerUnitaryBackend().get_unitary(orig_circ) u2 = AerUnitaryBackend().get_unitary(circ) assert np.allclose(u1, u2)
def test_rebase_singleq() -> None: circ = Circuit(1) # some arbitrary unitary circ.add_gate(OpType.U3, [0.01231, 0.848, 38.200], [0]) orig_circ = circ.copy() _aqt_rebase().apply(circ) # TODO use tketsim for this test once available u1 = AerUnitaryBackend().get_unitary(orig_circ) u2 = AerUnitaryBackend().get_unitary(circ) assert np.allclose(u1, u2)
def test_rebase_large() -> None: circ = Circuit(3) # some arbitrary unitary circ.Rx(0.21, 0).Rz(0.12, 1).Rz(8.2, 2).X(2).CX(0, 1).CX(1, 2).Rz(0.44, 1).Rx( 0.43, 0 ) orig_circ = circ.copy() _aqt_rebase().apply(circ) # TODO use tketsim for this test once available u1 = AerUnitaryBackend().get_unitary(orig_circ) u2 = AerUnitaryBackend().get_unitary(circ) assert np.allclose(u1, u2)
def test_aerstate_result_handle() -> None: c = circuit_gen() b1 = AerStateBackend() h1 = b1.process_circuits([c])[0] state = b1.get_result(h1).get_state() status = b1.circuit_status(h1) assert status == CircuitStatus(StatusEnum.COMPLETED, "job has successfully run") assert np.allclose(state, [np.sqrt(0.5), 0, 0, math.sqrt(0.5)], atol=1e-10) b2 = AerUnitaryBackend() unitary = b2.get_unitary(c) assert np.allclose( unitary, np.sqrt(0.5) * np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 1, 0, -1], [1, 0, -1, 0]]), )
def test_compilation_correctness() -> None: c = Circuit(5) c.H(0).H(1).H(2) c.CX(0, 1).CX(1, 2) c.Rx(0.25, 1).Ry(0.75, 1).Rz(0.5, 2) c.CCX(2, 1, 0) c.CY(1, 0).CY(2, 1) c.H(0).H(1).H(2) c.Rz(0.125, 0) c.X(1) c.Rz(0.125, 2).X(2).Rz(0.25, 2) c.SX(3).Rz(0.125, 3).SX(3) c.CX(0, 3).CX(0, 4) u_backend = AerUnitaryBackend() u = u_backend.get_unitary(c) ibm_backend = IBMQBackend("ibmq_santiago", hub="ibm-q", group="open", project="main") for ol in range(3): p = ibm_backend.default_compilation_pass(optimisation_level=ol) cu = CompilationUnit(c) p.apply(cu) c1 = cu.circuit compiled_u = u_backend.get_unitary(c1) # Adjust for placement imap = cu.initial_map fmap = cu.final_map c_idx = {c.qubits[i]: i for i in range(5)} c1_idx = {c1.qubits[i]: i for i in range(5)} ini = {c_idx[qb]: c1_idx[node] for qb, node in imap.items()} inv_fin = {c1_idx[node]: c_idx[qb] for qb, node in fmap.items()} m_ini = lift_perm(ini) m_inv_fin = lift_perm(inv_fin) assert compare_unitaries(u, m_inv_fin @ compiled_u @ m_ini)
def test_swaps_basisorder() -> None: # Check that implicit swaps can be corrected irrespective of BasisOrder b = AerStateBackend() c = Circuit(4) c.X(0) c.CX(0, 1) c.CX(1, 0) c.CX(1, 3) c.CX(3, 1) c.X(2) cu = CompilationUnit(c) CliffordSimp(True).apply(cu) c1 = cu.circuit assert c1.n_gates_of_type(OpType.CX) == 2 b.compile_circuit(c) b.compile_circuit(c1) handles = b.process_circuits([c, c1]) s_ilo = b.get_state(c1, basis=BasisOrder.ilo) correct_ilo = b.get_state(c, basis=BasisOrder.ilo) assert np.allclose(s_ilo, correct_ilo) s_dlo = b.get_state(c1, basis=BasisOrder.dlo) correct_dlo = b.get_state(c, basis=BasisOrder.dlo) assert np.allclose(s_dlo, correct_dlo) qbs = c.qubits for result in b.get_results(handles): assert (result.get_state([qbs[1], qbs[2], qbs[3], qbs[0]]).real.tolist().index(1.0) == 6) assert (result.get_state([qbs[2], qbs[1], qbs[0], qbs[3]]).real.tolist().index(1.0) == 9) assert (result.get_state([qbs[2], qbs[3], qbs[0], qbs[1]]).real.tolist().index(1.0) == 12) bu = AerUnitaryBackend() u_ilo = bu.get_unitary(c1, basis=BasisOrder.ilo) correct_ilo = bu.get_unitary(c, basis=BasisOrder.ilo) assert np.allclose(u_ilo, correct_ilo) u_dlo = bu.get_unitary(c1, basis=BasisOrder.dlo) correct_dlo = bu.get_unitary(c, basis=BasisOrder.dlo) assert np.allclose(u_dlo, correct_dlo)
# - provides the full unitary matrix for a pure quantum circuit. from pytket import Circuit from pytket.extensions.qiskit import AerUnitaryBackend from pytket.predicates import NoClassicalControlPredicate # Define a simple quantum incrementer: c = Circuit(3) c.CCX(2, 1, 0) c.CX(2, 1) c.X(2) # Examine the unitary: backend = AerUnitaryBackend() backend.compile_circuit(c) unitary = backend.get_unitary(c) print(unitary.round(1).real) # ## `pytket.extensions.pyquil.ForestBackend` # Whilst normally used as the method of accessing the Rigetti QPUs, the `ForestBackend` also features a simulator mode which turns it into a noiseless sampling simulator that matches the constraints of the simulated device (e.g. the same gate set, restricted connectivity, measurement model, etc.). This is useful when playing around with custom compilation strategies to ensure that your final circuits are suitable to run on the device and for checking that your overall program works fine before you invest in reserving a QPU. # # Unique features: # - faithful recreation of the circuit constraints of Rigetti QPUs. # If trying to use the `ForestBackend` locally (i.e. not on a Rigetti QMI), you will need to have `quilc` and `qvm` running as separate processes in server mode. One easy way of doing this is with `docker` (see the `quilc` and `qvm` documentation for alternative methods of running them): # `docker run --rm -it -p 5555:5555 rigetti/quilc -R` # `docker run --rm -it -p 5000:5000 rigetti/qvm -S`