def test_unitary_not_last_engine(): eng = MainEngine(backend=DummyEngine(save_commands=True), engine_list=[UnitarySimulator()]) qubit = eng.allocate_qubit() X | qubit eng.flush() Measure | qubit assert len(eng.backend.received_commands) == 4
def test_resource_counter(): resource_counter = ResourceCounter() backend = DummyEngine(save_commands=True) eng = MainEngine(backend, [resource_counter]) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() H | qubit1 X | qubit2 del qubit2 qubit3 = eng.allocate_qubit() CNOT | (qubit1, qubit3) Measure | (qubit1, qubit3) assert int(qubit1) == int(qubit3) assert int(qubit1) == 0 assert resource_counter.max_width == 2 str_repr = str(resource_counter) assert str_repr.count("H") == 1 assert str_repr.count("X") == 2 assert str_repr.count("CX") == 1 assert str_repr.count("Allocate : 3") == 1 assert str_repr.count("Deallocate : 1") == 1 sent_gates = [cmd.gate for cmd in backend.received_commands] assert sent_gates.count(H) == 1 assert sent_gates.count(X) == 2 assert sent_gates.count(Measure) == 1
def __init__(self, aq, engine_list=[], verbose=False): MainEngine.__init__(self, engine_list=engine_list) self.prog = aq.prog self.qb = aq.qb self.nbqb = aq.nbqb self.to_measure = aq.to_measure self.verbose = verbose
def run_adder(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) [xa, xb] = initialisation(eng2, a, b) adder(eng2, xa, xb) measure(eng2, xa, xb) print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) [xa, xb] = initialisation(eng, a, b) adder(eng, xa, xb) print(measure(eng, xa, xb))
def test_openqasm_test_qasm_single_qubit_gates(): backend = OpenQASMEngine() eng = MainEngine(backend=backend, engine_list=[]) qubit = eng.allocate_qubit() H | qubit S | qubit T | qubit Sdag | qubit Tdag | qubit X | qubit Y | qubit Z | qubit R(0.5) | qubit Rx(0.5) | qubit Ry(0.5) | qubit Rz(0.5) | qubit Ph(0.5) | qubit NOT | qubit Measure | qubit eng.flush() qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l] assert qasm == [ 'qreg q0[1];', 'creg c0[1];', 'h q0[0];', 's q0[0];', 't q0[0];', 'sdg q0[0];', 'tdg q0[0];', 'x q0[0];', 'y q0[0];', 'z q0[0];', 'u1(0.500000000000000) q0[0];', 'rx(0.500000000000000) q0[0];', 'ry(0.500000000000000) q0[0];', 'rz(0.500000000000000) q0[0];', 'u1(-0.250000000000000) q0[0];', 'x q0[0];', 'measure q0[0] -> c0[0];' ]
def test_unitary_warnings(): eng = MainEngine(backend=DummyEngine(save_commands=True), engine_list=[UnitarySimulator()]) qubit = eng.allocate_qubit() X | qubit with pytest.raises(RuntimeError): Measure | qubit
def run(x=4, N=7, param="run"): """ :param a: a<N and must be invertible mod[N] :param N: :param x: :param param: :return: |1> --> |(a**x) mod N> """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet(modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) arcsinQ(eng, x, N) return drawing_engine if param == "count": eng = MainEngine(resource_counter) arcsinQ(eng, x, N) return resource_counter else: eng = MainEngine(Simulator(), compilerengines) return arcsinQ(eng, x, N)
def test_resource_counter_depth_of_dag(): resource_counter = ResourceCounter() eng = MainEngine(resource_counter, []) assert resource_counter.depth_of_dag == 0 qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() qb2 = eng.allocate_qubit() QFT | qb0 + qb1 + qb2 assert resource_counter.depth_of_dag == 1 H | qb0 H | qb0 assert resource_counter.depth_of_dag == 3 CNOT | (qb0, qb1) X | qb1 assert resource_counter.depth_of_dag == 5 Measure | qb1 Measure | qb1 assert resource_counter.depth_of_dag == 7 CNOT | (qb1, qb2) Measure | qb2 assert resource_counter.depth_of_dag == 9 qb1[0].__del__() qb2[0].__del__() assert resource_counter.depth_of_dag == 9 qb0[0].__del__() assert resource_counter.depth_of_dag == 9
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_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_complex_aa(): rule_set = DecompositionRuleSet(modules=[aa]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) system_qubits = eng.allocate_qureg(6) # Prepare the control qubit in the |-> state control = eng.allocate_qubit() X | control H | control # Creates the initial state form the Algorithm complex_algorithm(eng, system_qubits) # Get the probabilty of getting the marked state before the AA # to calculate the number of iterations eng.flush() prob000000 = eng.backend.get_probability('000000', system_qubits) prob111111 = eng.backend.get_probability('111111', system_qubits) total_amp_before = math.sqrt(prob000000 + prob111111) theta_before = math.asin(total_amp_before) # Apply Quantum Amplitude Amplification the correct number of times # Theta is calculated previously using get_probability # We calculate also the theoretical final probability # of getting the good state num_it = int(math.pi / (4.0 * theta_before) + 1) theoretical_prob = math.sin((2 * num_it + 1.0) * theta_before)**2 with Loop(eng, num_it): QAA(complex_algorithm, complex_oracle) | (system_qubits, control) # Get the probabilty of getting the marked state after the AA # to compare with the theoretical probability after the AA eng.flush() prob000000 = eng.backend.get_probability('000000', system_qubits) prob111111 = eng.backend.get_probability('111111', system_qubits) total_prob_after = prob000000 + prob111111 All(Measure) | system_qubits H | control Measure | control eng.flush() assert total_prob_after == pytest.approx( theoretical_prob, abs=1e-2 ), "The obtained probability is less than expected %f vs. %f" % ( total_prob_after, theoretical_prob, )
def test_openqasm_is_available(gate, is_available): eng = MainEngine(backend=DummyEngine(), engine_list=[OpenQASMEngine()]) qubit1 = eng.allocate_qubit() cmd = Command(eng, gate, (qubit1, )) eng.is_available(cmd) == is_available eng = MainEngine(backend=OpenQASMEngine(), engine_list=[]) qubit1 = eng.allocate_qubit() cmd = Command(eng, gate, (qubit1, )) eng.is_available(cmd) == is_available
def test_decomposition_errors(gate_matrix): test_gate = BasicGate() test_gate.matrix = np.matrix(gate_matrix) rule_set = DecompositionRuleSet(modules=[arb1q]) eng = MainEngine(backend=DummyEngine(), engine_list=[AutoReplacer(rule_set), InstructionFilter(z_y_decomp_gates)]) qb = eng.allocate_qubit() with pytest.raises(Exception): test_gate | qb
def test_entangle(): sim = Simulator() eng = MainEngine(sim, [AutoReplacer(), InstructionFilter(low_level_gates)]) qureg = eng.allocate_qureg(4) Entangle | qureg assert .5 == pytest.approx(abs(sim.cheat()[1][0])**2) assert .5 == pytest.approx(abs(sim.cheat()[1][-1])**2) Measure | qureg
def test_unitary_simulator(): def create_random_unitary(n): return unitary_group.rvs(2**n) mat1 = create_random_unitary(1) mat2 = create_random_unitary(2) mat3 = create_random_unitary(3) mat4 = create_random_unitary(1) n_qubits = 3 def apply_gates(eng, qureg): MatrixGate(mat1) | qureg[0] MatrixGate(mat2) | qureg[1:] MatrixGate(mat3) | qureg with Control(eng, qureg[1]): MatrixGate(mat2) | (qureg[0], qureg[2]) MatrixGate(mat4) | qureg[0] with Control(eng, qureg[1], ctrl_state='0'): MatrixGate(mat1) | qureg[0] with Control(eng, qureg[2], ctrl_state='0'): MatrixGate(mat1) | qureg[0] for basis_state in [ list(x[::-1]) for x in itertools.product([0, 1], repeat=2**n_qubits) ][1:]: ref_eng = MainEngine(engine_list=[], verbose=True) ref_qureg = ref_eng.allocate_qureg(n_qubits) ref_eng.backend.set_wavefunction(basis_state, ref_qureg) apply_gates(ref_eng, ref_qureg) test_eng = MainEngine(backend=UnitarySimulator(), engine_list=[], verbose=True) test_qureg = test_eng.allocate_qureg(n_qubits) assert np.allclose(test_eng.backend.unitary, np.identity(2**n_qubits)) apply_gates(test_eng, test_qureg) qubit_map, ref_state = ref_eng.backend.cheat() assert qubit_map == {i: i for i in range(n_qubits)} test_state = test_eng.backend.unitary @ np.array(basis_state) assert np.allclose(ref_eng.backend.cheat()[1], test_state) ref_eng.flush() test_eng.flush() All(Measure) | ref_qureg All(Measure) | test_qureg
def test_openqasm_is_available_2control(gate, is_available): eng = MainEngine(backend=DummyEngine(), engine_list=[OpenQASMEngine()]) qubit1 = eng.allocate_qubit() qureg = eng.allocate_qureg(2) cmd = Command(eng, gate, (qubit1, ), controls=qureg) assert eng.is_available(cmd) == is_available eng = MainEngine(backend=OpenQASMEngine(), engine_list=[]) qubit1 = eng.allocate_qubit() qureg = eng.allocate_qureg(2) cmd = Command(eng, gate, (qubit1, ), controls=qureg) assert eng.is_available(cmd) == is_available
def test_recognize_correct_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() Ph(0.1) | qubit R(0.2) | qubit Rx(0.3) | qubit X | qubit eng.flush(deallocate_qubits=True) # Don't test initial allocate and trailing deallocate and flush gate. for cmd in saving_backend.received_commands[1:-2]: assert arb1q._recognize_arb1qubit(cmd)
def __enter__(self): ''' Enter context, Attributes: eng (MainEngine): main engine. backend ('graphical' or 'simulate'): backend used. qureg (Qureg): quantum register. ''' if self.task == 'ibm': import projectq.setups.ibm else: import projectq.setups.default # create a main compiler engine with a specific backend: if self.task == 'draw': self.backend = CircuitDrawer() # locations = {0: 0, 1: 1, 2: 2, 3:3} # swap order of lines 0-1-2. # self.backend.set_qubit_locations(locations) elif self.task == 'simulate': print( 'ProjecQ simulation in training can be slow, since in scipy context, we cached a lot gates.' ) self.backend = Simulator(gate_fusion=True) elif self.task == 'ibm': # choose device device = self.ibm_config.get( 'device', 'ibmqx2' if self.num_bit <= 5 else 'ibmqx5') # check data if self.ibm_config is None: raise if device == 'ibmqx5': device_num_bit = 16 else: device_num_bit = 5 if device_num_bit < self.num_bit: raise AttributeError( 'device %s has not enough qubits for %d bit simulation!' % (device, self.num_bit)) self.backend = IBMBackend(use_hardware=True, num_runs=self.ibm_config['num_runs'], user=self.ibm_config['user'], password=self.ibm_config['password'], device=device, verbose=True) else: raise ValueError('engine %s not defined' % self.task) self.eng = MainEngine(self.backend) # initialize register self.qureg = self.eng.allocate_qureg(self.num_bit) return self
def test_entangle(): rule_set = DecompositionRuleSet(modules=[entangle]) sim = Simulator() eng = MainEngine(sim, [AutoReplacer(rule_set), InstructionFilter(low_level_gates)]) qureg = eng.allocate_qureg(4) Entangle | qureg assert .5 == pytest.approx(abs(sim.cheat()[1][0])**2) assert .5 == pytest.approx(abs(sim.cheat()[1][-1])**2) All(Measure) | qureg
def test_openqasm_test_qasm_single_qubit_gates_controls(): backend = OpenQASMEngine() eng = MainEngine(backend=backend, engine_list=[], verbose=True) qubit = eng.allocate_qubit() ctrls = eng.allocate_qureg(2) with Control(eng, ctrls): X | qubit NOT | qubit eng.flush() qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l] assert qasm == [ 'qreg q0[1];', 'qreg q1[1];', 'qreg q2[1];', 'creg c0[1];', 'creg c1[1];', 'creg c2[1];', 'ccx q1[0],q2[0],q0[0];', 'ccx q1[0],q2[0],q0[0];', ] with pytest.raises(RuntimeError): with Control(eng, ctrls): Y | qubit eng.flush()
def test_recognize_incorrect_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() # Does not have matrix attribute: BasicGate() | qubit # Two qubit gate: two_qubit_gate = BasicGate() two_qubit_gate.matrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] two_qubit_gate | qubit eng.flush(deallocate_qubits=True) for cmd in saving_backend.received_commands: assert not arb1q._recognize_arb1qubit(cmd)
def main(): """Definition of the main function of this example.""" # Create a MainEngine with a unitary simulator backend eng = MainEngine(backend=UnitarySimulator()) n_qubits = 3 # Run out quantum circuit # 1 - circuit applying X on all qubits # 2 - circuit applying an X gate followed by a controlled-X gate # 3 - circuit applying a off-controlled-X gate # 4 - circuit applying a QFT on all qubits (QFT will get decomposed) run_circuit(eng, n_qubits, 3, gate_after_measure=True) # Output the unitary transformation of the circuit print('The unitary of the circuit is:') print(eng.backend.unitary) # Output the final state of the qubits (assuming they all start in state |0>) print('The final state of the qubits is:') print(eng.backend.unitary @ np.array([1] + ([0] * (2**n_qubits - 1)))) print('\n') # Show the unitaries separated by measurement: for history in eng.backend.history: print('Previous unitary is: \n', history, '\n')
def test_ibm_sent_error_2(monkeypatch): backend = _ibm.IBMBackend(verbose=True) mapper = BasicMapperEngine() res = {} 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 run(): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), InstructionFilter(high_level_gates), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # make the compiler and run the circuit on the simulator backend #eng = MainEngine(Simulator(), compilerengines) eng = MainEngine(resource_counter) # print welcome message and ask the user for the number to factor print( "\n\t\033[37mprojectq\033[0m\n\t--------\n\tImplementation of Shor" "\'s algorithm.", end="") N = int(input('\n\tNumber to factor: ')) print("\n\tFactoring N = {}: \033[0m".format(N), end="") # choose a base at random: a = N while not gcd(a, N) == 1: a = random.randint(2, N) print("\na is " + str(a)) if not gcd(a, N) == 1: print("\n\n\t\033[92mOoops, we were lucky: Chose non relative prime" " by accident :)") print("\tFactor: {}\033[0m".format(gcd(a, N))) else: # run the quantum subroutine r = run_shor(eng, N, a, True) print("\n\nr found : " + str(r)) # try to determine the factors if r % 2 != 0: r *= 2 apowrhalf = pow(a, r >> 1, N) f1 = gcd(apowrhalf + 1, N) f2 = gcd(apowrhalf - 1, N) print("f1 = {}, f2 = {}".format(f1, f2)) if ((not f1 * f2 == N) and f1 * f2 > 1 and int(1. * N / (f1 * f2)) * f1 * f2 == N): f1, f2 = f1 * f2, int(N / (f1 * f2)) if f1 * f2 == N and f1 > 1 and f2 > 1: print( "\n\n\t\033[92mFactors found :-) : {} * {} = {}\033[0m".format( f1, f2, N)) else: print("\n\n\t\033[91mBad luck: Found {} and {}\033[0m".format( f1, f2)) return resource_counter # print resource usage
def test_globalphase(): dummy = DummyEngine(save_commands=True) eng = MainEngine(dummy, [AutoReplacer(), InstructionFilter(low_level_gates_noglobalphase)]) qubit = eng.allocate_qubit() R(1.2) | qubit rz_count = 0 for cmd in dummy.received_commands: assert not isinstance(cmd.gate, R) if isinstance(cmd.gate, Rz): rz_count += 1 assert cmd.gate == Rz(1.2) assert rz_count == 1
def test_gate_decompositions(): sim = Simulator() eng = MainEngine(sim, []) qureg = run_circuit(eng) sim2 = Simulator() eng_lowlevel = MainEngine(sim2, [AutoReplacer(), InstructionFilter(low_level_gates)]) qureg2 = run_circuit(eng_lowlevel) for i in range(len(sim.cheat()[1])): assert sim.cheat()[1][i] == pytest.approx(sim2.cheat()[1][i]) Measure | qureg Measure | qureg2
def run_inv(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet(modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter] # create a main compiler engine a1 = a b1 = b if a == 0: a1 = 1 if b == 0: b1 = 1 n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xa = initialisation_n(eng2, a, n + 1) xb = initialisation_n(eng2, b, n + 1) # b --> phi(b) QFT | xb phi_adder(eng2, xa, xb) with Dagger(eng2): QFT | xb All(Measure) | xa All(Measure) | xb eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) xa = initialisation_n(eng, a, n + 1) xb = initialisation_n(eng, b, n + 1) # b --> phi(b) QFT | xb with Dagger(eng): phi_adder(eng, xa, xb) with Dagger(eng): QFT | xb All(Measure) | xa All(Measure) | xb eng.flush() n = n+1 measurements_a = [0] * n measurements_b = [0] * n for k in range(n): measurements_a[k] = int(xa[k]) measurements_b[k] = int(xb[k]) return [measurements_a, meas2int(measurements_b), measurements_b]
def test_ibm_errors(): backend = _ibm.IBMBackend(verbose=True, num_runs=1000) mapper = BasicMapperEngine() mapper.current_mapping = {0: 0} eng = MainEngine(backend=backend, engine_list=[mapper]) qb0 = WeakQubitRef(engine=None, idx=0) # No LogicalQubitIDTag with pytest.raises(RuntimeError): eng.backend._store(Command(engine=eng, gate=Measure, qubits=([qb0],))) eng = MainEngine(backend=backend, engine_list=[]) # No mapper with pytest.raises(RuntimeError): eng.backend._store(Command(engine=eng, gate=Measure, qubits=([qb0],), tags=(LogicalQubitIDTag(1),)))
def test_unitary_functional_measurement(): eng = MainEngine(UnitarySimulator()) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) eng.flush() All(Measure) | qubits bit_value_sum = sum([int(qubit) for qubit in qubits]) assert bit_value_sum == 0 or bit_value_sum == 5 qb1 = WeakQubitRef(engine=eng, idx=qubits[0].id) qb2 = WeakQubitRef(engine=eng, idx=qubits[1].id) with pytest.raises(ValueError): eng.backend._handle(Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[qb2]))
def test_resource_counter(): resource_counter = ResourceCounter() backend = DummyEngine(save_commands=True) eng = MainEngine(backend, [resource_counter]) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() H | qubit1 X | qubit2 del qubit2 qubit3 = eng.allocate_qubit() CNOT | (qubit1, qubit3) Rz(0.1) | qubit1 Rz(0.3) | qubit1 Rzz(0.5) | qubit1 All(Measure) | qubit1 + qubit3 with pytest.raises(NotYetMeasuredError): int(qubit1) assert resource_counter.max_width == 2 assert resource_counter.depth_of_dag == 6 str_repr = str(resource_counter) assert str_repr.count(" HGate : 1") == 1 assert str_repr.count(" XGate : 1") == 1 assert str_repr.count(" CXGate : 1") == 1 assert str_repr.count(" Rz : 2") == 1 assert str_repr.count(" AllocateQubitGate : 3") == 1 assert str_repr.count(" DeallocateQubitGate : 1") == 1 assert str_repr.count(" H : 1") == 1 assert str_repr.count(" X : 1") == 1 assert str_repr.count(" CX : 1") == 1 assert str_repr.count(" Rz(0.1) : 1") == 1 assert str_repr.count(" Rz(0.3) : 1") == 1 assert str_repr.count(" Allocate : 3") == 1 assert str_repr.count(" Deallocate : 1") == 1 sent_gates = [cmd.gate for cmd in backend.received_commands] assert sent_gates.count(H) == 1 assert sent_gates.count(X) == 2 assert sent_gates.count(Measure) == 2