def test_compute_uncompute_no_additional_qubits(): # No ancilla qubit created in compute section backend0 = DummyEngine(save_commands=True) compare_engine0 = CompareEngine() eng0 = MainEngine(backend=backend0, engine_list=[compare_engine0]) qubit = eng0.allocate_qubit() with _compute.Compute(eng0): Rx(0.5) | qubit H | qubit _compute.Uncompute(eng0) eng0.flush(deallocate_qubits=True) assert backend0.received_commands[0].gate == Allocate assert backend0.received_commands[1].gate == Rx(0.5) assert backend0.received_commands[2].gate == H assert backend0.received_commands[3].gate == Rx(-0.5) assert backend0.received_commands[4].gate == Deallocate assert backend0.received_commands[0].tags == [] assert backend0.received_commands[1].tags == [_compute.ComputeTag()] assert backend0.received_commands[2].tags == [] assert backend0.received_commands[3].tags == [_compute.UncomputeTag()] assert backend0.received_commands[4].tags == [] # Same using CustomUncompute and test using CompareEngine backend1 = DummyEngine(save_commands=True) compare_engine1 = CompareEngine() eng1 = MainEngine(backend=backend1, engine_list=[compare_engine1]) qubit = eng1.allocate_qubit() with _compute.Compute(eng1): Rx(0.5) | qubit H | qubit with _compute.CustomUncompute(eng1): Rx(-0.5) | qubit eng1.flush(deallocate_qubits=True) assert compare_engine0 == compare_engine1
def test_compute_uncompute_with_statement(): # Allocating and deallocating qubit within Compute backend = DummyEngine(save_commands=True) compare_engine0 = CompareEngine() # Allow dirty qubits dummy_cengine = DummyEngine() def allow_dirty_qubits(self, meta_tag): return meta_tag == DirtyQubitTag dummy_cengine.is_meta_tag_handler = types.MethodType( allow_dirty_qubits, dummy_cengine) eng = MainEngine(backend=backend, engine_list=[compare_engine0, dummy_cengine]) qubit = eng.allocate_qubit() with _compute.Compute(eng): Rx(0.9) | qubit ancilla = eng.allocate_qubit(dirty=True) # ancilla2 will be deallocated in Uncompute section: ancilla2 = eng.allocate_qubit() # Test that ancilla is registered in MainEngine.active_qubits: assert ancilla[0] in eng.active_qubits H | qubit Rx(0.5) | ancilla CNOT | (ancilla, qubit) Rx(0.7) | qubit Rx(-0.5) | ancilla ancilla[0].__del__() H | qubit _compute.Uncompute(eng) eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 22 # Test each Command has correct gate assert backend.received_commands[0].gate == Allocate assert backend.received_commands[1].gate == Rx(0.9) assert backend.received_commands[2].gate == Allocate assert backend.received_commands[3].gate == Allocate assert backend.received_commands[4].gate == H assert backend.received_commands[5].gate == Rx(0.5) assert backend.received_commands[6].gate == NOT assert backend.received_commands[7].gate == Rx(0.7) assert backend.received_commands[8].gate == Rx(-0.5) assert backend.received_commands[9].gate == Deallocate assert backend.received_commands[10].gate == H assert backend.received_commands[11].gate == Allocate assert backend.received_commands[12].gate == Rx(0.5) assert backend.received_commands[13].gate == Rx(-0.7) assert backend.received_commands[14].gate == NOT assert backend.received_commands[15].gate == Rx(-0.5) assert backend.received_commands[16].gate == H assert backend.received_commands[17].gate == Deallocate assert backend.received_commands[18].gate == Deallocate assert backend.received_commands[19].gate == Rx(-0.9) assert backend.received_commands[20].gate == Deallocate assert backend.received_commands[21].gate == FlushGate() # Test that each command has correct tags assert backend.received_commands[0].tags == [] assert backend.received_commands[1].tags == [_compute.ComputeTag()] assert backend.received_commands[2].tags == [ DirtyQubitTag(), _compute.ComputeTag() ] for cmd in backend.received_commands[3:9]: assert cmd.tags == [_compute.ComputeTag()] assert backend.received_commands[9].tags == [ DirtyQubitTag(), _compute.ComputeTag() ] assert backend.received_commands[10].tags == [] assert backend.received_commands[11].tags == [ DirtyQubitTag(), _compute.UncomputeTag() ] for cmd in backend.received_commands[12:18]: assert cmd.tags == [_compute.UncomputeTag()] assert backend.received_commands[18].tags == [ DirtyQubitTag(), _compute.UncomputeTag() ] assert backend.received_commands[19].tags == [_compute.UncomputeTag()] assert backend.received_commands[20].tags == [] assert backend.received_commands[21].tags == [] # Test that each command has correct qubits # Note that ancilla qubit in compute should be # different from ancilla qubit in uncompute section qubit_id = backend.received_commands[0].qubits[0][0].id ancilla_compt_id = backend.received_commands[2].qubits[0][0].id ancilla_uncompt_id = backend.received_commands[11].qubits[0][0].id ancilla2_id = backend.received_commands[3].qubits[0][0].id assert backend.received_commands[1].qubits[0][0].id == qubit_id assert backend.received_commands[4].qubits[0][0].id == qubit_id assert backend.received_commands[5].qubits[0][0].id == ancilla_compt_id assert backend.received_commands[6].qubits[0][0].id == qubit_id assert ( backend.received_commands[6].control_qubits[0].id == ancilla_compt_id) assert backend.received_commands[7].qubits[0][0].id == qubit_id assert backend.received_commands[8].qubits[0][0].id == ancilla_compt_id assert backend.received_commands[9].qubits[0][0].id == ancilla_compt_id assert backend.received_commands[10].qubits[0][0].id == qubit_id assert backend.received_commands[12].qubits[0][0].id == ancilla_uncompt_id assert backend.received_commands[13].qubits[0][0].id == qubit_id assert backend.received_commands[14].qubits[0][0].id == qubit_id assert (backend.received_commands[14].control_qubits[0].id == ancilla_uncompt_id) assert backend.received_commands[15].qubits[0][0].id == ancilla_uncompt_id assert backend.received_commands[16].qubits[0][0].id == qubit_id assert backend.received_commands[17].qubits[0][0].id == ancilla2_id assert backend.received_commands[18].qubits[0][0].id == ancilla_uncompt_id assert backend.received_commands[19].qubits[0][0].id == qubit_id assert backend.received_commands[20].qubits[0][0].id == qubit_id # Test that ancilla qubits should have seperate ids assert ancilla_uncompt_id != ancilla_compt_id # Do the same thing with CustomUncompute and compare using the # CompareEngine: backend1 = DummyEngine(save_commands=True) compare_engine1 = CompareEngine() # Allow dirty qubits dummy_cengine1 = DummyEngine() def allow_dirty_qubits(self, meta_tag): return meta_tag == DirtyQubitTag dummy_cengine1.is_meta_tag_handler = types.MethodType( allow_dirty_qubits, dummy_cengine1) eng1 = MainEngine(backend=backend1, engine_list=[compare_engine1, dummy_cengine1]) qubit = eng1.allocate_qubit() with _compute.Compute(eng1): Rx(0.9) | qubit ancilla = eng1.allocate_qubit(dirty=True) # ancilla2 will be deallocated in Uncompute section: ancilla2 = eng1.allocate_qubit() # Test that ancilla is registered in MainEngine.active_qubits: assert ancilla[0] in eng1.active_qubits H | qubit Rx(0.5) | ancilla CNOT | (ancilla, qubit) Rx(0.7) | qubit Rx(-0.5) | ancilla ancilla[0].__del__() H | qubit with _compute.CustomUncompute(eng1): ancilla = eng1.allocate_qubit(dirty=True) Rx(0.5) | ancilla Rx(-0.7) | qubit CNOT | (ancilla, qubit) Rx(-0.5) | ancilla H | qubit assert ancilla[0] in eng1.active_qubits ancilla2[0].__del__() ancilla[0].__del__() Rx(-0.9) | qubit eng1.flush(deallocate_qubits=True) assert compare_engine0 == compare_engine1