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_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_drawer_measurement(): drawer = CircuitDrawerMatplotlib(default_measure=0) eng = MainEngine(drawer, []) qubit = eng.allocate_qubit() Measure | qubit assert int(qubit) == 0 drawer = CircuitDrawerMatplotlib(default_measure=1) eng = MainEngine(drawer, []) qubit = eng.allocate_qubit() Measure | qubit assert int(qubit) == 1 drawer = CircuitDrawerMatplotlib(accept_input=True) eng = MainEngine(drawer, []) qubit = eng.allocate_qubit() old_input = _drawer.input _drawer.input = lambda x: '1' Measure | qubit assert int(qubit) == 1 _drawer.input = old_input qb1 = WeakQubitRef(engine=eng, idx=1) qb2 = WeakQubitRef(engine=eng, idx=2) with pytest.raises(ValueError): eng.backend._process(Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[qb2]))
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=[rx2rz]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[AutoReplacer(rule_set), InstructionFilter(rx_decomp_gates), test_dummy_eng]) correct_qb = correct_eng.allocate_qubit() Rx(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Rx(angle) | test_qb test_eng.flush() assert correct_dummy_eng.received_commands[1].gate == Rx(angle) assert test_dummy_eng.received_commands[1].gate != Rx(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_simulator_is_available(sim): backend = DummyEngine(save_commands=True) eng = MainEngine(backend, []) qubit = eng.allocate_qubit() Measure | qubit BasicMathGate(lambda x: x) | qubit del qubit assert len(backend.received_commands) == 4 # Test that allocate, measure, basic math, and deallocate are available. for cmd in backend.received_commands: assert sim.is_available(cmd) new_cmd = backend.received_commands[-1] new_cmd.gate = Mock1QubitGate() assert sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 new_cmd.gate = Mock6QubitGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 new_cmd.gate = MockNoMatrixGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 eng = MainEngine(sim, []) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() with pytest.raises(Exception): Mock2QubitGate() | (qubit1, qubit2)
def test_quantum_lines_cnot(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() Measure | qubit1 Measure | qubit2 CNOT | (qubit2, qubit1) del qubit1, qubit2 code = drawer.get_latex() assert code.count("edge[") == 12 # all lines are classical drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() Measure | qubit1 # qubit1 is classical CNOT | (qubit2, qubit1) # now it is quantum del qubit1, qubit2 code = drawer.get_latex() assert code.count("edge[") == 7 # all lines are quantum
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_large_gates(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) old_tolatex = _drawer.to_latex _drawer.to_latex = lambda x, drawing_order, draw_gates_in_parallel: x qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() qubit3 = eng.allocate_qubit() class MyLargeGate(BasicGate): def __str__(self): return "large_gate" H | qubit2 MyLargeGate() | (qubit1, qubit3) H | qubit2 eng.flush() circuit_lines = drawer.get_latex() _drawer.to_latex = old_tolatex settings = _to_latex.get_default_settings() settings['gates']['AllocateQubitGate']['draw_id'] = True code = _to_latex._body(circuit_lines, settings) assert code.count("large_gate") == 1 # 1 large gate was applied # check that large gate draws lines, also for qubits it does not act upon assert code.count("edge[") == 5 assert code.count("{H};") == 2
def test_body_with_drawing_order_and_gates_not_parallel(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) old_tolatex = _drawer.to_latex _drawer.to_latex = lambda x, drawing_order, draw_gates_in_parallel: x qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() qubit3 = eng.allocate_qubit() H | qubit1 H | qubit2 H | qubit3 CNOT | (qubit1, qubit3) # replicates the above order: first the 3 allocations, then the 3 Hadamard and 1 CNOT gates order = [0, 1, 2, 0, 1, 2, 0] del qubit1 eng.flush() circuit_lines = drawer.get_latex() _drawer.to_latex = old_tolatex settings = _to_latex.get_default_settings() settings['gates']['AllocateQubitGate']['draw_id'] = True code = _to_latex._body(circuit_lines, settings, drawing_order=order, draw_gates_in_parallel=False) # and the CNOT is at position 4.0, because of the offsets # which are 0.5 * 3 * 2 (due to three Hadamards) + the initialisations assert code.count("node[phase] (line0_gate4) at (4.0,-0)") == 1 assert code.count("node[xstyle] (line2_gate4) at (4.0,-2)") == 1
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_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_only_single_error_in_costum_uncompute(): eng = MainEngine(backend=DummyEngine(), engine_list=[]) with _compute.Compute(eng): eng.allocate_qubit() # Tests that QubitManagementError is not sent in addition with pytest.raises(RuntimeError): with _compute.CustomUncompute(eng): raise RuntimeError
def test_aqt_backend_functional_test(monkeypatch): correct_info = { 'circuit': '[["Y", 0.5, [1]], ["X", 0.5, [1]], ["X", 0.5, [1]], ' '["Y", 0.5, [1]], ["MS", 0.5, [1, 2]], ["X", 3.5, [1]], ' '["Y", 3.5, [1]], ["X", 3.5, [2]]]', 'nq': 3, 'shots': 10, 'backend': {'name': 'simulator'}, } def mock_send(*args, **kwargs): assert args[0] == correct_info return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6] monkeypatch.setattr(_aqt, "send", mock_send) backend = _aqt.AQTBackend(verbose=True, num_runs=10) # no circuit has been executed -> raises exception with pytest.raises(RuntimeError): backend.get_probabilities([]) mapper = BasicMapperEngine() res = {} for i in range(4): res[i] = i mapper.current_mapping = res eng = MainEngine(backend=backend, engine_list=[mapper]) unused_qubit = eng.allocate_qubit() qureg = eng.allocate_qureg(2) # entangle the qureg Ry(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Rx(math.pi / 2) | qureg[0] Ry(math.pi / 2) | qureg[0] Rxx(math.pi / 2) | (qureg[0], qureg[1]) Rx(7 * math.pi / 2) | qureg[0] Ry(7 * math.pi / 2) | qureg[0] Rx(7 * math.pi / 2) | qureg[1] All(Barrier) | qureg 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[1]]) assert prob_dict['11'] == pytest.approx(0.4) assert prob_dict['00'] == pytest.approx(0.6) # Unknown qubit and no mapper invalid_qubit = [WeakQubitRef(eng, 10)] with pytest.raises(RuntimeError): eng.backend.get_probabilities(invalid_qubit) with pytest.raises(RuntimeError): eng.backend.get_probabilities(eng.allocate_qubit())
def test_qubit_management_error2(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) with _compute.Compute(eng): ancilla = eng.allocate_qubit() local_ancilla = eng.allocate_qubit() local_ancilla[0].__del__() eng.active_qubits = weakref.WeakSet() with pytest.raises(_compute.QubitManagementError): _compute.Uncompute(eng)
def test_ibm_backend_functional_test(monkeypatch): correct_info = ('{"name": "ProjectQ Experiment", "qasm": "\\ninclude \\"' 'qelib1.inc\\";\\nqreg q[5];\\ncreg c[5];\\nh q[0];\\ncx' ' q[0], q[2];\\ncx q[0], q[1];\\ntdg q[0];\\nsdg q[0];\\' 'nmeasure q[0] -> c[0];\\nmeasure q[2] -> c[2];\\nmeasure' ' q[1] -> c[1];", "codeType": "QASM2"}') # patch send 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, 'serialNumberDevice': 'Real5Qv1', 'p': {'labels': ['00000', '00001', '00010', '00011', '00100', '00101', '00110', '00111'], 'values': [0.4521484375, 0.0419921875, 0.0185546875, 0.0146484375, 0.005859375, 0.0263671875, 0.0537109375, 0.38671875], 'qubits': [0, 1, 2]}, '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(), IBMCNOTMapper(), 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] # measure; should be all-0 or all-1 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 test_decomposition(angle): """ Test that this decomposition of Rz produces correct amplitudes Note that this function tests each DecompositionRule in rz2rx.all_defined_decomposition_rules """ decomposition_rule_list = rz2rx.all_defined_decomposition_rules for rule in decomposition_rule_list: 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(rules=[rule]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(rz_decomp_gates), test_dummy_eng ]) correct_qb = correct_eng.allocate_qubit() Rz(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Rz(angle) | test_qb test_eng.flush() # Create empty vectors for the wave vectors for the correct and # test qubits correct_vector = np.zeros((2, 1), dtype=np.complex_) test_vector = np.zeros((2, 1), dtype=np.complex_) i = 0 for fstate in ['0', '1']: test = test_eng.backend.get_amplitude(fstate, test_qb) correct = correct_eng.backend.get_amplitude(fstate, correct_qb) correct_vector[i] = correct test_vector[i] = test i += 1 # Necessary to transpose vector to use matrix dot product test_vector = test_vector.transpose() # Remember that transposed vector should come first in product vector_dot_product = np.dot(test_vector, correct_vector) assert np.absolute(vector_dot_product) == pytest.approx(1, rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def MPS(params, data, shots, rounding): answers = np.zeros(data.shape[0]) for i in range(data.shape[0]): x = np.zeros(shots) for k in range(shots): eng = MainEngine( ) # create a default compiler (the back-end is a simulator) q1 = eng.allocate_qubit() # allocate 1 qubit q2 = eng.allocate_qubit() q3 = eng.allocate_qubit() q4 = eng.allocate_qubit() Ry(data[i, 0] * 2) | q1 Ry(data[i, 1] * 2) | q2 Ry(data[i, 2] * 2) | q3 Ry(data[i, 3] * 2) | q4 Ry(params[0]) | q1 Ry(params[1]) | q2 Ry(params[2]) | q3 Ry(params[3]) | q4 CNOT | (q1, q2) Ry(params[4]) | q2 CNOT | (q2, q3) Ry(params[5]) | q3 CNOT | (q3, q4) Ry(params[6]) | q4 Measure | q4 # measure the qubit Measure | q1 Measure | q2 Measure | q3 eng.flush() x[k] = int(q4) #print(x) #print(x) idx = x == 0 num_zeros = shots - sum(x) prop_zeros = num_zeros / shots #print(prop_zeros) if rounding == 1: answers[i] = 1 - round(prop_zeros) answers[i] = abs(answers[i] - data[i, 4]) if rounding == 0: prop_ones = 1 - prop_zeros answers[i] = abs(prop_ones - data[i, 4]) print(np.sum(answers)) print(answers) return (np.sum(answers))
def test_uniformly_controlled_ry(n, gate_classes): random_angles = [ 0.5, 0.8, 1.2, 2.5, 4.4, 2.32, 6.6, 15.12, 1, 2, 9.54, 2.1, 3.1415, 1.1, 0.01, 0.99 ] angles = random_angles[:2**n] for basis_state_index in range(0, 2**(n + 1)): basis_state = [0] * 2**(n + 1) basis_state[basis_state_index] = 1. correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[ucr2cnot]) 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(n) correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qureg = test_eng.allocate_qureg(n) 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) gate_classes[1](angles) | (test_ctrl_qureg, test_qb) slow_implementation(angles=angles, control_qubits=correct_ctrl_qureg, target_qubit=correct_qb, eng=correct_eng, gate_class=gate_classes[0]) test_eng.flush() correct_eng.flush() for fstate in range(2**(n + 1)): binary_state = format(fstate, '0' + str(n + 1) + 'b') 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-10, abs=1e-10) 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_command_printer_accept_input(monkeypatch): cmd_printer = _printer.CommandPrinter() eng = MainEngine(backend=cmd_printer, engine_list=[DummyEngine()]) monkeypatch.setattr(_printer, "input", lambda x: 1) qubit = eng.allocate_qubit() Measure | qubit assert int(qubit) == 1 monkeypatch.setattr(_printer, "input", lambda x: 0) qubit = eng.allocate_qubit() NOT | qubit Measure | qubit assert int(qubit) == 0
def test_recognize_correct_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() eng.flush() Rx(0.3) | qubit with Control(eng, ctrl_qubit): Rx(0.4) | qubit eng.flush(deallocate_qubits=True) assert rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[3]) assert not rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[4])
def test_body_with_drawing_order_and_gates_parallel(): drawer = _drawer.CircuitDrawer() eng = MainEngine(drawer, []) old_tolatex = _drawer.to_latex _drawer.to_latex = lambda x, drawing_order, draw_gates_in_parallel: x qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() qubit3 = eng.allocate_qubit() H | qubit1 H | qubit2 H | qubit3 CNOT | (qubit1, qubit3) # replicates the above order order = [ 0, 1, 2, # initializations 0, 1, 2, # H1, H3, H2 0 # CNOT ] del qubit1 eng.flush() circuit_lines = drawer.get_latex() _drawer.to_latex = old_tolatex settings = _to_latex.get_default_settings() settings['gates']['AllocateQubitGate']['draw_id'] = True code = _to_latex._body(circuit_lines, settings, drawing_order=order, draw_gates_in_parallel=True) # there are three Hadamards in parallel assert code.count("node[pos=.5] {H}") == 3 # line1_gate0 is initialisation # line1_gate1 is empty # line1_gate2 is for Hadamard on line1 # line1_gate3 is empty # XOR of CNOT is node[xstyle] (line1_gate4) assert code.count("node[xstyle] (line2_gate4)") == 1 # and the CNOT is at position 1.4, because of the offsets assert code.count("node[phase] (line0_gate4) at (1.4") == 1 assert code.count("node[xstyle] (line2_gate4) at (1.4") == 1
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 test_qubitop2singlequbit(): num_qubits = 4 random_initial_state = [ 0.2 + 0.1 * x * cmath.exp(0.1j + 0.2j * x) for x in range(2**(num_qubits + 1)) ] rule_set = DecompositionRuleSet(modules=[qubitop2onequbit]) test_eng = MainEngine( backend=Simulator(), engine_list=[AutoReplacer(rule_set), InstructionFilter(_decomp_gates)], ) test_qureg = test_eng.allocate_qureg(num_qubits) test_ctrl_qb = test_eng.allocate_qubit() test_eng.flush() test_eng.backend.set_wavefunction(random_initial_state, test_qureg + test_ctrl_qb) correct_eng = MainEngine() correct_qureg = correct_eng.allocate_qureg(num_qubits) correct_ctrl_qb = correct_eng.allocate_qubit() correct_eng.flush() correct_eng.backend.set_wavefunction(random_initial_state, correct_qureg + correct_ctrl_qb) qubit_op_0 = QubitOperator("X0 Y1 Z3", -1.0j) qubit_op_1 = QubitOperator("Z0 Y1 X3", cmath.exp(0.6j)) qubit_op_0 | test_qureg with Control(test_eng, test_ctrl_qb): qubit_op_1 | test_qureg test_eng.flush() correct_eng.backend.apply_qubit_operator(qubit_op_0, correct_qureg) with Control(correct_eng, correct_ctrl_qb): Ph(0.6) | correct_qureg[0] Z | correct_qureg[0] Y | correct_qureg[1] X | correct_qureg[3] correct_eng.flush() for fstate in range(2**(num_qubits + 1)): binary_state = format(fstate, '0' + str(num_qubits + 1) + 'b') test = test_eng.backend.get_amplitude(binary_state, test_qureg + test_ctrl_qb) correct = correct_eng.backend.get_amplitude( binary_state, correct_qureg + correct_ctrl_qb) assert correct == pytest.approx(test, rel=1e-10, abs=1e-10) All(Measure) | correct_qureg + correct_ctrl_qb All(Measure) | test_qureg + test_ctrl_qb correct_eng.flush() test_eng.flush()
def test_recognize_correct_gates(): """ Test that recognize_HNoCtrl recognizes ctrl qubits """ saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() eng.flush() H | qubit with Control(eng, ctrl_qubit): H | qubit eng.flush(deallocate_qubits=True) assert h2rx._recognize_HNoCtrl(saving_backend.received_commands[3]) assert not h2rx._recognize_HNoCtrl(saving_backend.received_commands[4])
def test_control_function_majority(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) qubit0 = main_engine.allocate_qubit() qubit1 = main_engine.allocate_qubit() qubit2 = main_engine.allocate_qubit() qubit3 = main_engine.allocate_qubit() ControlFunctionOracle(0xe8) | (qubit0, qubit1, qubit2, qubit3) assert len(saving_backend.received_commands) == 7
def test_ibmcnotmapper_invalid_circuit(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_ibmcnotmapper.IBMCNOTMapper()]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() qb3 = eng.allocate_qubit() CNOT | (qb1, qb2) CNOT | (qb0, qb1) with pytest.raises(Exception): CNOT | (qb3, qb2) eng.flush()
def test_auto_replacer_priorize_controlstate_rule(): # Check that when a control state is given and it has negative control, # Autoreplacer prioritizes the corresponding decomposition rule before anything else. # (Decomposition rule should have name _decompose_controlstate) # Create test gate and inverse class ControlGate(BasicGate): pass def _decompose_controlstate(cmd): S | cmd.qubits def _decompose_random(cmd): H | cmd.qubits def control_filter(self, cmd): if cmd.gate == ControlGate(): return False return True rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_random)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == H rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_controlstate)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == S
def test_decomposition(): """Test that this decomposition of H produces correct amplitudes Function tests each DecompositionRule in h2rx.all_defined_decomposition_rules """ decomposition_rule_list = h2rx.all_defined_decomposition_rules for rule in decomposition_rule_list: for basis_state_index in range(2): basis_state = [0] * 2 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(rules=[rule]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(h_decomp_gates), test_dummy_eng, ], ) correct_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_eng.flush() correct_eng.backend.set_wavefunction(basis_state, correct_qb) test_eng.backend.set_wavefunction(basis_state, test_qb) H | correct_qb H | test_qb correct_eng.flush() test_eng.flush() assert H in (cmd.gate for cmd in correct_dummy_eng.received_commands) assert H not in (cmd.gate for cmd in test_dummy_eng.received_commands) assert correct_eng.backend.cheat()[1] == pytest.approx( test_eng.backend.cheat()[1], rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def test_swapandcnotflipper_invalid_circuit(): backend = DummyEngine(save_commands=True) connectivity = {(0, 2)} flipper = _swapandcnotflipper.SwapAndCNOTFlipper(connectivity) eng = MainEngine(backend=backend, engine_list=[flipper]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() CNOT | (qb0, qb2) CNOT | (qb2, qb0) with pytest.raises(RuntimeError): CNOT | (qb0, qb1) with pytest.raises(RuntimeError): Swap | (qb0, qb1)
def test_decomposition(): """ Test that this decomposition of CNOT produces correct amplitudes Function tests each DecompositionRule in cnot2rxx.all_defined_decomposition_rules """ decomposition_rule_list = cnot2rxx.all_defined_decomposition_rules for rule in decomposition_rule_list: for basis_state_index in range(0, 4): basis_state = [0] * 4 basis_state[basis_state_index] = 1. correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(rules=[rule]) 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_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qb = test_eng.allocate_qubit() test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qb) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qb) CNOT | (test_ctrl_qb, test_qb) CNOT | (correct_ctrl_qb, correct_qb) test_eng.flush() correct_eng.flush() assert len(correct_dummy_eng.received_commands) == 5 assert len(test_dummy_eng.received_commands) == 10 assert correct_eng.backend.cheat()[1] == pytest.approx( test_eng.backend.cheat()[1], rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qb All(Measure) | correct_qb + correct_ctrl_qb test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
from projectq import MainEngine # import the main compiler engine # import the operations we want to perform (Hadamard and measurement) from projectq.ops import H, Measure eng = MainEngine() # create a default compiler (the back-end is a simulator) qubit = eng.allocate_qubit() # allocate 1 qubit H | qubit # apply a Hadamard gate Measure | qubit # measure the qubit eng.flush() # flush all gates (and execute measurements) print("Measured {}".format(int(qubit))) # output measurement result