def test_not_propagation(self): q_0 = cirq.NamedQubit("q_0") q_1 = cirq.NamedQubit("q_1") before = cirq.Circuit([cirq.X.on(q_1), cirq.CNOT.on(q_0, q_1)]) after = cirq.Circuit([cirq.CNOT.on(q_0, q_1), cirq.X.on(q_1)]) self.assertEqual(cirq.qasm(self.run_voqc(before, ["not_propagation"])), cirq.qasm(after))
def test_consistency_with_qasm_output_and_qiskit(): qubits = [cirq.NamedQubit('q_{}'.format(i)) for i in range(4)] a, b, c, d = qubits circuit1 = cirq.Circuit( cirq.rx(np.pi / 2).on(a), cirq.ry(np.pi / 2).on(b), cirq.rz(np.pi / 2).on(b), cirq.X.on(a), cirq.Y.on(b), cirq.Z.on(c), cirq.H.on(d), cirq.S.on(a), cirq.T.on(b), cirq.S.on(c) ** -1, cirq.T.on(d) ** -1, cirq.X.on(d) ** 0.125, cirq.TOFFOLI.on(a, b, c), cirq.CSWAP.on(d, a, b), cirq.SWAP.on(c, d), cirq.CX.on(a, b), cirq.ControlledGate(cirq.Y).on(c, d), cirq.CZ.on(a, b), cirq.ControlledGate(cirq.H).on(b, c), cirq.IdentityGate(1).on(c), cirq.circuits.qasm_output.QasmUGate(1.0, 2.0, 3.0).on(d), ) qasm = cirq.qasm(circuit1) circuit2 = circuit_from_qasm(qasm) cirq_unitary = cirq.unitary(circuit2) ct.assert_allclose_up_to_global_phase(cirq_unitary, cirq.unitary(circuit1), atol=1e-8) cq.assert_qiskit_parsed_qasm_consistent_with_unitary(qasm, cirq_unitary)
def test_classical_control_multi_bit(): qasm = """OPENQASM 2.0; qreg q[2]; creg a[2]; measure q[0] -> a[0]; measure q[0] -> a[1]; if (a==1) CX q[0],q[1]; """ parser = QasmParser() q_0 = cirq.NamedQubit('q_0') q_1 = cirq.NamedQubit('q_1') # Since we split the measurement into two, we also need two conditions. # m_a==1 corresponds to m_a[0]==1, m_a[1]==0 expected_circuit = cirq.Circuit( cirq.measure(q_0, key='a_0'), cirq.measure(q_0, key='a_1'), cirq.CNOT(q_0, q_1).with_classical_controls( sympy.Eq(sympy.Symbol('a_0'), 1), sympy.Eq(sympy.Symbol('a_1'), 0) ), ) parsed_qasm = parser.parse(qasm) assert parsed_qasm.supportedFormat assert not parsed_qasm.qelib1Include ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit) assert parsed_qasm.qregs == {'q': 2} # Note that this will *not* round-trip, but there's no good way around that due to the # difference in how Cirq and QASM do multi-bit measurements. with pytest.raises(ValueError, match='QASM does not support multiple conditions'): _ = cirq.qasm(parsed_qasm.circuit)
def test_confused_measure_qasm(): q0 = cirq.LineQubit(0) assert (cirq.qasm( cirq.measure(q0, key='a', confusion_map={(0, ): np.array([[0, 1], [1, 0]])}), args=cirq.QasmArgs(), default='not implemented', ) == 'not implemented')
def test_qudit_measure_qasm(): assert ( cirq.qasm( cirq.measure(cirq.LineQid(0, 3), key='a'), args=cirq.QasmArgs(), default='not implemented', ) == 'not implemented' )
def test_AT(self): before = format_from_qasm(os.path.join(rel, "Arithmetic_and_Toffoli/tof_10.qasm")) with open("copy.qasm", "r") as f: c = f.read() before = circuit_from_qasm(c) #c.close() f = open(os.path.join((os.path.dirname(os.path.abspath(__file__))), "interop/tests/optimized_qasm_files/optim_tof_10.qasm")) t = f.read() f.close() after = circuit_from_qasm(t) #f.close() a = cirq.qasm(after) after = circuit_from_qasm(a) run = self.run_voqc(before) run = cirq.qasm(run) run = circuit_from_qasm(run) self.assertEqual(run, after)
def test_qasm_multiple_conditions(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.measure(q0, key='a'), cirq.measure(q0, key='b'), cirq.X(q1).with_classical_controls(sympy.Eq(sympy.Symbol('a'), 0), sympy.Eq(sympy.Symbol('b'), 0)), ) with pytest.raises(ValueError, match='QASM does not support multiple conditions'): _ = cirq.qasm(circuit)
def test_AT(self): before = format_from_qasm( os.path.join(rel, "pyvoqc/tests/test_qasm_files/tof_10.qasm")) with open("copy.qasm", "r") as f: c = f.read() before = circuit_from_qasm(c) #c.close() f = open( os.path.join(rel, "pyvoqc/tests/test_qasm_files/optim_tof_10.qasm")) t = f.read() f.close() after = circuit_from_qasm(t) a = cirq.qasm(after) after = circuit_from_qasm(a) run = self.run_voqc(before) run = cirq.qasm(run) run = circuit_from_qasm(run) self.assertEqual(run, after)
def test_consistency_with_qasm_output(): a, b, c, d = [cirq.NamedQubit('q_{}'.format(i)) for i in range(4)] circuit1 = cirq.Circuit.from_ops( cirq.Rx(np.pi / 2).on(a), cirq.Ry(np.pi / 2).on(b), cirq.Rz(np.pi / 2).on(b), cirq.IdentityGate(1).on(c), cirq.circuits.qasm_output.QasmUGate(1.0, 2.0, 3.0).on(d), ) qasm1 = cirq.qasm(circuit1) circuit2 = cirq.contrib.qasm_import.qasm.QasmCircuitParser().parse(qasm1) ct.assert_same_circuits(circuit1, circuit2)
def test_qasm(): assert cirq.qasm(NoMethod(), default=None) is None assert cirq.qasm(NoMethod(), default=5) == 5 assert cirq.qasm(ReturnsText()) == 'text' with pytest.raises(TypeError, match='no _qasm_ method'): _ = cirq.qasm(NoMethod()) with pytest.raises(TypeError, match='returned NotImplemented or None'): _ = cirq.qasm(ReturnsNotImplemented()) assert cirq.qasm(ExpectsArgs(), args=cirq.QasmArgs()) == 'text' assert cirq.qasm(ExpectsArgsQubits(), args=cirq.QasmArgs(), qubits=()) == 'text'
def test_qasm(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit(cirq.measure(q0, key='a'), cirq.X(q1).with_classical_controls('a')) qasm = cirq.qasm(circuit) assert (qasm == """// Generated from Cirq v0.15.0.dev OPENQASM 2.0; include "qelib1.inc"; // Qubits: [q(0), q(1)] qreg q[2]; creg m_a[1]; measure q[0] -> m_a[0]; if (m_a!=0) x q[1]; """)
def test_qasm_no_conditions(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit(cirq.measure(q0, key='a'), cirq.ClassicallyControlledOperation(cirq.X(q1), [])) qasm = cirq.qasm(circuit) assert (qasm == f"""// Generated from Cirq v{cirq.__version__} OPENQASM 2.0; include "qelib1.inc"; // Qubits: [q(0), q(1)] qreg q[2]; creg m_a[1]; measure q[0] -> m_a[0]; x q[1]; """)
def test_classical_control(): qasm = """OPENQASM 2.0; qreg q[2]; creg a[1]; measure q[0] -> a[0]; if (a==1) CX q[0],q[1]; """ parser = QasmParser() q_0 = cirq.NamedQubit('q_0') q_1 = cirq.NamedQubit('q_1') expected_circuit = cirq.Circuit( cirq.measure(q_0, key='a_0'), cirq.CNOT(q_0, q_1).with_classical_controls(sympy.Eq(sympy.Symbol('a_0'), 1)), ) parsed_qasm = parser.parse(qasm) assert parsed_qasm.supportedFormat assert not parsed_qasm.qelib1Include ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit) assert parsed_qasm.qregs == {'q': 2} # Note this cannot *exactly* round-trip because the way QASM and Cirq handle measurements # into classical registers is different. Cirq parses QASM classical registers into m_a_i for i # in 0..bit_count. Thus the generated key has an extra "_0" at the end. expected_generated_qasm = f"""// Generated from Cirq v{cirq.__version__} OPENQASM 2.0; include "qelib1.inc"; // Qubits: [q_0, q_1] qreg q[2]; creg m_a_0[1]; measure q[0] -> m_a_0[0]; if (m_a_0==1) cx q[0],q[1]; """ assert cirq.qasm(parsed_qasm.circuit) == expected_generated_qasm
def test_qasm(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.measure(q0, key='a'), cirq.X(q1).with_classical_controls(sympy.Eq(sympy.Symbol('a'), 0)), ) qasm = cirq.qasm(circuit) assert (qasm == f"""// Generated from Cirq v{cirq.__version__} OPENQASM 2.0; include "qelib1.inc"; // Qubits: [q(0), q(1)] qreg q[2]; creg m_a[1]; measure q[0] -> m_a[0]; if (m_a==0) x q[1]; """)
def optimize_circuit(self, circuit: circuits.Circuit): #Write qasm file from circuit circuit = Circuit( decompose(circuit, intercepting_decomposer=decompose_library, keep=need_to_keep)) qasm_str = cirq.qasm(circuit) f = open("temp.qasm", "w") f.write(qasm_str) f.close() #Call VOQC optimizations from input list and go from rzq to rz t = self.function_call("temp.qasm") rzq_to_rz("temp2.qasm") #Get Cirq Circuit from qasm file with open("temp2.qasm", "r") as f: c = f.read() circ = circuit_from_qasm(c) #Remove temporary files os.remove("temp.qasm") os.remove("temp2.qasm") return circ
def test_no_symbolic_qasm_but_fails_gracefully(): q = cirq.NamedQubit('q') v = cirq.PhasedXPowGate(phase_exponent=sympy.Symbol('p')).on(q) assert cirq.qasm(v, args=cirq.QasmArgs(), default=None) is None
def test_tagged_operation_forwards_protocols(): """The results of all protocols applied to an operation with a tag should be equivalent to the result without tags. """ q1 = cirq.GridQubit(1, 1) q2 = cirq.GridQubit(1, 2) h = cirq.H(q1) tag = 'tag1' tagged_h = cirq.H(q1).with_tags(tag) np.testing.assert_equal(cirq.unitary(tagged_h), cirq.unitary(h)) assert cirq.has_unitary(tagged_h) assert cirq.decompose(tagged_h) == cirq.decompose(h) assert cirq.pauli_expansion(tagged_h) == cirq.pauli_expansion(h) assert cirq.equal_up_to_global_phase(h, tagged_h) assert np.isclose(cirq.channel(h), cirq.channel(tagged_h)).all() assert cirq.measurement_key(cirq.measure(q1, key='blah').with_tags(tag)) == 'blah' parameterized_op = cirq.XPowGate(exponent=sympy.Symbol('t'))(q1).with_tags(tag) assert cirq.is_parameterized(parameterized_op) resolver = cirq.study.ParamResolver({'t': 0.25}) assert cirq.resolve_parameters(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) assert cirq.resolve_parameters_once(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) y = cirq.Y(q1) tagged_y = cirq.Y(q1).with_tags(tag) assert tagged_y ** 0.5 == cirq.YPowGate(exponent=0.5)(q1) assert tagged_y * 2 == (y * 2) assert 3 * tagged_y == (3 * y) assert cirq.phase_by(y, 0.125, 0) == cirq.phase_by(tagged_y, 0.125, 0) controlled_y = tagged_y.controlled_by(q2) assert controlled_y.qubits == ( q2, q1, ) assert isinstance(controlled_y, cirq.Operation) assert not isinstance(controlled_y, cirq.TaggedOperation) clifford_x = cirq.SingleQubitCliffordGate.X(q1) tagged_x = cirq.SingleQubitCliffordGate.X(q1).with_tags(tag) assert cirq.commutes(clifford_x, clifford_x) assert cirq.commutes(tagged_x, clifford_x) assert cirq.commutes(clifford_x, tagged_x) assert cirq.commutes(tagged_x, tagged_x) assert cirq.trace_distance_bound(y ** 0.001) == cirq.trace_distance_bound( (y ** 0.001).with_tags(tag) ) flip = cirq.bit_flip(0.5)(q1) tagged_flip = cirq.bit_flip(0.5)(q1).with_tags(tag) assert cirq.has_mixture(tagged_flip) assert cirq.has_channel(tagged_flip) flip_mixture = cirq.mixture(flip) tagged_mixture = cirq.mixture(tagged_flip) assert len(tagged_mixture) == 2 assert len(tagged_mixture[0]) == 2 assert len(tagged_mixture[1]) == 2 assert tagged_mixture[0][0] == flip_mixture[0][0] assert np.isclose(tagged_mixture[0][1], flip_mixture[0][1]).all() assert tagged_mixture[1][0] == flip_mixture[1][0] assert np.isclose(tagged_mixture[1][1], flip_mixture[1][1]).all() qubit_map = {q1: 'q1'} qasm_args = cirq.QasmArgs(qubit_id_map=qubit_map) assert cirq.qasm(h, args=qasm_args) == cirq.qasm(tagged_h, args=qasm_args) cirq.testing.assert_has_consistent_apply_unitary(tagged_h)
def test_consistency_with_qasm_output(): circuit1 = cirq.Circuit() qasm1 = cirq.qasm(circuit1) circuit2 = cirq.contrib.qasm_import.qasm.QasmCircuitParser().parse(qasm1) cirq.testing.assert_same_circuits(circuit1, circuit2)
def test_qasm_consistency(theta): """ Tests the OpenQASM consistency for special cases of \theta. Ticket: https://github.com/quantumlib/Cirq/issues/3728 Note: Built for OpenQASM 2.0. Doesn't handle integer values for \theta (not applicable to issue). """ # handle integer case if isinstance(theta, int): return NotImplemented # normalize theta to be in [0,2π) theta = theta % 2 # create simple circuits test_circuits = [ cirq.Circuit((cirq.X ** theta)(cirq.NamedQubit("a"))), # X Gate cirq.Circuit((cirq.Y ** theta)(cirq.NamedQubit("a"))), # Y Gate cirq.Circuit((cirq.Z ** theta)(cirq.NamedQubit("a"))), # Z Gate cirq.Circuit((cirq.X ** -theta)(cirq.NamedQubit("a"))), # X Gate (-\theta) cirq.Circuit((cirq.Y ** -theta)(cirq.NamedQubit("a"))), # Y Gate (-\theta) cirq.Circuit((cirq.Z ** -theta)(cirq.NamedQubit("a"))), # Z Gate (-\theta) ] # create associated outputs (expected) test_qasm_outputs = [ """Qubits: [a] qreg q[1]; rx(pi*"""+str(theta)+""") q[0]; """, """Qubits: [a] qreg q[1]; ry(pi*"""+str(theta)+""") q[0]; """, """Qubits: [a] qreg q[1]; rz(pi*"""+str(theta)+""") q[0]; ""","""Qubits: [a] qreg q[1]; rx(pi*-"""+str(theta)+""") q[0]; ""","""Qubits: [a] qreg q[1]; ry(pi*-"""+str(theta)+""") q[0]; ""","""Qubits: [a] qreg q[1]; rz(pi*-"""+str(theta)+""") q[0]; """ ] # Test all the expected outputs equal their OpenQASM string generated by `cirq.qasm`. # Condensed via the `split` operator, which assumes OpenQASM 2.0 structure. assert all([cirq.qasm(circ).split('// ')[2] == expected_qasm_output for circ, expected_qasm_output in zip(test_circuits, test_qasm_outputs)])