def test_send_possible_commands_deallocate(different_backend_ids): if different_backend_ids: map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 4, 4: 5, 5: 6} else: map_to_backend_ids = None mapper = two_d.GridMapper(num_rows=3, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend qb0 = WeakQubitRef(engine=None, idx=0) cmd0 = Command(engine=None, gate=Deallocate, qubits=([qb0],), controls=[], tags=[]) mapper._stored_commands = [cmd0] mapper.current_mapping = {} mapper._currently_allocated_ids = {10} # not yet allocated: mapper._send_possible_commands() assert len(backend.received_commands) == 0 assert mapper._stored_commands == [cmd0] # allocated: mapper.current_mapping = {0: 3} mapper._currently_allocated_ids.add(0) mapper._send_possible_commands() assert len(backend.received_commands) == 1 assert len(mapper._stored_commands) == 0 assert mapper.current_mapping == {} assert mapper._currently_allocated_ids == {10}
def test_decomposition(angle): for basis_state in ([1, 0], [0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[ry2rz]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(ry_decomp_gates), test_dummy_eng, ], ) correct_qb = correct_eng.allocate_qubit() Ry(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Ry(angle) | test_qb test_eng.flush() assert correct_dummy_eng.received_commands[1].gate == Ry(angle) assert test_dummy_eng.received_commands[1].gate != Ry(angle) for fstate in ['0', '1']: test = test_eng.backend.get_amplitude(fstate, test_qb) correct = correct_eng.backend.get_amplitude(fstate, correct_qb) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def test_ionq_no_midcircuit_measurement(monkeypatch, mapper_factory): """Test that attempts to measure mid-circuit raise exceptions.""" def mock_send(*args, **kwargs): return { 'nq': 1, 'shots': 10, 'output_probs': { '0': 0.4, '1': 0.6 }, } monkeypatch.setattr(_ionq_http_client, "send", mock_send) # Create a backend to use with an engine. backend = _ionq.IonQBackend(verbose=True, num_runs=10) eng = MainEngine( backend=backend, engine_list=[mapper_factory()], verbose=True, ) qubit = eng.allocate_qubit() X | qubit Measure | qubit with pytest.raises(MidCircuitMeasurementError): X | qubit # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.active_qubits = [] eng.next_engine = dummy
def test_send_possible_commands_allocate(different_backend_ids): if different_backend_ids: map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 4, 4: 5, 5: 6} else: map_to_backend_ids = None mapper = two_d.GridMapper(num_rows=3, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend qb0 = WeakQubitRef(engine=None, idx=0) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],), controls=[], tags=[]) mapper._stored_commands = [cmd0] mapper._currently_allocated_ids = {10} # not in mapping: mapper.current_mapping = {} assert len(backend.received_commands) == 0 mapper._send_possible_commands() assert len(backend.received_commands) == 0 assert mapper._stored_commands == [cmd0] # in mapping: mapper.current_mapping = {0: 3} mapper._send_possible_commands() assert len(mapper._stored_commands) == 0 # Only self._run() sends Allocate gates mapped0 = WeakQubitRef(engine=None, idx=3) received_cmd = Command( engine=mapper, gate=Allocate, qubits=([mapped0],), controls=[], tags=[LogicalQubitIDTag(0)], ) assert backend.received_commands[0] == received_cmd assert mapper._currently_allocated_ids == {10, 0}
def test_swapandcnotflipper_optimize_swaps(): backend = DummyEngine(save_commands=True) connectivity = set([(1, 0)]) flipper = _swapandcnotflipper.SwapAndCNOTFlipper(connectivity) eng = MainEngine(backend=backend, engine_list=[flipper]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() Swap | (qb0, qb1) hgates = 0 for cmd in backend.received_commands: if cmd.gate == H: hgates += 1 if cmd.gate == X: assert cmd.qubits[0][0].id == 0 assert cmd.control_qubits[0].id == 1 assert hgates == 4 backend = DummyEngine(save_commands=True) connectivity = set([(0, 1)]) flipper = _swapandcnotflipper.SwapAndCNOTFlipper(connectivity) eng = MainEngine(backend=backend, engine_list=[flipper]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() Swap | (qb0, qb1) hgates = 0 for cmd in backend.received_commands: if cmd.gate == H: hgates += 1 if cmd.gate == X: assert cmd.qubits[0][0].id == 1 assert cmd.control_qubits[0].id == 0 assert hgates == 4
def test_ionq_sent_error(monkeypatch, mapper_factory): """Test that errors on "send" will raise back out.""" # patch send type_error = TypeError() mock_send = mock.MagicMock(side_effect=type_error) monkeypatch.setattr(_ionq_http_client, "send", mock_send) backend = _ionq.IonQBackend() eng = MainEngine( backend=backend, engine_list=[mapper_factory()], verbose=True, ) qubit = eng.allocate_qubit() Rx(0.5) | qubit with pytest.raises(Exception) as excinfo: qubit[0].__del__() eng.flush() # verbose=True on the engine re-raises errors instead of compacting them. assert type_error is excinfo.value # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_send_possible_commands_cyclic(): mapper = lm.LinearMapper(num_qubits=4, cyclic=True) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend qb0 = WeakQubitRef(engine=None, idx=0) qb1 = WeakQubitRef(engine=None, idx=1) qb2 = WeakQubitRef(engine=None, idx=2) qb3 = WeakQubitRef(engine=None, idx=3) mapper._currently_allocated_ids = {0, 1, 2, 3} cmd0 = Command(None, CNOT, qubits=([qb0],), controls=[qb1]) cmd1 = Command(None, CNOT, qubits=([qb1],), controls=[qb2]) cmd2 = Command(None, CNOT, qubits=([qb1],), controls=[qb3]) cmd3 = Command(None, X, qubits=([qb0],), controls=[]) mapper._stored_commands = [cmd0, cmd1, cmd2, cmd3] # Following chain 0 <-> 2 <-> 3 <-> 1 mapper.current_mapping = {0: 0, 2: 1, 3: 2, 1: 3} mapper._send_possible_commands() assert len(backend.received_commands) == 2 assert backend.received_commands[0] == Command(None, CNOT, qubits=([qb0],), controls=[qb3]) assert backend.received_commands[1] == Command(None, X, qubits=([qb0],)) # Following chain 0 <-> 2 <-> 1 <-> 3 mapper.current_mapping = {0: 0, 2: 1, 3: 3, 1: 2} mapper._send_possible_commands() assert len(backend.received_commands) == 4 assert len(mapper._stored_commands) == 0
def test_swapandcnotflipper_is_available(): flipper = _swapandcnotflipper.SwapAndCNOTFlipper(set()) dummy = DummyEngine() dummy.is_available = lambda x: False flipper.next_engine = dummy eng = MainEngine(DummyEngine(save_commands=True), []) qubit1, qubit2 = eng.allocate_qureg(2) Swap | (qubit1, qubit2) swap_count = 0 for cmd in eng.backend.received_commands: if cmd.gate == Swap: swap_count += 1 assert flipper.is_available(cmd) assert swap_count == 1 eng = MainEngine(DummyEngine(save_commands=True), []) qubit1, qubit2, qubit3 = eng.allocate_qureg(3) with Control(eng, qubit3): Swap | (qubit1, qubit2) swap_count = 0 for cmd in eng.backend.received_commands: if cmd.gate == Swap: swap_count += 1 assert not flipper.is_available(cmd) assert swap_count == 1
def test_send_possible_commands_deallocate(): mapper = lm.LinearMapper(num_qubits=4, cyclic=False) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend qb0 = WeakQubitRef(engine=None, idx=0) cmd0 = Command(engine=None, gate=Deallocate, qubits=([qb0],), controls=[], tags=[]) mapper._stored_commands = [cmd0] mapper.current_mapping = {} mapper._currently_allocated_ids = {10} # not yet allocated: mapper._send_possible_commands() assert len(backend.received_commands) == 0 assert mapper._stored_commands == [cmd0] # allocated: mapper.current_mapping = {0: 3} mapper._currently_allocated_ids.add(0) mapper._send_possible_commands() assert len(backend.received_commands) == 1 assert backend.received_commands[0].gate == Deallocate assert backend.received_commands[0].qubits[0][0].id == 3 assert backend.received_commands[0].tags == [LogicalQubitIDTag(0)] assert len(mapper._stored_commands) == 0 assert mapper.current_mapping == {} assert mapper._currently_allocated_ids == {10}
def test_insert_then_drop(): d1 = DummyEngine() d2 = DummyEngine() d3 = DummyEngine() eng = MainEngine(backend=d3, engine_list=[d1]) assert d1.next_engine is d3 assert d2.next_engine is None assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is None assert d3.main_engine is eng assert eng.n_engines == 2 _util.insert_engine(d1, d2) assert d1.next_engine is d2 assert d2.next_engine is d3 assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is eng assert d3.main_engine is eng assert eng.n_engines == 3 _util.drop_engine_after(d1) assert d1.next_engine is d3 assert d2.next_engine is None assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is None assert d3.main_engine is eng assert eng.n_engines == 2
def test_ibm5qubitmapper_valid_circuit2_ibmqx4(): connectivity = {(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)} backend = DummyEngine(save_commands=True) class FakeIBMBackend(IBMBackend): pass fake = FakeIBMBackend(device='ibmqx4', use_hardware=True) fake.receive = backend.receive fake.is_available = backend.is_available backend.is_last_engine = True eng = MainEngine( backend=fake, engine_list=[ _ibm5qubitmapper.IBM5QubitMapper(connections=connectivity) ], ) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() qb3 = eng.allocate_qubit() qb4 = eng.allocate_qubit() CNOT | (qb3, qb1) CNOT | (qb3, qb2) CNOT | (qb3, qb0) CNOT | (qb3, qb4) CNOT | (qb1, qb2) CNOT | (qb0, qb4) CNOT | (qb2, qb1) eng.flush()
def test_qubit_not_copyable(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit = _qubit.Qubit(eng, 10) qubit_copy = copy(qubit) assert id(qubit) == id(qubit_copy) qubit_deepcopy = deepcopy(qubit) assert id(qubit) == id(qubit_deepcopy)
def test_qureg_engine(): eng1 = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) eng2 = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qureg = _qubit.Qureg([_qubit.Qubit(eng1, 0), _qubit.Qubit(eng1, 1)]) assert eng1 == qureg.engine qureg.engine = eng2 assert qureg[0].engine == eng2 and qureg[1].engine == eng2
def test_qureg(qubit_ids, expected): eng = MainEngine(backend = DummyEngine(), engine_list = [DummyEngine()]) qureg = _qubit.Qureg() for qubit_id in qubit_ids: qubit = _qubit.Qubit(eng, qubit_id) qureg.append(qubit) assert str(qureg) == expected
def test_basic_gate_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) qubit3 = Qubit(main_engine, 3) qureg = Qureg([qubit2, qubit3]) basic_gate = _basics.BasicGate() command1 = basic_gate.generate_command(qubit0) basic_gate | qubit0 command2 = basic_gate.generate_command([qubit0, qubit1]) basic_gate | [qubit0, qubit1] command3 = basic_gate.generate_command(qureg) basic_gate | qureg command4 = basic_gate.generate_command((qubit0, )) basic_gate | (qubit0, ) command5 = basic_gate.generate_command((qureg, qubit0)) basic_gate | (qureg, qubit0) received_commands = [] # Remove Deallocate gates for cmd in saving_backend.received_commands: if not isinstance(cmd.gate, _basics.FastForwardingGate): received_commands.append(cmd) assert received_commands == ([ command1, command2, command3, command4, command5 ])
def test_dagger_with_dirty_qubits(): backend = DummyEngine(save_commands=True) def allow_dirty_qubits(self, meta_tag): return meta_tag == DirtyQubitTag backend.is_meta_tag_handler = types.MethodType(allow_dirty_qubits, backend) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() with _dagger.Dagger(eng): ancilla = eng.allocate_qubit(dirty=True) Rx(0.6) | ancilla CNOT | (ancilla, qubit) H | qubit Rx(-0.6) | ancilla del ancilla[0] eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 9 assert backend.received_commands[0].gate == Allocate assert backend.received_commands[1].gate == Allocate assert backend.received_commands[2].gate == Rx(0.6) assert backend.received_commands[3].gate == H assert backend.received_commands[4].gate == X assert backend.received_commands[5].gate == Rx(-0.6) assert backend.received_commands[6].gate == Deallocate assert backend.received_commands[7].gate == Deallocate assert backend.received_commands[1].tags == [DirtyQubitTag()] assert backend.received_commands[6].tags == [DirtyQubitTag()]
def test_forwarder_engine(): backend = DummyEngine(save_commands=True) engine0 = DummyEngine() main_engine = MainEngine(backend=backend, engine_list=[engine0]) def cmd_mod_fun(cmd): cmd.tags = "NewTag" return cmd forwarder_eng = _basics.ForwarderEngine(backend, cmd_mod_fun) engine0.next_engine = forwarder_eng forwarder_eng2 = _basics.ForwarderEngine(engine0) main_engine.next_engine = forwarder_eng2 qubit = main_engine.allocate_qubit() H | qubit # Test if H gate was sent through forwarder_eng and tag was added received_commands = [] # Remove Allocate and Deallocate gates for cmd in backend.received_commands: if not (isinstance(cmd.gate, FastForwardingGate) or isinstance(cmd.gate, ClassicalInstructionGate)): received_commands.append(cmd) for cmd in received_commands: print(cmd) assert len(received_commands) == 1 assert received_commands[0].gate == H assert received_commands[0].tags == "NewTag"
def test_control(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qureg = eng.allocate_qureg(2) with _control.Control(eng, qureg): qubit = eng.allocate_qubit() with Compute(eng): Rx(0.5) | qubit H | qubit Uncompute(eng) with _control.Control(eng, qureg[0]): H | qubit eng.flush() assert len(backend.received_commands) == 8 assert len(backend.received_commands[0].control_qubits) == 0 assert len(backend.received_commands[1].control_qubits) == 0 assert len(backend.received_commands[2].control_qubits) == 0 assert len(backend.received_commands[3].control_qubits) == 0 assert len(backend.received_commands[4].control_qubits) == 2 assert len(backend.received_commands[5].control_qubits) == 0 assert len(backend.received_commands[6].control_qubits) == 1 assert len(backend.received_commands[7].control_qubits) == 0 assert backend.received_commands[4].control_qubits[0].id == qureg[0].id assert backend.received_commands[4].control_qubits[1].id == qureg[1].id assert backend.received_commands[6].control_qubits[0].id == qureg[0].id
def test_controlled_gate_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) gate = Rx(0.6) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) qubit3 = Qubit(main_engine, 3) expected_cmd = Command(main_engine, gate, ([qubit3], ), controls=[qubit0, qubit1, qubit2]) received_commands = [] # Option 1: _metagates.ControlledGate(gate, 3) | ([qubit1], [qubit0], [qubit2 ], [qubit3]) # Option 2: _metagates.ControlledGate(gate, 3) | (qubit1, qubit0, qubit2, qubit3) # Option 3: _metagates.ControlledGate(gate, 3) | ([qubit1, qubit0], qubit2, qubit3) # Option 4: _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2], qubit3) # Wrong option 5: with pytest.raises(_metagates.ControlQubitError): _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2, qubit3]) # Remove Allocate and Deallocate gates for cmd in saving_backend.received_commands: if not (isinstance(cmd.gate, FastForwardingGate) or isinstance(cmd.gate, ClassicalInstructionGate)): received_commands.append(cmd) assert len(received_commands) == 4 for cmd in received_commands: assert cmd == expected_cmd
def test_ibm_backend_is_available_control_not(num_ctrl_qubits, is_available): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit1 = eng.allocate_qubit() qureg = eng.allocate_qureg(num_ctrl_qubits) ibm_backend = _ibm.IBMBackend() cmd = Command(eng, NOT, (qubit1, ), controls=qureg) assert ibm_backend.is_available(cmd) == is_available
def test_tensor_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) gate = Rx(0.6) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) # Option 1: _metagates.Tensor(gate) | ([qubit0, qubit1, qubit2], ) # Option 2: _metagates.Tensor(gate) | [qubit0, qubit1, qubit2] received_commands = [] # Remove Allocate and Deallocate gates for cmd in saving_backend.received_commands: if not (isinstance(cmd.gate, FastForwardingGate) or isinstance(cmd.gate, ClassicalInstructionGate)): received_commands.append(cmd) # Check results assert len(received_commands) == 6 qubit_ids = [] for cmd in received_commands: assert len(cmd.qubits) == 1 assert cmd.gate == gate qubit_ids.append(cmd.qubits[0][0].id) assert sorted(qubit_ids) == [0, 0, 1, 1, 2, 2]
def test_qubit_management_error(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) with _compute.Compute(eng): ancilla = eng.allocate_qubit() # noqa: F841 eng.active_qubits = weakref.WeakSet() with pytest.raises(_compute.QubitManagementError): _compute.Uncompute(eng)
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_loop_unrolling_with_ancillas(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() qubit_id = deepcopy(qubit[0].id) with _loop.Loop(eng, 3): ancilla = eng.allocate_qubit() H | ancilla CNOT | (ancilla, qubit) del ancilla eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 15 assert backend.received_commands[0].gate == Allocate for ii in range(3): assert backend.received_commands[ii * 4 + 1].gate == Allocate assert backend.received_commands[ii * 4 + 2].gate == H assert backend.received_commands[ii * 4 + 3].gate == X assert backend.received_commands[ii * 4 + 4].gate == Deallocate # Check qubit ids assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 2].qubits[0][0].id) assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 3].control_qubits[0].id) assert (backend.received_commands[ii * 4 + 3].qubits[0][0].id == qubit_id) assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 4].qubits[0][0].id) assert backend.received_commands[13].gate == Deallocate assert backend.received_commands[14].gate == FlushGate() assert (backend.received_commands[1].qubits[0][0].id != backend.received_commands[5].qubits[0][0].id) assert (backend.received_commands[1].qubits[0][0].id != backend.received_commands[9].qubits[0][0].id) assert (backend.received_commands[5].qubits[0][0].id != backend.received_commands[9].qubits[0][0].id)
def test_loop_unrolling(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() with _loop.Loop(eng, 3): H | qubit eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 6
def test_outside_qubit_deallocated_in_compute(): # Test that there is an error if a qubit is deallocated which has # not been allocated within the with Compute(eng) context eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() with pytest.raises(_compute.QubitManagementError): with _compute.Compute(eng): qubit[0].__del__()
def test_decomposition(): for basis_state_index in range(0, 16): basis_state = [0] * 16 basis_state[basis_state_index] = 1.0 correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[cnu2toffoliandcu]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(_decomp_gates), test_dummy_eng, ], ) test_sim = test_eng.backend correct_sim = correct_eng.backend correct_qb = correct_eng.allocate_qubit() correct_ctrl_qureg = correct_eng.allocate_qureg(3) correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qureg = test_eng.allocate_qureg(3) test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qureg) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qureg) with Control(test_eng, test_ctrl_qureg[:2]): Rx(0.4) | test_qb with Control(test_eng, test_ctrl_qureg): Ry(0.6) | test_qb with Control(test_eng, test_ctrl_qureg): X | test_qb with Control(correct_eng, correct_ctrl_qureg[:2]): Rx(0.4) | correct_qb with Control(correct_eng, correct_ctrl_qureg): Ry(0.6) | correct_qb with Control(correct_eng, correct_ctrl_qureg): X | correct_qb test_eng.flush() correct_eng.flush() assert len(correct_dummy_eng.received_commands) == 9 assert len(test_dummy_eng.received_commands) == 25 for fstate in range(16): binary_state = format(fstate, '04b') test = test_sim.get_amplitude(binary_state, test_qb + test_ctrl_qureg) correct = correct_sim.get_amplitude(binary_state, correct_qb + correct_ctrl_qureg) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qureg All(Measure) | correct_qb + correct_ctrl_qureg test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def test_basic_mapper_engine_send_cmd_with_mapped_ids(): mapper = _basicmapper.BasicMapperEngine() mapper.current_mapping = {0: 3, 1: 2, 2: 1, 3: 0} backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend # generate a few commands qb0 = WeakQubitRef(engine=None, idx=0) qb1 = WeakQubitRef(engine=None, idx=1) qb2 = WeakQubitRef(engine=None, idx=2) qb3 = WeakQubitRef(engine=None, idx=3) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0], ), controls=[], tags=[]) cmd1 = Command(engine=None, gate=Deallocate, qubits=([qb1], ), controls=[], tags=[]) cmd2 = Command(engine=None, gate=Measure, qubits=([qb2], ), controls=[], tags=["SomeTag"]) cmd3 = Command( engine=None, gate=BasicGate(), qubits=([qb0, qb1], [qb2]), controls=[qb3], tags=[], ) cmd4 = Command(None, FlushGate(), ([WeakQubitRef(None, -1)], )) mapper._send_cmd_with_mapped_ids(cmd0) mapper._send_cmd_with_mapped_ids(cmd1) mapper._send_cmd_with_mapped_ids(cmd2) mapper._send_cmd_with_mapped_ids(cmd3) mapper._send_cmd_with_mapped_ids(cmd4) rcmd0 = backend.received_commands[0] rcmd1 = backend.received_commands[1] rcmd2 = backend.received_commands[2] rcmd3 = backend.received_commands[3] rcmd4 = backend.received_commands[4] assert rcmd0.gate == Allocate assert rcmd0.qubits == ([qb3], ) assert rcmd1.gate == Deallocate assert rcmd1.qubits == ([qb2], ) assert rcmd2.gate == Measure assert rcmd2.qubits == ([qb1], ) assert rcmd2.tags == ["SomeTag", LogicalQubitIDTag(2)] assert rcmd3.gate == BasicGate() assert rcmd3.qubits == ([qb3, qb2], [qb1]) assert rcmd3.control_qubits == [qb0] assert len(rcmd4.qubits) == 1 assert len(rcmd4.qubits[0]) == 1 assert rcmd4.qubits[0][0].id == -1
def test_deallocation_using_custom_uncompute3(): # Test not allowed version: eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) with _compute.Compute(eng): pass with pytest.raises(_compute.QubitManagementError): with _compute.CustomUncompute(eng): ancilla = eng.allocate_qubit() H | ancilla
def test_empty_loop(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() assert len(backend.received_commands) == 1 with _loop.Loop(eng, 0): H | qubit assert len(backend.received_commands) == 1