예제 #1
0
def test_cannot_deallocate_same_qubit():
    mapper = BoundedQubitMapper(1)
    engine = MainEngine(
        Simulator(),
        engine_list=[mapper],
        verbose=True,
    )
    qureg = engine.allocate_qubit()
    qubit_id = qureg[0].id
    engine.deallocate_qubit(qureg[0])

    with pytest.raises(RuntimeError) as excinfo:
        deallocate_cmd = Command(
            engine=engine,
            gate=DeallocateQubitGate(),
            qubits=([WeakQubitRef(engine=engine, idx=qubit_id)], ),
            tags=[LogicalQubitIDTag(qubit_id)],
        )
        engine.send([deallocate_cmd])

    assert str(excinfo.value
               ) == "Cannot deallocate a qubit that is not already allocated!"
예제 #2
0
def test_cannot_deallocate_unknown_qubit():
    engine = MainEngine(
        Simulator(),
        engine_list=[BoundedQubitMapper(1)],
        verbose=True,
    )
    qureg = engine.allocate_qubit()
    with pytest.raises(RuntimeError) as excinfo:
        deallocate_cmd = Command(
            engine=engine,
            gate=DeallocateQubitGate(),
            qubits=([WeakQubitRef(engine=engine, idx=1)], ),
            tags=[LogicalQubitIDTag(1)],
        )
        engine.send([deallocate_cmd])
    assert str(excinfo.value
               ) == "Cannot deallocate a qubit that is not already allocated!"

    # but we can still deallocate an already allocated one
    engine.deallocate_qubit(qureg[0])
    del qureg
    del engine
예제 #3
0
def test_unitary_after_deallocation_or_measurement():
    eng = MainEngine(backend=UnitarySimulator(), engine_list=[])
    qubit = eng.allocate_qubit()
    X | qubit

    assert not eng.backend.history

    eng.flush()
    Measure | qubit

    # FlushGate and MeasureGate do not append to the history
    assert not eng.backend.history
    assert np.allclose(eng.backend.unitary, X.matrix)

    with pytest.warns(UserWarning):
        Y | qubit

    # YGate after FlushGate and MeasureGate does not append current unitary (identity) to the history
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.unitary,
                       Y.matrix)  # Reset of unitary when applying Y above
    assert np.allclose(eng.backend.history[0], X.matrix)

    # Still ok
    eng.flush()
    Measure | qubit

    # FlushGate and MeasureGate do not append to the history
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.unitary, Y.matrix)
    assert np.allclose(eng.backend.history[0], X.matrix)

    # Make sure that the new gate will trigger appending to the history and modify the current unitary
    with pytest.warns(UserWarning):
        Rx(1) | qubit
    assert len(eng.backend.history) == 2
    assert np.allclose(eng.backend.unitary, Rx(1).matrix)
    assert np.allclose(eng.backend.history[0], X.matrix)
    assert np.allclose(eng.backend.history[1], Y.matrix)

    # --------------------------------------------------------------------------

    eng = MainEngine(backend=UnitarySimulator(), engine_list=[])
    qureg = eng.allocate_qureg(2)
    All(X) | qureg

    XX_matrix = np.kron(X.matrix, X.matrix)
    assert not eng.backend.history
    assert np.allclose(eng.backend.unitary, XX_matrix)

    eng.deallocate_qubit(qureg[0])

    assert not eng.backend.history

    with pytest.warns(UserWarning):
        Y | qureg[1]

    # An internal call to flush() happens automatically since the X
    # gate occurs as the simulator is in an invalid state (after qubit
    # deallocation)
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.history[0], XX_matrix)
    assert np.allclose(eng.backend.unitary, Y.matrix)

    # Still ok
    eng.flush()
    Measure | qureg[1]

    # Nothing should have changed
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.history[0], XX_matrix)
    assert np.allclose(eng.backend.unitary, Y.matrix)