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_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_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_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_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_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_ibm5qubitmapper_valid_circuit2_ibmqx4(): connectivity = set([(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_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_run_infinite_loop_detection(): mapper = lm.LinearMapper(num_qubits=1, cyclic=False) 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) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(None, X, qubits=([qb0],), controls=[qb1]) qb2 = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb2],)) with pytest.raises(RuntimeError): mapper.receive([cmd0, cmd1, cmd2, cmd_flush])
def test_send_possible_commands_keep_remaining_gates(): 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) qb1 = WeakQubitRef(engine=None, idx=1) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],), controls=[], tags=[]) cmd1 = Command(engine=None, gate=Deallocate, qubits=([qb0],), controls=[], tags=[]) cmd2 = Command(engine=None, gate=Allocate, qubits=([qb1],), controls=[], tags=[]) mapper._stored_commands = [cmd0, cmd1, cmd2] mapper.current_mapping = {0: 0} mapper._send_possible_commands() assert mapper._stored_commands == [cmd2]
def test_send_possible_cmds_before_new_mapping(): mapper = two_d.GridMapper(num_rows=3, num_columns=1) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend def dont_call_mapping(): raise Exception mapper._return_new_mapping = dont_call_mapping mapper.current_mapping = {0: 1} qb0 = WeakQubitRef(engine=None, idx=0) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) qb2 = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb2],)) mapper.receive([cmd0, cmd_flush])
def test_ibm_sent_error_2(monkeypatch): backend = _ibm.IBMBackend(verbose=True) mapper = BasicMapperEngine() res = dict() for i in range(4): res[i] = i mapper.current_mapping = res eng = MainEngine(backend=backend, engine_list=[mapper]) qubit = eng.allocate_qubit() Rx(math.pi) | qubit with pytest.raises(Exception): S | qubit # no setup to decompose S gate, so not accepted by the backend dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_send_possible_commands_one_inactive_qubit(different_backend_ids): if different_backend_ids: map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 0, 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) qb1 = WeakQubitRef(engine=None, idx=1) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],), controls=[], tags=[]) cmd1 = Command(engine=None, gate=X, qubits=([qb0],), controls=[qb1]) mapper._stored_commands = [cmd0, cmd1] mapper.current_mapping = {0: 0} mapper._send_possible_commands() assert mapper._stored_commands == [cmd1]
def test_ibm_sent_error(monkeypatch): # patch send def mock_send(*args, **kwargs): raise TypeError monkeypatch.setattr(_ibm, "send", mock_send) backend = _ibm.IBMBackend(verbose=True) eng = MainEngine(backend=backend, engine_list=[IBMCNOTMapper()]) qubit = eng.allocate_qubit() X | qubit with pytest.raises(Exception): qubit[0].__del__() eng.flush() # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_aqt_sent_error(monkeypatch): # patch send def mock_send(*args, **kwargs): raise TypeError monkeypatch.setattr(_aqt, "send", mock_send) backend = _aqt.AQTBackend(verbose=True) eng = MainEngine(backend=backend) qubit = eng.allocate_qubit() Rx(0.5) | qubit with pytest.raises(Exception): qubit[0].__del__() eng.flush() # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_run_and_receive(): mapper = lm.LinearMapper(num_qubits=3, cyclic=False) 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) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],)) cmd3 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd4 = Command(None, X, qubits=([qb1],), controls=[qb2]) cmd5 = Command(engine=None, gate=Deallocate, qubits=([qb1],)) mapper.receive([cmd0, cmd1, cmd2, cmd3, cmd4, cmd5]) assert mapper._stored_commands == [cmd0, cmd1, cmd2, cmd3, cmd4, cmd5] qb3 = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb3],)) mapper.receive([cmd_flush]) assert mapper._stored_commands == [] assert len(backend.received_commands) == 7 assert mapper._currently_allocated_ids == {0, 2} assert mapper.current_mapping == {0: 2, 2: 0} or mapper.current_mapping == { 0: 0, 2: 2, } cmd6 = Command(None, X, qubits=([qb0],), controls=[qb2]) mapper.storage = 1 mapper.receive([cmd6]) assert mapper._currently_allocated_ids == {0, 2} assert mapper._stored_commands == [] assert len(mapper.current_mapping) == 2 assert 0 in mapper.current_mapping assert 2 in mapper.current_mapping assert len(backend.received_commands) == 11 for cmd in backend.received_commands: print(cmd) assert backend.received_commands[-1] == Command( None, X, qubits=([WeakQubitRef(engine=None, idx=mapper.current_mapping[qb0.id])],), controls=[WeakQubitRef(engine=None, idx=mapper.current_mapping[qb2.id])], ) assert mapper.num_mappings == 1
def test_send_possible_commands(different_backend_ids): if different_backend_ids: map_to_backend_ids = {0: 21, 1: 32, 2: 1, 3: 4, 4: 5, 5: 6, 6: 10, 7: 7} else: map_to_backend_ids = None mapper = two_d.GridMapper(num_rows=2, num_columns=4, mapped_ids_to_backend_ids=map_to_backend_ids) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = backend # mapping is identical except 5 <-> 0 if different_backend_ids: mapper.current_mapping = {0: 6, 1: 32, 2: 1, 3: 4, 4: 5, 5: 21, 6: 10, 7: 7} else: mapper.current_mapping = {5: 0, 1: 1, 2: 2, 3: 3, 4: 4, 0: 5, 6: 6, 7: 7} neighbours = [ (5, 1), (1, 2), (2, 3), (4, 0), (0, 6), (6, 7), (5, 4), (1, 0), (2, 6), (3, 7), ] for qb0_id, qb1_id in neighbours: qb0 = WeakQubitRef(engine=None, idx=qb0_id) qb1 = WeakQubitRef(engine=None, idx=qb1_id) cmd1 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd2 = Command(None, X, qubits=([qb1],), controls=[qb0]) mapper._stored_commands = [cmd1, cmd2] mapper._send_possible_commands() assert len(mapper._stored_commands) == 0 for qb0_id, qb1_id in itertools.permutations(range(8), 2): if (qb0_id, qb1_id) not in neighbours and (qb1_id, qb0_id) not in neighbours: qb0 = WeakQubitRef(engine=None, idx=qb0_id) qb1 = WeakQubitRef(engine=None, idx=qb1_id) cmd = Command(None, X, qubits=([qb0],), controls=[qb1]) mapper._stored_commands = [cmd] mapper._send_possible_commands() assert len(mapper._stored_commands) == 1
def test_run_infinite_loop_detection(): mapper = two_d.GridMapper(num_rows=2, num_columns=2) 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) qb4 = WeakQubitRef(engine=None, idx=4) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],)) cmd3 = Command(engine=None, gate=Allocate, qubits=([qb3],)) cmd4 = Command(engine=None, gate=Allocate, qubits=([qb4],)) cmd5 = Command(None, X, qubits=([qb0],), controls=[qb1]) qb2 = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb2],)) with pytest.raises(RuntimeError): mapper.receive([cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd_flush])
def test_ibm_sent_error(monkeypatch): # patch send def mock_send(*args, **kwargs): raise TypeError monkeypatch.setattr(_ibm, "send", mock_send) backend = _ibm.IBMBackend(verbose=True) mapper = BasicMapperEngine() res = dict() for i in range(4): res[i] = i mapper.current_mapping = res eng = MainEngine(backend=backend, engine_list=[mapper]) qubit = eng.allocate_qubit() Rx(math.pi) | qubit with pytest.raises(Exception): qubit[0].__del__() eng.flush() # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_correct_stats(): # Should test stats for twice same mapping but depends on heuristic mapper = two_d.GridMapper(num_rows=3, num_columns=1) 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) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],)) cmd3 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd4 = Command(None, X, qubits=([qb1],), controls=[qb2]) cmd5 = Command(None, X, qubits=([qb0],), controls=[qb2]) cmd6 = Command(None, X, qubits=([qb2],), controls=[qb1]) cmd7 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd8 = Command(None, X, qubits=([qb1],), controls=[qb2]) qb_flush = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],)) mapper.receive([cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd_flush]) assert mapper.num_mappings == 2
def test_check_that_local_optimizer_doesnt_merge(): mapper = two_d.GridMapper(num_rows=2, num_columns=2) optimizer = LocalOptimizer(10) backend = DummyEngine(save_commands=True) backend.is_last_engine = True mapper.next_engine = optimizer optimizer.next_engine = backend mapper.current_mapping = {0: 0} mapper.storage = 1 qb0 = WeakQubitRef(engine=None, idx=0) qb1 = WeakQubitRef(engine=None, idx=1) qb_flush = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],)) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(None, X, qubits=([qb0],)) cmd2 = Command(engine=None, gate=Deallocate, qubits=([qb0],)) mapper.receive([cmd0, cmd1, cmd2]) assert len(mapper._stored_commands) == 0 mapper.current_mapping = {1: 0} cmd3 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd4 = Command(None, X, qubits=([qb1],)) cmd5 = Command(engine=None, gate=Deallocate, qubits=([qb1],)) mapper.receive([cmd3, cmd4, cmd5, cmd_flush]) assert len(backend.received_commands) == 7
def test_logical_id_tags_allocate_and_deallocate(): mapper = two_d.GridMapper(num_rows=2, num_columns=2) 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) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd3 = Command(engine=None, gate=Deallocate, qubits=([qb0],)) cmd4 = Command(engine=None, gate=Deallocate, qubits=([qb1],)) mapper.current_mapping = {0: 0, 1: 3} qb_flush = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],)) mapper.receive([cmd0, cmd1, cmd2, cmd_flush]) assert backend.received_commands[0].gate == Allocate assert backend.received_commands[0].qubits[0][0].id == 0 assert backend.received_commands[0].tags == [LogicalQubitIDTag(0)] assert backend.received_commands[1].gate == Allocate assert backend.received_commands[1].qubits[0][0].id == 3 assert backend.received_commands[1].tags == [LogicalQubitIDTag(1)] for cmd in backend.received_commands[2:]: if cmd.gate == Allocate: assert cmd.tags == [] elif cmd.gate == Deallocate: assert cmd.tags == [] mapped_id_for_0 = mapper.current_mapping[0] mapped_id_for_1 = mapper.current_mapping[1] mapper.receive([cmd3, cmd4, cmd_flush]) assert backend.received_commands[-3].gate == Deallocate assert backend.received_commands[-3].qubits[0][0].id == mapped_id_for_0 assert backend.received_commands[-3].tags == [LogicalQubitIDTag(0)] assert backend.received_commands[-2].gate == Deallocate assert backend.received_commands[-2].qubits[0][0].id == mapped_id_for_1 assert backend.received_commands[-2].tags == [LogicalQubitIDTag(1)]
def test_ionq_send_nonetype_response_error(monkeypatch, mapper_factory): """Test that no return value from "send" will raise a runtime error.""" # patch send mock_send = mock.MagicMock(return_value=None) 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(RuntimeError) as excinfo: eng.flush() # verbose=True on the engine re-raises errors instead of compacting them. assert str(excinfo.value) == "Failed to submit job to the server!" # atexit sends another FlushGate, therefore we remove the backend: dummy = DummyEngine() dummy.is_last_engine = True eng.next_engine = dummy
def test_run_and_receive(num_optimization_steps, different_backend_ids): if different_backend_ids: map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 0} else: map_to_backend_ids = None def choose_last_permutation(swaps): choose_last_permutation.counter -= 1 return choose_last_permutation.counter choose_last_permutation.counter = 100 mapper = two_d.GridMapper( num_rows=2, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids, optimization_function=choose_last_permutation, num_optimization_steps=num_optimization_steps, ) 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) cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],)) cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],)) cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],)) cmd3 = Command(engine=None, gate=Allocate, qubits=([qb3],)) cmd4 = Command(None, X, qubits=([qb0],), controls=[qb1]) cmd5 = Command(None, X, qubits=([qb1],), controls=[qb3]) cmd6 = Command(None, X, qubits=([qb3],), controls=[qb2]) cmd7 = Command(None, X, qubits=([qb0],), controls=[qb2]) cmd8 = Command(engine=None, gate=Deallocate, qubits=([qb1],)) all_cmd = [cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8] mapper.receive(all_cmd) assert mapper._stored_commands == all_cmd qb4 = WeakQubitRef(engine=None, idx=-1) cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb4],)) mapper.receive([cmd_flush]) assert mapper._stored_commands == [] assert len(backend.received_commands) == 10 assert mapper._currently_allocated_ids == {0, 2, 3} if different_backend_ids: assert ( mapper.current_mapping == {0: 21, 2: 3, 3: 0} or mapper.current_mapping == {0: 32, 2: 0, 3: 21} or mapper.current_mapping == {0: 3, 2: 21, 3: 32} or mapper.current_mapping == {0: 0, 2: 32, 3: 3} ) else: assert ( mapper.current_mapping == {0: 0, 2: 2, 3: 3} or mapper.current_mapping == {0: 1, 2: 3, 3: 0} or mapper.current_mapping == {0: 2, 2: 0, 3: 1} or mapper.current_mapping == {0: 3, 2: 1, 3: 2} ) cmd9 = Command(None, X, qubits=([qb0],), controls=[qb3]) mapper.storage = 1 mapper.receive([cmd9]) assert mapper._currently_allocated_ids == {0, 2, 3} assert mapper._stored_commands == [] assert len(mapper.current_mapping) == 3 assert 0 in mapper.current_mapping assert 2 in mapper.current_mapping assert 3 in mapper.current_mapping assert mapper.num_mappings == 1