def test_convert_to_sycamore_gates_swap_zz(): qubits = cirq.LineQubit.range(3) gamma = np.random.randn() circuit1 = cirq.Circuit(cirq.SWAP(qubits[0], qubits[1]), cirq.Z(qubits[2]), cirq.ZZ(qubits[0], qubits[1])**gamma, strategy=cirq.InsertStrategy.NEW) circuit2 = cirq.Circuit(cirq.ZZ(qubits[0], qubits[1])**gamma, cirq.Z(qubits[2]), cirq.SWAP(qubits[0], qubits[1]), strategy=cirq.InsertStrategy.NEW) compiled_circuit1 = circuit1.copy() cgoc.ConvertToSycamoreGates()(compiled_circuit1) compiled_circuit2 = circuit2.copy() cgoc.ConvertToSycamoreGates()(compiled_circuit2) cirq.testing.assert_same_circuits(compiled_circuit1, compiled_circuit2) assert len( list( compiled_circuit1.findall_operations_with_gate_type( cirq.google.SycamoreGate))) == 3 cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit1, compiled_circuit1, atol=1e-7)
def test_convert_to_sycamore_equivalent_unitaries(gate): qubits = [cirq.NamedQubit('a'), cirq.NamedQubit('b')] operation = gate.on(qubits[0], qubits[1]) converted = cgoc.ConvertToSycamoreGates().convert(operation) u1 = cirq.unitary(cirq.Circuit(converted)) u2 = cirq.unitary(operation) cirq.testing.assert_allclose_up_to_global_phase(u1, u2, atol=1e-8)
def test_convert_to_sycamore_gates_fsim(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.FSimGate(theta=np.pi / 2, phi=np.pi / 6)(q0, q1)) compiled_circuit = circuit.copy() cgoc.ConvertToSycamoreGates()(compiled_circuit) cirq.testing.assert_same_circuits(circuit, compiled_circuit)
def test_unsupported_gate(): class UnknownGate(cirq.TwoQubitGate): pass q0 = cirq.LineQubit(0) q1 = cirq.LineQubit(1) circuit = cirq.Circuit(UnknownGate()(q0, q1)) with pytest.raises(ValueError, match='Unrecognized gate: '): cgoc.ConvertToSycamoreGates().optimize_circuit(circuit)
def test_unsupported_phased_iswap(): """Tests that a Phased ISwap with a provided phase_exponent and exponent is not supported.""" q0 = cirq.LineQubit(0) q1 = cirq.LineQubit(1) circuit = cirq.Circuit( cirq.PhasedISwapPowGate(exponent=0.5, phase_exponent=.33)(q0, q1)) with pytest.raises(ValueError, match='phase_exponent of .25 OR an exponent of 1'): cgoc.ConvertToSycamoreGates().optimize_circuit(circuit)
def test_three_qubit_gate(): class ThreeQubitGate(cirq.ThreeQubitGate): pass q0 = cirq.LineQubit(0) q1 = cirq.LineQubit(1) q2 = cirq.LineQubit(2) circuit = cirq.Circuit(ThreeQubitGate()(q0, q1, q2)) with pytest.raises(TypeError): cgoc.ConvertToSycamoreGates().optimize_circuit(circuit)
def test_single_qubit_gate_phased_xz(): q = cirq.LineQubit(0) gate = cirq.PhasedXZGate(axis_phase_exponent=0.2, x_exponent=0.3, z_exponent=0.4) circuit = cirq.Circuit(gate(q)) converted_circuit = circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(converted_circuit) ops = list(converted_circuit.all_operations()) assert len(ops) == 1 assert ops[0].gate == gate
def test_single_qubit_gate(): q = cirq.LineQubit(0) mat = cirq.testing.random_unitary(2) gate = cirq.MatrixGate(mat, qid_shape=(2,)) circuit = cirq.Circuit(gate(q)) converted_circuit = circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(converted_circuit) for op in converted_circuit.all_operations(): gate = op.gate assert isinstance(gate, (cirq.PhasedXPowGate, cirq.ZPowGate)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8)
def test_zztheta_zzpow_unsorted_qubits(): qubits = cirq.LineQubit(1), cirq.LineQubit(0) exponent = 0.06366197723675814 expected_circuit = cirq.Circuit( cirq.ZZPowGate(exponent=exponent, global_shift=-0.5).on(qubits[0], qubits[1]),) actual_circuit = expected_circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(actual_circuit) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(expected_circuit), cirq.unitary(actual_circuit), atol=1e-7)
def test_convert_to_sycamore_tabulation(): # A tabulation for the sycamore gate with an infidelity of .1. sycamore_tabulation = gate_product_tabulation(cirq.unitary(cirq.google.SYC), .1, random_state=_rng) qubits = [cirq.NamedQubit('a'), cirq.NamedQubit('b')] operation = cirq.MatrixGate(cirq.unitary(cirq.CX), qid_shape=(2, 2)).on(qubits[0], qubits[1]) converted = cgoc.ConvertToSycamoreGates(sycamore_tabulation).convert( operation) u1 = cirq.unitary(cirq.Circuit(converted)) u2 = cirq.unitary(operation) overlap = abs(np.trace(u1.conj().T @ u2)) assert np.isclose(overlap, 4.0, .1)
def test_zztheta_qaoa_like(): qubits = cirq.LineQubit.range(4) for exponent in np.linspace(-1, 1, 10): cirq_circuit = cirq.Circuit([ cirq.H.on_each(qubits), cirq.ZZPowGate(exponent=exponent)(qubits[0], qubits[1]), cirq.ZZPowGate(exponent=exponent)(qubits[2], qubits[3]), cirq.rx(.123).on_each(qubits), ]) syc_circuit = cirq_circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(syc_circuit) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(cirq_circuit), cirq.unitary(syc_circuit), atol=1e-7)
def test_known_two_q_operations_to_sycamore_operations_cnot(): a, b = cirq.LineQubit.range(2) op = cirq.CNOT(a, b) decomposed = cirq.Circuit(cgoc.ConvertToSycamoreGates().convert(op)) # Should be equivalent. cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(op), cirq.unitary(decomposed), atol=1e-8) # Should have decomposed into two Sycamores. multi_qubit_ops = [ e for e in decomposed.all_operations() if len(e.qubits) > 1 ] assert len(multi_qubit_ops) == 2 assert all( isinstance(e.gate, cirq.google.SycamoreGate) for e in multi_qubit_ops)
def test_swap_zztheta(): """ Construct a Ising gate followed by a swap using a sycamore. """ qubits = cirq.LineQubit.range(2) a, b = qubits for theta in np.linspace(0, 2 * np.pi, 10): expected_circuit = cirq.Circuit( cirq.SWAP(a, b), cirq.ZZPowGate(exponent=2 * theta / np.pi, global_shift=-0.5).on(a, b)) expected_unitary = cirq.unitary(expected_circuit) actual_circuit = expected_circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(actual_circuit) actual_unitary = cirq.unitary(actual_circuit) cirq.testing.assert_allclose_up_to_global_phase(actual_unitary, expected_unitary, atol=1e-7)
def test_non_gate_operation(): class UnknownOperation(cirq.Operation): def __init__(self, qubits): self._qubits = qubits @property def qubits(self): return self._qubits def with_qubits(self, *new_qubits): # coverage: ignore return UnknownOperation(self._qubits) q0 = cirq.LineQubit(0) circuit = cirq.Circuit(UnknownOperation([q0])) converted_circuit = circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(converted_circuit) assert circuit == converted_circuit
def test_sycamore_invalid_tabulation(): # An object other than a tabulation. sycamore_tabulation = {} with pytest.raises(ValueError): cgoc.ConvertToSycamoreGates(sycamore_tabulation)