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