def test_honeywell() -> None:
    token = os.getenv("HQS_AUTH")
    backend = HoneywellBackend(
        device_name="HQS-LT-1.0-APIVAL", machine_debug=skip_remote_tests
    )
    c = Circuit(4, 4, "test 1")
    c.H(0)
    c.CX(0, 1)
    c.Rz(0.3, 2)
    c.CSWAP(0, 1, 2)
    c.CRz(0.4, 2, 3)
    c.CY(1, 3)
    c.ZZPhase(0.1, 2, 0)
    c.Tdg(3)
    c.measure_all()
    backend.compile_circuit(c)
    n_shots = 4
    handle = backend.process_circuits([c], n_shots)[0]
    correct_shots = np.zeros((4, 4))
    correct_counts = {(0, 0, 0, 0): 4}
    res = backend.get_result(handle, timeout=49)
    shots = res.get_shots()
    counts = res.get_counts()
    assert backend.circuit_status(handle).status is StatusEnum.COMPLETED
    assert np.all(shots == correct_shots)
    assert counts == correct_counts
    newshots = backend.get_shots(c, 4, timeout=49)
    assert np.all(newshots == correct_shots)
    newcounts = backend.get_counts(c, 4)
    assert newcounts == correct_counts
    if token is None:
        assert backend.device is None
示例#2
0
def test_rebase() -> None:
    """
    Check that we can compile from a circuit containing non-Q# gates.
    """
    b = QsharpSimulatorBackend()
    c = Circuit(2)
    c.CY(0, 1)
    b.compile_circuit(c)
示例#3
0
def test_aqt() -> None:
    # Run a circuit on the noisy simulator.
    token = cast(str, os.getenv("AQT_AUTH"))
    b = AQTBackend(token, device_name="sim/noise-model-1", label="test 1")
    c = Circuit(4, 4)
    c.H(0)
    c.CX(0, 1)
    c.Rz(0.3, 2)
    c.CSWAP(0, 1, 2)
    c.CRz(0.4, 2, 3)
    c.CY(1, 3)
    c.add_barrier([0, 1])
    c.ZZPhase(0.1, 2, 0)
    c.Tdg(3)
    c.measure_all()
    b.compile_circuit(c)
    n_shots = 10
    shots = b.get_shots(c, n_shots, seed=1, timeout=30)
    counts = b.get_counts(c, n_shots)
    assert len(shots) == n_shots
    assert sum(counts.values()) == n_shots
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)
示例#5
0
c.CX(x, y)

c1 = Circuit()
c1.add_qubit(x)
c1.add_qubit(y)
c1.CZ(y, x)

c.append(c1)

print(c.get_commands())

# If either circuit contains wires not matching any wires in the other, those are added to the other circuit before composition:

z = Qubit("z")
c1.add_qubit(z)
c1.CY(y, z)
c.append(c1)
print(c.qubits)
print(c.get_commands())

# If the sets of unit IDs for the two circuits are disjoint, then the composition is entirely parallel.
#
# What if we want to serially compose two circuits having different sets of `Qubit`? In that case, we can use the `rename_units()` method on one or other of them to bring them into line. This method takes a dictionary mapping current unit IDs to new one:

c2 = Circuit()
c2.add_q_register("w", 3)
w = [Qubit("w", i) for i in range(3)]
c2.H(w[0]).CX(w[0], w[1]).CRz(0.25, w[1], w[2])

c.rename_units({x: w[0], y: w[1], z: w[2]})
示例#6
0
print(tk_to_qiskit(circ2))

# Note that the pass we just ran also performed some clean-up: the SWAP gate was decomposed into three CX gates, one of which was cancelled by a preceding CX gate; the cancelling gates were removed from the circuit.
#
# Every compilation pass has associated sets of preconditions and postconditions on the circuit. If all preconditions are satisfied before the pass, all postconditions are guaranteed to be satisfied afterwards. When we apply a pass to a circuit, we can optionally pass `SafetyMode.Audit` as the second parameter; this will tell the pass to check all preconditions explicitly. By default, there is only limited checking of preconditions and `pytket` relies on the programmer assuring these.
#
# For example, the `NoClassicalControl` predicate is a precondition of the `PauliSimp` pass. Let's add a classically controlled gate to our circuit:

from pytket.passes import PauliSimp, SafetyMode
from pytket.circuit import Qubit, Bit

q = [Qubit("q", i) for i in range(5)]
c = Bit("c")
circ.add_bit(c)
circ.Measure(q[3], c)
circ.CY(q[0], q[1], condition_bits=[c], condition_value=1)
cu = CompilationUnit(circ)
try:
    PauliSimp().apply(cu, safety_mode=SafetyMode.Audit)
except RuntimeError as e:
    print("Error:", str(e))

# The preconditions and postconditions of all the elementary predicates are documented in their string representations:

PauliSimp()

# ## Backends and default passes

# A `pytket` `Backend` may have a default compilation pass, which will guarantee that the circuit can run on it. This is given by the `default_compilation_pass` property. For example, the default pass for Qiskit's `AerBackend` just converts all gates to U1, U2, U3 and CX:

from pytket.extensions.qiskit import AerBackend