def get_engine_list(): rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions]) return [ TagRemover(), LocalOptimizer(10), AutoReplacer(rule_set), TagRemover(), IBM5QubitMapper(), SwapAndCNOTFlipper(ibmqx4_connections), LocalOptimizer(10) ]
def test_ibm5qubitmapper_toomanyqubits(): backend = DummyEngine(save_commands=True) connectivity = set([(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)]) eng = MainEngine(backend=backend, engine_list=[_ibm5qubitmapper.IBM5QubitMapper(), SwapAndCNOTFlipper(connectivity)]) qubits = eng.allocate_qureg(6) All(H) | qubits CNOT | (qubits[0], qubits[1]) with pytest.raises(RuntimeError): eng.flush()
def test_ibm_backend_functional_test(monkeypatch): correct_info = ('{"qasms": [{"qasm": "\\ninclude \\"qelib1.inc\\";' '\\nqreg q[3];\\ncreg c[3];\\nh q[2];\\ncx q[2], q[0];' '\\ncx q[2], q[1];\\ntdg q[2];\\nsdg q[2];' '\\nbarrier q[2], q[0], q[1];' '\\nu3(0.2, -pi/2, pi/2) q[2];\\nmeasure q[2] -> ' 'c[2];\\nmeasure q[0] -> c[0];\\nmeasure q[1] -> c[1];"}]' ', "shots": 1024, "maxCredits": 5, "backend": {"name": ' '"simulator"}}') def mock_send(*args, **kwargs): assert json.loads(args[0]) == json.loads(correct_info) return {'date': '2017-01-19T14:28:47.622Z', 'data': {'time': 14.429004907608032, 'counts': {'00111': 396, '00101': 27, '00000': 601}, 'qasm': ('...')}} monkeypatch.setattr(_ibm, "send", mock_send) backend = _ibm.IBMBackend(verbose=True) # no circuit has been executed -> raises exception with pytest.raises(RuntimeError): backend.get_probabilities([]) rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions]) engine_list = [TagRemover(), LocalOptimizer(10), AutoReplacer(rule_set), TagRemover(), IBM5QubitMapper(), SwapAndCNOTFlipper(ibmqx4_connections), LocalOptimizer(10)] eng = MainEngine(backend=backend, engine_list=engine_list) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(3) # entangle the qureg Entangle | qureg Tdag | qureg[0] Sdag | qureg[0] Barrier | qureg Rx(0.2) | qureg[0] del unused_qubit # measure; should be all-0 or all-1 All(Measure) | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[2], qureg[1]]) assert prob_dict['111'] == pytest.approx(0.38671875) assert prob_dict['101'] == pytest.approx(0.0263671875) with pytest.raises(RuntimeError): eng.backend.get_probabilities(eng.allocate_qubit())
def get_engine_list(): rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) return [ TagRemover(), LocalOptimizer(5), AutoReplacer(rule_set), InstructionFilter(high_level_gates), TagRemover(), LocalOptimizer(5), AutoReplacer(rule_set), TagRemover(), GridMapper(2, 8, grid_to_physical), LocalOptimizer(5), SwapAndCNOTFlipper(ibmqx5_connections), LocalOptimizer(5) ]
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=[IBM5QubitMapper(), SwapAndCNOTFlipper(set())]) 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_ibm5qubitmapper_optimizeifpossible(): backend = DummyEngine(save_commands=True) connectivity = {(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)} eng = MainEngine( backend=backend, engine_list=[ _ibm5qubitmapper.IBM5QubitMapper(connections=connectivity), SwapAndCNOTFlipper(connectivity), ], ) qb0 = eng.allocate_qubit() # noqa: F841 qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() qb3 = eng.allocate_qubit() # noqa: F841 CNOT | (qb1, qb2) CNOT | (qb2, qb1) CNOT | (qb1, qb2) eng.flush() hadamard_count = 0 for cmd in backend.received_commands: if cmd.gate == H: hadamard_count += 1 assert hadamard_count == 4 backend.received_commands = [] CNOT | (qb2, qb1) CNOT | (qb1, qb2) CNOT | (qb2, qb1) eng.flush() hadamard_count = 0 for cmd in backend.received_commands: if cmd.gate == H: hadamard_count += 1 assert hadamard_count == 4
def test_ibm_retrieve(monkeypatch): # patch send def mock_retrieve(*args, **kwargs): return {'date': '2017-01-19T14:28:47.622Z', 'data': {'time': 14.429004907608032, 'counts': {'00111': 396, '00101': 27, '00000': 601}, 'qasm': ('...')}} monkeypatch.setattr(_ibm, "retrieve", mock_retrieve) backend = _ibm.IBMBackend(retrieve_execution="ab1s2") rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions]) connectivity = set([(1, 2), (2, 4), (0, 2), (3, 2), (4, 3), (0, 1)]) engine_list = [TagRemover(), LocalOptimizer(10), AutoReplacer(rule_set), TagRemover(), IBM5QubitMapper(), SwapAndCNOTFlipper(connectivity), LocalOptimizer(10)] eng = MainEngine(backend=backend, engine_list=engine_list) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(3) # entangle the qureg Entangle | qureg Tdag | qureg[0] Sdag | qureg[0] Barrier | qureg Rx(0.2) | qureg[0] del unused_qubit # measure; should be all-0 or all-1 All(Measure) | qureg # run the circuit eng.flush() prob_dict = eng.backend.get_probabilities([qureg[0], qureg[2], qureg[1]]) assert prob_dict['111'] == pytest.approx(0.38671875) assert prob_dict['101'] == pytest.approx(0.0263671875)
def get_engine_list(token=None, device=None): """Return the default list of compiler engine for the IBM QE platform.""" # Access to the hardware properties via show_devices # Can also be extended to take into account gate fidelities, new available # gate, etc.. devices = show_devices(token) ibm_setup = [] if device not in devices: raise DeviceOfflineError('Error when configuring engine list: device requested for Backend not connected') if devices[device]['nq'] == 5: # The requested device is a 5 qubit processor # Obtain the coupling map specific to the device coupling_map = devices[device]['coupling_map'] coupling_map = list2set(coupling_map) mapper = IBM5QubitMapper(coupling_map) ibm_setup = [mapper, SwapAndCNOTFlipper(coupling_map), LocalOptimizer(10)] elif device == 'ibmq_qasm_simulator': # The 32 qubit online simulator doesn't need a specific mapping for # gates. Can also run wider gateset but this setup keep the # restrictedgateset setup for coherence mapper = BasicMapperEngine() # Note: Manual Mapper doesn't work, because its map is updated only if # gates are applied if gates in the register are not used, then it # will lead to state errors res = {} for i in range(devices[device]['nq']): res[i] = i mapper.current_mapping = res ibm_setup = [mapper] elif device == 'ibmq_16_melbourne': # Only 15 qubits available on this ibmqx2 unit(in particular qubit 7 # on the grid), therefore need custom grid mapping grid_to_physical = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 15, 8: 14, 9: 13, 10: 12, 11: 11, 12: 10, 13: 9, 14: 8, 15: 7, } coupling_map = devices[device]['coupling_map'] coupling_map = list2set(coupling_map) ibm_setup = [ GridMapper(2, 8, grid_to_physical), LocalOptimizer(5), SwapAndCNOTFlipper(coupling_map), LocalOptimizer(5), ] else: # If there is an online device not handled into ProjectQ it's not too # bad, the engine_list can be constructed manually with the # appropriate mapper and the 'coupling_map' parameter raise DeviceNotHandledError('Device not yet fully handled by ProjectQ') # Most IBM devices accept U1,U2,U3,CX gates. # Most gates need to be decomposed into a subset that is manually converted # in the backend (until the implementation of the U1,U2,U3) # available gates decomposable now for U1,U2,U3: Rx,Ry,Rz and H setup = restrictedgateset.get_engine_list( one_qubit_gates=(Rx, Ry, Rz, H), two_qubit_gates=(CNOT,), other_gates=(Barrier,) ) setup.extend(ibm_setup) return setup