def test_no_touch_single_sqrt_iswap(): a, b = cirq.LineQubit.range(2) assert_optimizes( before=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag')]), ]), expected=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag')]), ]), )
def test_works_with_tags(): a, b = cirq.LineQubit.range(2) assert_optimizes( before=cirq.Circuit([ cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag1')]), cirq.Moment([cirq.SQRT_ISWAP(a, b).with_tags('mytag2')]), cirq.Moment([cirq.SQRT_ISWAP_INV(a, b).with_tags('mytag3')]), ]), expected=cirq.Circuit([cirq.Moment([cirq.SQRT_ISWAP(a, b)])]), )
def test_incremental_simulate(multiprocess): q0, q1 = cirq.LineQubit.range(2) circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=100, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), ) for _ in range(20) ] cycle_depths = np.arange(3, 100, 9) if multiprocess: pool = multiprocessing.Pool() else: pool = None start = time.perf_counter() df_ref = _ref_simulate_2q_xeb_circuits( circuits=circuits, cycle_depths=cycle_depths, pool=pool, ) end1 = time.perf_counter() df = simulate_2q_xeb_circuits(circuits=circuits, cycle_depths=cycle_depths, pool=pool) end2 = time.perf_counter() if pool is not None: pool.terminate() print("\nnew:", end2 - end1, "old:", end1 - start) pd.testing.assert_frame_equal(df_ref, df)
def _get_random_circuit(qubits, *, n_moments=10, random_state=52): return cirq.experiments.random_rotations_between_grid_interaction_layers_circuit( qubits=qubits, depth=n_moments, seed=random_state, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), ) + cirq.measure(*qubits, key='z')
def test_simulate_2q_xeb_circuits(): q0, q1 = cirq.LineQubit.range(2) circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=50, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), ) for _ in range(2) ] cycle_depths = np.arange(3, 50, 9) df = simulate_2q_xeb_circuits( circuits=circuits, cycle_depths=cycle_depths, ) assert len(df) == len(cycle_depths) * len(circuits) for (circuit_i, cycle_depth), row in df.iterrows(): assert 0 <= circuit_i < len(circuits) assert cycle_depth in cycle_depths assert len(row['pure_probs']) == 4 assert np.isclose(np.sum(row['pure_probs']), 1) with multiprocessing.Pool() as pool: df2 = simulate_2q_xeb_circuits(circuits, cycle_depths, pool=pool) pd.testing.assert_frame_equal(df, df2)
def cphase_symbols_to_sqrt_iswap(a, b, turns): """Version of cphase_to_sqrt_iswap that works with symbols. Note that the formulae contained below will need to be flattened into a sweep before serializing. """ theta = sympy.Mod(turns, 2.0) * sympy.pi # -1 if theta > pi. Adds a hacky fudge factor so theta=pi is not 0 sign = sympy.sign(sympy.pi - theta + 1e-9) # For sign = 1: theta. For sign = -1, 2pi-theta theta_prime = (sympy.pi - sign * sympy.pi) + sign * theta phi = sympy.asin(np.sqrt(2) * sympy.sin(theta_prime / 4)) xi = sympy.atan(sympy.tan(phi) / np.sqrt(2)) yield cirq.rz(sign * 0.5 * theta_prime).on(a) yield cirq.rz(sign * 0.5 * theta_prime).on(b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(-sign * 0.5) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.rx(-2 * phi).on(a) yield cirq.SQRT_ISWAP(a, b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(sign * 0.5)
def test_sample_2q_xeb_circuits(): q0 = cirq.NamedQubit('a') q1 = cirq.NamedQubit('b') circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=20, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), ) for _ in range(2) ] cycle_depths = np.arange(3, 20, 6) df = sample_2q_xeb_circuits( sampler=cirq.Simulator(), circuits=circuits, cycle_depths=cycle_depths, shuffle=np.random.RandomState(10), ) assert len(df) == len(cycle_depths) * len(circuits) for (circuit_i, cycle_depth), row in df.iterrows(): assert 0 <= circuit_i < len(circuits) assert cycle_depth in cycle_depths assert len(row['sampled_probs']) == 4 assert np.isclose(np.sum(row['sampled_probs']), 1)
def test_simplifies_sqrt_iswap(): a, b = cirq.LineQubit.range(2) assert_optimizes( before=cirq.Circuit([ # SQRT_ISWAP**8 == Identity cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), cirq.Moment([cirq.SQRT_ISWAP(a, b)]), ]), expected=cirq.Circuit([cirq.Moment([cirq.SQRT_ISWAP(a, b)])]), )
def rewriter_replace_with_decomp(op: 'cirq.CircuitOperation') -> 'cirq.OP_TREE': nonlocal component_id component_id = component_id + 1 tag = f'{component_id}' if len(op.qubits) == 1: return [cirq.T(op.qubits[0]).with_tags(tag)] one_layer = [op.with_tags(tag) for op in cirq.T.on_each(*op.qubits)] two_layer = [cirq.SQRT_ISWAP(*op.qubits).with_tags(tag)] return [one_layer, two_layer, one_layer]
def swap_to_sqrt_iswap(a, b, turns): """Implement the evolution of a hopping term using two sqrt_iswap gates and single qubit gates. Output unitary: [[1, 0, 0, 0], [0, g·c, -i·g·s, 0], [0, -i·g·s, g·c, 0], [0, 0, 0, 1]] where c = cos(theta) and s = sin(theta). Args: a: the first qubit b: the second qubit turns: The rotational angle that specifies the gate, where c = cos(π·t/2), s = sin(π·t/2), g = exp(i·π·t/2). Yields: A `cirq.OP_TREE` representing the decomposition. """ if not isinstance(turns, sympy.Basic) and _near_mod_n(turns, 1.0, 2): # Decomposition for cirq.SWAP yield cirq.Y(a)**0.5 yield cirq.Y(b)**0.5 yield cirq.SQRT_ISWAP(a, b) yield cirq.Y(a)**-0.5 yield cirq.Y(b)**-0.5 yield cirq.SQRT_ISWAP(a, b) yield cirq.X(a)**-0.5 yield cirq.X(b)**-0.5 yield cirq.SQRT_ISWAP(a, b) yield cirq.X(a)**0.5 yield cirq.X(b)**0.5 return yield cirq.Z(a)**1.25 yield cirq.Z(b)**-0.25 yield cirq.ISWAP(a, b)**-0.5 yield cirq.Z(a)**(-turns / 2 + 1) yield cirq.Z(b)**(turns / 2) yield cirq.ISWAP(a, b)**-0.5 yield cirq.Z(a)**(turns / 2 - 0.25) yield cirq.Z(b)**(turns / 2 + 0.25) yield cirq.CZ.on(a, b)**(-turns)
def test_simulate_circuit_length_validation(): q0, q1 = cirq.LineQubit.range(2) circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=10, # not long enough! two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), ) for _ in range(2) ] cycle_depths = np.arange(3, 50, 9) with pytest.raises(ValueError, match='.*not long enough.*'): _ = simulate_2q_xeb_circuits(circuits=circuits, cycle_depths=cycle_depths)
def test_random_device_placer_small_device(): topo = cirq.TiltedSquareLattice(3, 3) qubits = sorted(topo.nodes_to_gridqubits().values()) circuit = cirq.experiments.random_rotations_between_grid_interaction_layers_circuit( qubits, depth=8, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b) ) qp = cg.RandomDevicePlacer() with pytest.raises(cg.CouldNotPlaceError): qp.place_circuit( circuit, problem_topology=topo, shared_rt_info=cg.SharedRuntimeInfo(run_id='1', device=cg.Foxtail), rs=np.random.RandomState(1), )
def circuits_cycle_depths_sampled_df(): q0, q1 = cirq.LineQubit.range(2) circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=50, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), seed=52) for _ in range(2) ] cycle_depths = np.arange(10, 40 + 1, 10) sampled_df = sample_2q_xeb_circuits(sampler=cirq.Simulator(seed=53), circuits=circuits, cycle_depths=cycle_depths) return circuits, cycle_depths, sampled_df
def test_characterize_phased_fsim_parameters_with_xeb(): q0, q1 = cirq.LineQubit.range(2) rs = np.random.RandomState(52) circuits = [ rqcg.random_rotations_between_two_qubit_circuit( q0, q1, depth=20, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b), seed=rs, ) for _ in range(2) ] cycle_depths = np.arange(3, 20, 6) sampled_df = sample_2q_xeb_circuits( sampler=cirq.Simulator(seed=rs), circuits=circuits, cycle_depths=cycle_depths, progress_bar=None, ) # only optimize theta so it goes faster. options = SqrtISwapXEBOptions( characterize_theta=True, characterize_gamma=False, characterize_chi=False, characterize_zeta=False, characterize_phi=False, ) p_circuits = [ parameterize_circuit(circuit, options) for circuit in circuits ] with multiprocessing.Pool() as pool: result = characterize_phased_fsim_parameters_with_xeb( sampled_df=sampled_df, parameterized_circuits=p_circuits, cycle_depths=cycle_depths, options=options, # speed up with looser tolerances: fatol=1e-2, xatol=1e-2, pool=pool, ) opt_res = result.optimization_results[(q0, q1)] assert np.abs(opt_res.x[0] + np.pi / 4) < 0.1 assert np.abs(opt_res.fun) < 0.1 # noiseless simulator assert len(result.fidelities_df) == len(cycle_depths) assert np.all(result.fidelities_df['fidelity'] > 0.95)
def cphase_to_sqrt_iswap(a, b, turns): """Implement a C-Phase gate using two sqrt ISWAP gates and single-qubit operations. The circuit is equivalent to cirq.CZPowGate(exponent=turns). Output unitary: [1 0 0 0], [0 1 0 0], [0 0 1 0], [0 0 0 e^{i turns pi}]. Args: a: the first qubit b: the second qubit turns: Exponent specifying the evolution time in number of rotations. """ theta = (turns % 2) * np.pi if 0 <= theta <= np.pi: sign = 1.0 theta_prime = theta elif np.pi < theta < 2 * np.pi: sign = -1.0 theta_prime = 2 * np.pi - theta if np.isclose(theta, np.pi): # If we are close to pi, just set values manually to avoid possible # numerical errors with arcsin of greater than 1.0 (Ahem, Windows). phi = np.pi / 2 xi = np.pi / 2 else: phi = np.arcsin(np.sqrt(2) * np.sin(theta_prime / 4)) xi = np.arctan(np.tan(phi) / np.sqrt(2)) yield cirq.rz(sign * 0.5 * theta_prime).on(a) yield cirq.rz(sign * 0.5 * theta_prime).on(b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(-sign * 0.5) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.rx(-2 * phi).on(a) yield cirq.SQRT_ISWAP(a, b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(sign * 0.5) # Corrects global phase yield cirq.global_phase_operation(np.exp(sign * theta_prime * 0.25j))
def test_device_missing_metadata(): class BadDevice(cirq.Device): pass topo = cirq.TiltedSquareLattice(3, 3) qubits = sorted(topo.nodes_to_gridqubits().values()) circuit = cirq.experiments.random_rotations_between_grid_interaction_layers_circuit( qubits, depth=8, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b)) qp = cg.RandomDevicePlacer() with pytest.raises(ValueError): qp.place_circuit( circuit, problem_topology=topo, shared_rt_info=cg.SharedRuntimeInfo(run_id='1', device=BadDevice()), rs=np.random.RandomState(1), )
def test_random_device_placer_tilted_square_lattice(): topo = cirq.TiltedSquareLattice(4, 2) qubits = sorted(topo.nodes_to_gridqubits().values()) circuit = cirq.experiments.random_rotations_between_grid_interaction_layers_circuit( qubits, depth=8, two_qubit_op_factory=lambda a, b, _: cirq.SQRT_ISWAP(a, b) ) assert not all(q in cg.Sycamore23.qubit_set() for q in circuit.all_qubits()) qp = cg.RandomDevicePlacer() circuit2, mapping = qp.place_circuit( circuit, problem_topology=topo, shared_rt_info=cg.SharedRuntimeInfo(run_id='1', device=cg.Sycamore23), rs=np.random.RandomState(1), ) assert circuit is not circuit2 assert circuit != circuit2 assert all(q in cg.Sycamore23.qubit_set() for q in circuit2.all_qubits()) for k, v in mapping.items(): assert k != v