def test_cz_parameterize(): parameterized_gate = cg.Exp11Gate(half_turns=cirq.Symbol('a')) assert parameterized_gate.is_parameterized() assert cirq.unitary(parameterized_gate, None) is None resolver = cirq.ParamResolver({'a': 0.1}) resolved_gate = parameterized_gate.with_parameters_resolved_by(resolver) assert resolved_gate == cg.Exp11Gate(half_turns=0.1)
def test_can_add_operation_into_moment(): d = square_device(2, 2) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) q11 = cirq.GridQubit(1, 1) m = cirq.Moment([cg.Exp11Gate().on(q00, q01)]) assert not d.can_add_operation_into_moment(cg.Exp11Gate().on(q10, q11), m)
def test_cz_parameterize(): parameterized_gate = cg.Exp11Gate(half_turns=Symbol('a')) assert parameterized_gate.is_parameterized() with pytest.raises(ValueError): _ = parameterized_gate.matrix() resolver = ParamResolver({'a': 0.1}) resolved_gate = parameterized_gate.with_parameters_resolved_by(resolver) assert resolved_gate == cg.Exp11Gate(half_turns=0.1)
def test_validate_moment(): d = square_device(2, 2) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) q11 = cirq.GridQubit(1, 1) m = cirq.Moment([cg.Exp11Gate().on(q00, q01), cg.Exp11Gate().on(q10, q11)]) with pytest.raises(ValueError): d.validate_moment(m)
def test_validate_operation_adjacent_qubits(): d = square_device(3, 3) d.validate_operation(cirq.GateOperation( cg.Exp11Gate(), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)))) with pytest.raises(ValueError): d.validate_operation(cirq.GateOperation( cg.Exp11Gate(), (cirq.GridQubit(0, 0), cirq.GridQubit(2, 0))))
def test_crosses_czs(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') # Full CZ. assert_optimizes( before=quick_circuit( [cg.ExpWGate(axis_half_turns=0.25).on(a)], [cirq.CZ(a, b)], ), expected=quick_circuit( [cg.ExpZGate().on(b)], [cg.Exp11Gate().on(a, b)], [cg.ExpWGate(axis_half_turns=0.25).on(a)], )) assert_optimizes( before=quick_circuit( [cg.ExpWGate(axis_half_turns=0.125).on(a)], [cirq.CZ(b, a)], ), expected=quick_circuit( [cg.ExpZGate().on(b)], [cg.Exp11Gate().on(a, b)], [cg.ExpWGate(axis_half_turns=0.125).on(a)], )) # Partial CZ. assert_optimizes( before=quick_circuit( [cg.ExpWGate().on(a)], [cirq.CZ(a, b)**0.25], ), expected=quick_circuit( [cg.ExpZGate(half_turns=0.25).on(b)], [cg.Exp11Gate(half_turns=-0.25).on(a, b)], [cg.ExpWGate().on(a)], )) # Double cross. assert_optimizes( before=quick_circuit( [cg.ExpWGate(axis_half_turns=0.125).on(a)], [cg.ExpWGate(axis_half_turns=0.375).on(b)], [cirq.CZ(a, b)**0.25], ), expected=quick_circuit( [], [], [cirq.CZ(a, b)**0.25], [cg.ExpWGate(axis_half_turns=0.25).on(a), cg.ExpWGate(axis_half_turns=0.5).on(b)], ))
def test_cz_eq(): eq = cirq.testing.EqualsTester() eq.make_equality_group(lambda: cg.Exp11Gate(half_turns=0)) eq.add_equality_group(cg.Exp11Gate(), cg.Exp11Gate(half_turns=1), cg.Exp11Gate(degs=180), cg.Exp11Gate(rads=np.pi)) eq.make_equality_group(lambda: cg.Exp11Gate(half_turns=cirq.Symbol('a'))) eq.make_equality_group(lambda: cg.Exp11Gate(half_turns=cirq.Symbol('b'))) eq.add_equality_group(cg.Exp11Gate(half_turns=-1.5), cg.Exp11Gate(half_turns=6.5))
def test_adjacent_cz_get_split_apart(): before = cirq.Circuit([cirq.Moment([ cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))])]) after = cg.optimized_for_xmon(before, new_device=cg.Foxtail) assert after == cirq.Circuit([ cirq.Moment([ cg.Exp11Gate().on(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]), cirq.Moment([ cg.Exp11Gate().on(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))])], device=cg.Foxtail)
def test_expw_matrix(half_turns): if (version[0] == 0 and version[1] <= 3): nptest.assert_array_almost_equal(xmon_gates.Exp11Gate(half_turns=half_turns).matrix, google.Exp11Gate(half_turns=half_turns).matrix()) else: nptest.assert_array_almost_equal(xmon_gates.Exp11Gate(half_turns=half_turns).matrix, unitary(ops.CZPowGate(exponent=half_turns)))
def test_validate_operation_existing_qubits(): d = square_device(3, 3, holes=[cirq.GridQubit(1, 1)]) d.validate_operation(cirq.GateOperation( cg.Exp11Gate(), (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)))) d.validate_operation(cg.ExpZGate().on(cirq.GridQubit(0, 0))) with pytest.raises(ValueError): d.validate_operation( cg.Exp11Gate().on(cirq.GridQubit(0, 0), cirq.GridQubit(-1, 0))) with pytest.raises(ValueError): d.validate_operation(cg.ExpZGate().on(cirq.GridQubit(-1, 0))) with pytest.raises(ValueError): d.validate_operation( cg.Exp11Gate().on(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)))
def test_param_resolver_exp_11_half_turns(): exp_11 = cg.Exp11Gate(half_turns=cirq.Symbol('a')) circuit = cirq.Circuit() circuit.append(exp_11(Q1, Q2)) resolver = cirq.ParamResolver({'a': 0.5}) result = compute_gate(circuit, resolver, num_qubits=2) # Slight hack: doesn't depend on order of qubits. np.testing.assert_almost_equal( result, np.diag([1, 1, 1, cmath.exp(1j * math.pi * 0.5)]))
def test_handedness_of_xmon_exp_11_gate(): circuit = cirq.Circuit.from_ops(cirq.H(Q1), cirq.H(Q2), cg.Exp11Gate(half_turns=0.5).on(Q1, Q2)) simulator = cg.XmonSimulator() result = list(simulator.simulate_moment_steps(circuit))[-1] print(np.round(result.state(), 3)) cirq.testing.assert_allclose_up_to_global_phase(result.state(), np.array([1, 1, 1, 1j]) / 2, atol=1e-7)
def test_invalid_to_proto_dict_qubit_number(): with pytest.raises(ValueError): cg.Exp11Gate(half_turns=0.5).to_proto_dict(cirq.GridQubit(2, 3)) with pytest.raises(ValueError): cg.ExpZGate(half_turns=0.5).to_proto_dict(cirq.GridQubit(2, 3), cirq.GridQubit(3, 4)) with pytest.raises(ValueError): cg.ExpWGate(half_turns=0.5, axis_half_turns=0).to_proto_dict(cirq.GridQubit(2, 3), cirq.GridQubit(3, 4))
def basic_circuit(): sqrt_x = cg.ExpWGate(half_turns=-0.5, axis_half_turns=0.0) z = cg.ExpZGate() cz = cg.Exp11Gate() circuit = cirq.Circuit() circuit.append( [sqrt_x(Q1), sqrt_x(Q2), cz(Q1, Q2), sqrt_x(Q1), sqrt_x(Q2), z(Q1)]) return circuit
def test_blocked_by_unknown_and_symbols(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') assert_optimizes( before=quick_circuit( [cg.ExpWGate().on(a)], [cirq.SWAP(a, b)], [cg.ExpWGate().on(a)], ), expected=quick_circuit( [cg.ExpWGate().on(a)], [cirq.SWAP(a, b)], [cg.ExpWGate().on(a)], )) assert_optimizes( before=quick_circuit( [cg.ExpWGate().on(a)], [cg.ExpZGate(half_turns=cirq.Symbol('z')).on(a)], [cg.ExpWGate().on(a)], ), expected=quick_circuit( [cg.ExpWGate().on(a)], [cg.ExpZGate(half_turns=cirq.Symbol('z')).on(a)], [cg.ExpWGate().on(a)], ), compare_unitaries=False) assert_optimizes( before=quick_circuit( [cg.ExpWGate().on(a)], [cg.Exp11Gate(half_turns=cirq.Symbol('z')).on(a, b)], [cg.ExpWGate().on(a)], ), expected=quick_circuit( [cg.ExpWGate().on(a)], [cg.Exp11Gate(half_turns=cirq.Symbol('z')).on(a, b)], [cg.ExpWGate().on(a)], ), compare_unitaries=False)
def test_validate_scheduled_operation_adjacent_exp_11_exp_z(): d = square_device(3, 3, holes=[cirq.GridQubit(1, 1)]) q0 = cirq.GridQubit(0, 0) q1 = cirq.GridQubit(1, 0) q2 = cirq.GridQubit(2, 0) s = cirq.Schedule(d, [ cirq.ScheduledOperation.op_at_on( cg.ExpZGate().on(q0), cirq.Timestamp(), d), cirq.ScheduledOperation.op_at_on( cg.Exp11Gate().on(q1, q2), cirq.Timestamp(), d), ]) d.validate_schedule(s)
def test_validate_scheduled_operation_not_adjacent_exp_11_exp_w(): d = square_device(3, 3, holes=[cirq.GridQubit(1, 1)]) q0 = cirq.GridQubit(0, 0) p1 = cirq.GridQubit(1, 2) p2 = cirq.GridQubit(2, 2) s = cirq.Schedule(d, [ cirq.ScheduledOperation.op_at_on( cg.ExpWGate().on(q0), cirq.Timestamp(), d), cirq.ScheduledOperation.op_at_on( cg.Exp11Gate().on(p1, p2), cirq.Timestamp(), d), ]) d.validate_schedule(s)
def test_remap_qubits(): before = cirq.Circuit([cirq.Moment([ cirq.CZ(cirq.LineQubit(0), cirq.LineQubit(1))])]) after = cg.optimized_for_xmon(before, new_device=cg.Foxtail, qubit_map=lambda q: cirq.GridQubit(q.x, 0)) assert after == cirq.Circuit([ cirq.Moment([ cg.Exp11Gate().on(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))])], device=cg.Foxtail)
def large_circuit(): np.random.seed(0) qubits = [cirq.GridQubit(i, 0) for i in range(10)] sqrt_x = cg.ExpWGate(half_turns=0.5, axis_half_turns=0.0) cz = cg.Exp11Gate() circuit = cirq.Circuit() for _ in range(11): circuit.append( [sqrt_x(qubit) for qubit in qubits if np.random.random() < 0.5]) circuit.append([cz(qubits[i], qubits[i + 1]) for i in range(9)]) circuit.append([cg.XmonMeasurementGate(key='meas')(*qubits)]) return circuit
def _make_cz_layer(device: cg.XmonDevice, layer_index: int) -> Iterable[cirq.Operation]: """ Each layer index corresponds to a shift/transpose of this CZ pattern: ●───● ● ● ●───● ● ● . . . ● ● ●───● ● ● ●───● . . . ●───● ● ● ●───● ● ● . . . ● ● ●───● ● ● ●───● . . . ●───● ● ● ●───● ● ● . . . ● ● ●───● ● ● ●───● . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Labelled edges, showing the exact index-to-CZs mapping (mod 8): ●─0─●─2─●─4─●─6─●─0─. . . 1│ 5│ 1│ 5│ 1│ ●─4─●─6─●─0─●─2─●─4─. . . 3│ 7│ 3│ 7│ 3│ ●─0─●─2─●─4─●─6─●─0─. . . 5│ 1│ 5│ 1│ 5│ ●─4─●─6─●─0─●─2─●─4─. . . 7│ 3│ 7│ 3│ 7│ ●─0─●─2─●─4─●─6─●─0─. . . 1│ 5│ 1│ 5│ 1│ . . . . . . . . . . . . . . . . . . Note that, for small devices, some layers will be empty because the layer only contains edges not present on the device. """ dir_row = layer_index % 2 dir_col = 1 - dir_row shift = (layer_index >> 1) % 4 for q in device.qubits: q2 = cirq.GridQubit(q.row + dir_row, q.col + dir_col) if q2 not in device.qubits: continue # This edge isn't on the device. if (q.row * (2 - dir_row) + q.col * (2 - dir_col)) % 4 != shift: continue # No CZ along this edge for this layer. yield cg.Exp11Gate().on(q, q2)
def test_cz_proto_dict_convert(): gate = cg.Exp11Gate(half_turns=cirq.Symbol('k')) proto_dict = { 'exp_11': { 'target1': { 'row': 2, 'col': 3 }, 'target2': { 'row': 3, 'col': 4 }, 'half_turns': { 'parameter_key': 'k' } } } assert_proto_dict_convert(cg.Exp11Gate, gate, proto_dict, cirq.GridQubit(2, 3), cirq.GridQubit(3, 4)) gate = cg.Exp11Gate(half_turns=0.5) proto_dict = { 'exp_11': { 'target1': { 'row': 2, 'col': 3 }, 'target2': { 'row': 3, 'col': 4 }, 'half_turns': { 'raw': 0.5 } } } assert_proto_dict_convert(cg.Exp11Gate, gate, proto_dict, cirq.GridQubit(2, 3), cirq.GridQubit(3, 4))
def test_cirq_symbol_diagrams(): q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) c = cirq.Circuit.from_ops( cg.ExpWGate(axis_half_turns=cirq.Symbol('a'), half_turns=cirq.Symbol('b')).on(q00), cg.ExpZGate(half_turns=cirq.Symbol('c')).on(q01), cg.Exp11Gate(half_turns=cirq.Symbol('d')).on(q00, q01), ) assert c.to_text_diagram() == """ (0, 0): ───W(a)^b───@───── │ (0, 1): ───Z^c──────@^d─── """.strip()
def test_not_decompose_partial_czs(): circuit = cirq.Circuit.from_ops( cg.Exp11Gate(half_turns=0.1)(*cirq.LineQubit.range(2)), ) optimizer = cg.MergeInteractions(allow_partial_czs=True) optimizer.optimize_circuit(circuit) cz_gates = [op.gate for op in circuit.all_operations() if cg.XmonGate.is_xmon_op(op) and isinstance(op.gate, cg.Exp11Gate)] num_full_cz = sum(1 for cz in cz_gates if cz.half_turns == 1) num_part_cz = sum(1 for cz in cz_gates if cz.half_turns != 1) assert num_full_cz == 0 assert num_part_cz == 1
def test_init(): d = square_device(2, 2, holes=[cirq.GridQubit(1, 1)]) ns = cirq.Duration(nanos=1) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) assert d.qubits == {q00, q01, q10} assert d.duration_of(cg.ExpZGate().on(q00)) == 0 * ns assert d.duration_of(cirq.measure(q00)) == ns assert d.duration_of(cirq.measure(q00, q01)) == ns assert d.duration_of(cg.ExpWGate().on(q00)) == 2 * ns assert d.duration_of(cg.Exp11Gate().on(q00, q01)) == 3 * ns with pytest.raises(ValueError): _ = d.duration_of(cirq.Gate().on(q00))
def test_cz_to_proto(): assert proto_matches_text( cg.Exp11Gate(half_turns=Symbol('k')).to_proto(GridQubit(2, 3), GridQubit(4, 5)), """ exp_11 { target1 { row: 2 col: 3 } target2 { row: 4 col: 5 } half_turns { parameter_key: "k" } } """) assert proto_matches_text( cg.Exp11Gate(half_turns=0.5).to_proto(GridQubit(2, 3), GridQubit(4, 5)), """ exp_11 { target1 { row: 2 col: 3 } target2 { row: 4 col: 5 } half_turns { raw: 0.5 } } """)
def test_cz_potential_implementation(): assert not cirq.can_cast(cirq.KnownMatrix, cg.Exp11Gate(half_turns=Symbol('a'))) assert cirq.can_cast(cirq.KnownMatrix, cg.Exp11Gate())
)) def test_optimizes_single_iswap(): a, b = cirq.LineQubit.range(2) c = cirq.Circuit.from_ops(cirq.ISWAP(a, b)) assert_optimization_not_broken(c) cg.MergeInteractions().optimize_circuit(c) assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2 assert all(cg.XmonGate.is_xmon_op(op) for op in c.all_operations()) @pytest.mark.parametrize('circuit', ( cirq.Circuit.from_ops( cg.Exp11Gate(half_turns=0.1)(*cirq.LineQubit.range(2)), ), cirq.Circuit.from_ops( cg.Exp11Gate(half_turns=0.2)(*cirq.LineQubit.range(2)), cg.Exp11Gate(half_turns=0.3)(*cirq.LineQubit.range(2)), ))) def test_decompose_partial_czs(circuit): optimizer = cg.MergeInteractions(allow_partial_czs=False) optimizer.optimize_circuit(circuit) cz_gates = [op.gate for op in circuit.all_operations() if cg.XmonGate.is_xmon_op(op) and isinstance(op.gate, cg.Exp11Gate)] num_full_cz = sum(1 for cz in cz_gates if cz.half_turns == 1) num_part_cz = sum(1 for cz in cz_gates if cz.half_turns != 1) assert num_full_cz == 2
def test_cz_potential_implementation(): assert cirq.unitary(cg.Exp11Gate(half_turns=cirq.Symbol('a')), None) is None assert cirq.unitary(cg.Exp11Gate()) is not None
def test_cz_repr(): gate = cg.Exp11Gate(half_turns=0.1) assert repr(gate) == 'Exp11Gate(half_turns=0.1)'