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_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_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_openqasm_test_qasm_single_qubit_gates_control(): backend = OpenQASMEngine() eng = MainEngine(backend=backend, engine_list=[]) qubit = eng.allocate_qubit() ctrl = eng.allocate_qubit() with Control(eng, ctrl): H | qubit X | qubit Y | qubit Z | qubit NOT | qubit R(0.5) | qubit Rz(0.5) | qubit Ph(0.5) | qubit eng.flush() qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l] assert qasm == [ 'qreg q0[1];', 'qreg q1[1];', 'creg c0[1];', 'creg c1[1];', 'ch q1[0],q0[0];', 'cx q1[0],q0[0];', 'cy q1[0],q0[0];', 'cz q1[0],q0[0];', 'cx q1[0],q0[0];', 'cu1(0.500000000000000) q1[0],q0[0];', 'crz(0.500000000000000) q1[0],q0[0];', 'cu1(-0.250000000000000) q1[0],q0[0];' ]
def test_Ph_eigenvectors(): rule_set = DecompositionRuleSet(modules=[pe, dqft]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) N = 150 results = np.array([]) for i in range(N): autovector = eng.allocate_qureg(1) theta = cmath.pi * 2.0 * 0.125 unit = Ph(theta) ancillas = eng.allocate_qureg(3) QPE(unit) | (ancillas, autovector) All(Measure) | ancillas fasebinlist = [int(q) for q in ancillas] fasebin = ''.join(str(j) for j in fasebinlist) faseint = int(fasebin, 2) phase = faseint / (2.0**(len(ancillas))) results = np.append(results, phase) All(Measure) | autovector eng.flush() num_phase = (results == 0.125).sum() assert num_phase / N >= 0.35, "Statistics phase calculation are not correct (%f vs. %f)" % ( num_phase / N, 0.35, )
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 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_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_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_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 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 test_unitary_flush_does_not_invalidate(): eng = MainEngine(backend=UnitarySimulator(), engine_list=[]) qureg = eng.allocate_qureg(2) X | qureg[0] eng.flush() Y | qureg[1] eng.flush() # Make sure that calling flush() multiple time is ok (before measurements) eng.flush() eng.flush() # Nothing should be added to the history here since no measurements or qubit deallocation happened assert not eng.backend.history assert np.allclose(eng.backend.unitary, np.kron(Y.matrix, X.matrix)) All(Measure) | qureg # Make sure that calling flush() multiple time is ok (after measurement) eng.flush() eng.flush() # Nothing should be added to the history here since no gate since measurements or qubit deallocation happened assert not eng.backend.history assert np.allclose(eng.backend.unitary, np.kron(Y.matrix, X.matrix))
def test_X_no_eigenvectors(): rule_set = DecompositionRuleSet( modules=[pe, dqft, stateprep2cnot, ucr2cnot]) eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), ], ) N = 100 results = np.array([]) results_plus = np.array([]) results_minus = np.array([]) for i in range(N): autovector = eng.allocate_qureg(1) amplitude0 = (np.sqrt(2) + np.sqrt(6)) / 4.0 amplitude1 = (np.sqrt(2) - np.sqrt(6)) / 4.0 StatePreparation([amplitude0, amplitude1]) | autovector unit = X ancillas = eng.allocate_qureg(1) QPE(unit) | (ancillas, autovector) All(Measure) | ancillas fasebinlist = [int(q) for q in ancillas] fasebin = ''.join(str(j) for j in fasebinlist) faseint = int(fasebin, 2) phase = faseint / (2.0**(len(ancillas))) results = np.append(results, phase) Tensor(H) | autovector if np.allclose(phase, 0.0, rtol=1e-1): results_plus = np.append(results_plus, phase) All(Measure) | autovector autovector_result = int(autovector) assert autovector_result == 0 elif np.allclose(phase, 0.5, rtol=1e-1): results_minus = np.append(results_minus, phase) All(Measure) | autovector autovector_result = int(autovector) assert autovector_result == 1 eng.flush() total = len(results_plus) + len(results_minus) plus_probability = len(results_plus) / N assert total == pytest.approx(N, abs=5) assert plus_probability == pytest.approx( 1.0 / 4.0, abs=1e-1 ), "Statistics on |+> probability are not correct (%f vs. %f)" % ( plus_probability, 1.0 / 4.0, )
def test_recognize_incorrect_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() ctrl_qureg = eng.allocate_qureg(2) eng.flush() with Control(eng, ctrl_qubit): Rx(0.3) | qubit X | qubit with Control(eng, ctrl_qureg): X | qubit eng.flush(deallocate_qubits=True) for cmd in saving_backend.received_commands: assert not cnu2toffoliandcu._recognize_CnU(cmd)
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() with Control(eng, ctrl_qubit): Ph(0.1) | qubit R(0.2) | qubit Rx(0.3) | qubit X | qubit eng.flush(deallocate_qubits=True) # Don't test initial two allocate and flush and trailing deallocate # and flush gate. for cmd in saving_backend.received_commands[3:-3]: assert carb1q._recognize_carb1qubit(cmd)
def test_resource_counter_measurement(): eng = MainEngine(ResourceCounter(), []) qb1 = WeakQubitRef(engine=eng, idx=1) qb2 = WeakQubitRef(engine=eng, idx=2) cmd0 = Command(engine=eng, gate=Allocate, qubits=([qb1],)) cmd1 = Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[], tags=[LogicalQubitIDTag(2)]) with pytest.raises(NotYetMeasuredError): int(qb1) with pytest.raises(NotYetMeasuredError): int(qb2) eng.send([cmd0, cmd1]) eng.flush() with pytest.raises(NotYetMeasuredError): int(qb1) assert int(qb2) == 0
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 run(args, param="simulation"): """ Be careful the Measure command can take a lot of time to execute as you can create as much as qubit as you want :param args: list of int :param param: choose between simulation or latex :return: """ # 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) Xreg = initialisation(eng2, args) m = len(Xreg) All(Measure) | Xreg eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) Xreg = initialisation(eng, args) m = len(Xreg) n = Xreg[0].__len__() for i in range(m): All(Measure) | Xreg[i] eng.flush() measurement = [] for i in range(m): measurement.append([0] * n) for k in range(n): measurement[i][k] = int(Xreg[i][k]) return measurement
def test_flush_deallocates_all_qubits(): mapper = BoundedQubitMapper(10) engine = MainEngine( Simulator(), engine_list=[mapper], verbose=True, ) # needed to prevent GC from removing qubit refs qureg = engine.allocate_qureg(10) assert len(mapper.current_mapping.keys()) == 10 assert len(engine.active_qubits) == 10 engine.flush() # Should still be around after flush assert len(engine.active_qubits) == 10 assert len(mapper.current_mapping.keys()) == 10 # GC will clean things up del qureg assert len(engine.active_qubits) == 0 assert len(mapper.current_mapping.keys()) == 0
def test_chooser_Ry_reducer_unsupported_gate(): backend = DummyEngine(save_commands=True) rule_set = DecompositionRuleSet( rules=[DecompositionRule(H.__class__, _dummy_h2nothing_A)]) engine_list = [ AutoReplacer(rule_set, chooser_Ry_reducer), TagRemover(), InstructionFilter(filter_gates), ] eng = MainEngine(backend=backend, engine_list=engine_list) qubit = eng.allocate_qubit() H | qubit eng.flush() for cmd in backend.received_commands: print(cmd) assert isinstance(backend.received_commands[1].gate, Ry)
def test_recognize_incorrect_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qubit = eng.allocate_qubit() ctrl_qureg = eng.allocate_qureg(2) eng.flush() with Control(eng, ctrl_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 with Control(eng, ctrl_qureg): # Too many Control qubits: Rx(0.3) | qubit eng.flush(deallocate_qubits=True) for cmd in saving_backend.received_commands: assert not carb1q._recognize_carb1qubit(cmd)
def qft(a = 11, param = "draw"): # Initialisation if param == "draw": drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) else: eng = MainEngine() [La, n] = int2bit(a) xa = eng.allocate_qureg(n) # initialisation de a et b for i in range(n): if La[i]: X | xa[i] # On passe de a a phi(a) : QTF eng.flush() QFT | xa eng.flush() if param != "draw": amp_xa = [] for i in range(1 << n): phase_reel = phase(eng.backend.get_amplitude(adapt_binary(bin(i), n), xa)) / (2 * math.pi) amp_xa.append(Fraction(phase_reel).limit_denominator(10)) print(amp_xa) All(Measure) | xa eng.flush() if param == "draw": print(drawing_engine.get_latex())
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 = {} 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 _recursive_decompose(self, cmd): if self.is_available(cmd): return [cmd] canonical_cmd, id_map, key, used, avail = self._canonicalize(cmd) if key in self._cached_results: if self._cached_results == 'IN PROGRESS': raise NoGateDecompositionError( 'Cyclic decomposition for {}.'.format(cmd)) return self._translate(cmd, self._cached_results[key], id_map) self._cached_results[key] = 'IN PROGRESS' rec = DummyEngine(save_commands=True) eng = MainEngine(backend=rec, engine_list=[ LocalOptimizer(), SimpleAdjacentCombiner(self.merge_rules), ]) involved = eng.allocate_qureg(used) workspace = eng.allocate_qureg(avail) eng.flush() rec.received_commands = [] canonical_cmd.engine = eng self._pick_decomp_for(cmd).decompose(canonical_cmd) eng.flush() intermediate_result = rec.received_commands[:-1] assert involved is not None assert workspace is not None flattened_result = [ leaf for child in intermediate_result for leaf in self._recursive_decompose(child) ] self._cached_results[key] = flattened_result return self._translate(cmd, flattened_result, id_map)
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_unitary_measure_mapped_qubit(): eng = MainEngine(UnitarySimulator()) qb1 = WeakQubitRef(engine=eng, idx=1) qb2 = WeakQubitRef(engine=eng, idx=2) cmd0 = Command(engine=eng, gate=Allocate, qubits=([qb1], )) cmd1 = Command(engine=eng, gate=X, qubits=([qb1], )) cmd2 = Command( engine=eng, gate=Measure, qubits=([qb1], ), controls=[], tags=[LogicalQubitIDTag(2)], ) with pytest.raises(NotYetMeasuredError): int(qb1) with pytest.raises(NotYetMeasuredError): int(qb2) eng.send([cmd0, cmd1]) eng.flush() eng.send([cmd2]) with pytest.raises(NotYetMeasuredError): int(qb1) assert int(qb2) == 1
def test_transpile_circuit(self): backend = JaqalBackend() engine_list = get_engine_list() eng = MainEngine(backend, engine_list, verbose=True) q1 = eng.allocate_qubit() q2 = eng.allocate_qubit() SqrtX | q1 SqrtX | q2 Barrier | (q1, q2) Rxx(1.0) | (q1, q2) All(Measure) | [q1, q2] eng.flush() circ = backend.circuit jcirc = CircuitBuilder() reg = jcirc.register("q", 2) block = jcirc.block() block.gate("prepare_all") block.gate("Sx", reg[0]) block.gate("Sx", reg[1]) block = jcirc.block() block.gate("MS", reg[0], reg[1], 0, 1.0) block.gate("measure_all") self.assertEqual(generate_jaqal_program(jcirc.build()), generate_jaqal_program(circ))
def test_decomposition(gate_matrix): for basis_state in ([1, 0], [0, 1]): # Create single qubit gate with gate_matrix test_gate = MatrixGate() test_gate.matrix = np.matrix(gate_matrix) correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[arb1q]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(z_y_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) test_gate | test_qb test_gate | correct_qb test_eng.flush() correct_eng.flush() assert correct_dummy_eng.received_commands[2].gate == test_gate assert test_dummy_eng.received_commands[2].gate != test_gate 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_recognize_correct_gates(): saving_backend = DummyEngine(save_commands=True) eng = MainEngine(backend=saving_backend) qubit = eng.allocate_qubit() ctrl_qureg = eng.allocate_qureg(2) ctrl_qureg2 = eng.allocate_qureg(3) eng.flush() with Control(eng, ctrl_qureg): Ph(0.1) | qubit Ry(0.2) | qubit with Control(eng, ctrl_qureg2): QFT | qubit + ctrl_qureg X | qubit eng.flush() # To make sure gates arrive before deallocate gates eng.flush(deallocate_qubits=True) # Don't test initial 6 allocate and flush and trailing deallocate # and two flush gates. for cmd in saving_backend.received_commands[7:-8]: assert cnu2toffoliandcu._recognize_CnU(cmd)
def test_decomposition(gate_matrix): # Create single qubit gate with gate_matrix test_gate = MatrixGate() test_gate.matrix = np.matrix(gate_matrix) for basis_state in ([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[carb1q]) 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) with Control(test_eng, test_ctrl_qb): test_gate | test_qb with Control(correct_eng, correct_ctrl_qb): test_gate | correct_qb test_eng.flush() correct_eng.flush() assert correct_dummy_eng.received_commands[3].gate == test_gate assert test_dummy_eng.received_commands[3].gate != test_gate for fstate in ['00', '01', '10', '11']: test = test_sim.get_amplitude(fstate, test_qb + test_ctrl_qb) correct = correct_sim.get_amplitude(fstate, correct_qb + correct_ctrl_qb) assert correct == pytest.approx(test, 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)