Example #1
0
def test_two_qubit_gates_with_symbols(gate: cirq.Gate, expected_length: int):
    """Tests that the gates with symbols decompose without error into a
    circuit that has an equivalent unitary form.
    """
    q0 = cirq.GridQubit(5, 3)
    q1 = cirq.GridQubit(5, 4)
    original_circuit = cirq.Circuit(gate(q0, q1))
    converted_circuit = original_circuit.copy()
    with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset",
                                        deadline='v1.0'):
        cgoc.ConvertToSqrtIswapGates().optimize_circuit(converted_circuit)
    converted_circuit_iswap_inv = cirq.optimize_for_target_gateset(
        original_circuit,
        gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True))
    converted_circuit_iswap = cirq.optimize_for_target_gateset(
        original_circuit, gateset=cirq.SqrtIswapTargetGateset())
    assert len(converted_circuit) <= expected_length
    assert (len(converted_circuit_iswap) <= expected_length
            or len(converted_circuit_iswap_inv) <= expected_length)

    # Check if unitaries are the same
    for val in np.linspace(0, 2 * np.pi, 12):
        assert _unitaries_allclose(
            cirq.resolve_parameters(original_circuit, {'t': val}),
            cirq.resolve_parameters(converted_circuit, {'t': val}),
        )
        assert _unitaries_allclose(
            cirq.resolve_parameters(original_circuit, {'t': val}),
            cirq.resolve_parameters(converted_circuit_iswap, {'t': val}),
        )
        assert _unitaries_allclose(
            cirq.resolve_parameters(original_circuit, {'t': val}),
            cirq.resolve_parameters(converted_circuit_iswap_inv, {'t': val}),
        )
Example #2
0
def test_givens_rotation():
    """Test if the sqrt_iswap synthesis for a givens rotation is correct"""
    thetas = np.linspace(0, 2 * np.pi, 100)
    qubits = [cirq.NamedQubit('a'), cirq.NamedQubit('b')]
    for theta in thetas:
        program = cirq.Circuit(cirq.givens(theta).on(qubits[0], qubits[1]))
        unitary = cirq.unitary(program)
        test_program = program.copy()
        with cirq.testing.assert_deprecated(
                "Use cirq.optimize_for_target_gateset", deadline='v1.0'):
            cgoc.ConvertToSqrtIswapGates().optimize_circuit(test_program)
        converted_circuit_iswap_inv = cirq.optimize_for_target_gateset(
            test_program,
            gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True))
        converted_circuit_iswap = cirq.optimize_for_target_gateset(
            test_program, gateset=cirq.SqrtIswapTargetGateset())
        for circuit in [
                test_program, converted_circuit_iswap_inv,
                converted_circuit_iswap
        ]:
            circuit.append(cirq.IdentityGate(2).on(*qubits))
            test_unitary = cirq.unitary(circuit)
            np.testing.assert_allclose(
                4,
                np.abs(
                    np.trace(
                        np.conjugate(np.transpose(test_unitary)) @ unitary)))
Example #3
0
def test_two_qubit_gates(gate: cirq.Gate, expected_length: int):
    """Tests that two qubit gates decompose to an equivalent and
    serializable circuit with the expected length (or less).
    """
    q0 = cirq.GridQubit(5, 3)
    q1 = cirq.GridQubit(5, 4)
    original_circuit = cirq.Circuit(gate(q0, q1))
    converted_circuit = original_circuit.copy()
    converted_circuit_iswap_inv = cirq.optimize_for_target_gateset(
        original_circuit,
        gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True))
    converted_circuit_iswap = cirq.optimize_for_target_gateset(
        original_circuit, gateset=cirq.SqrtIswapTargetGateset())
    with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset",
                                        deadline='v1.0'):
        cgoc.ConvertToSqrtIswapGates().optimize_circuit(converted_circuit)
    cig.SQRT_ISWAP_GATESET.serialize(converted_circuit)
    cig.SQRT_ISWAP_GATESET.serialize(converted_circuit_iswap)
    cig.SQRT_ISWAP_GATESET.serialize(converted_circuit_iswap_inv)
    assert len(converted_circuit) <= expected_length
    assert (len(converted_circuit_iswap) <= expected_length
            or len(converted_circuit_iswap_inv) <= expected_length)
    assert _unitaries_allclose(original_circuit, converted_circuit)
    assert _unitaries_allclose(original_circuit, converted_circuit_iswap)
    assert _unitaries_allclose(original_circuit, converted_circuit_iswap_inv)
def test_sqrt_iswap_gateset_eq():
    eq = cirq.testing.EqualsTester()
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(), cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=False)
    )
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6, required_sqrt_iswap_count=0, use_sqrt_iswap_inv=True)
    )
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6, required_sqrt_iswap_count=3, use_sqrt_iswap_inv=True)
    )
    eq.add_equality_group(cirq.SqrtIswapTargetGateset(additional_gates=[cirq.XPowGate]))
Example #5
0
def test_optimizes_single_inv_sqrt_iswap_require3():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b))
    assert_optimization_not_broken(c, required_sqrt_iswap_count=3)
    c = cirq.optimize_for_target_gateset(
        c, gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=3))
    assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3
Example #6
0
def test_optimizes_single_iswap_require0():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.CNOT(a, b), cirq.CNOT(a, b))  # Minimum 0 sqrt-iSWAP
    assert_optimization_not_broken(c, required_sqrt_iswap_count=0)
    c = cirq.optimize_for_target_gateset(
        c, gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=0))
    assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 0
Example #7
0
def test_optimizes_single_iswap():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.ISWAP(a, b))
    assert_optimization_not_broken(c)
    c = cirq.optimize_for_target_gateset(c,
                                         gateset=cirq.SqrtIswapTargetGateset())
    assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 2
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, **kwargs):
    cirq.testing.assert_same_circuits(
        cirq.optimize_for_target_gateset(
            before, gateset=cirq.SqrtIswapTargetGateset(**kwargs), ignore_failures=False
        ),
        expected,
    )
def test_two_qubit_gates_with_symbols(gate: cirq.Gate, use_sqrt_iswap_inv: bool):
    # Note that even though these gates are not natively supported by
    # `cirq.parameterized_2q_op_to_sqrt_iswap_operations`, the transformation succeeds because
    # `cirq.optimize_for_target_gateset` also relies on `cirq.decompose` as a fallback.

    c_orig = cirq.Circuit(gate(*cirq.LineQubit.range(2)))
    c_new = cirq.optimize_for_target_gateset(
        c_orig,
        gateset=cirq.SqrtIswapTargetGateset(
            use_sqrt_iswap_inv=use_sqrt_iswap_inv,
            additional_gates=[cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate],
        ),
        ignore_failures=False,
    )

    # Check that `c_new` only contains sqrt iswap as the 2q entangling gate.
    sqrt_iswap_gate = cirq.SQRT_ISWAP_INV if use_sqrt_iswap_inv else cirq.SQRT_ISWAP
    for op in c_new.all_operations():
        if cirq.num_qubits(op) == 2:
            assert op.gate == sqrt_iswap_gate

    # Check if unitaries are the same
    for val in np.linspace(0, 2 * np.pi, 10):
        cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
            cirq.resolve_parameters(c_orig, {'t': val}),
            cirq.resolve_parameters(c_new, {'t': val}),
            atol=1e-6,
        )
Example #10
0
def _build_compilation_target_gatesets(
    gateset: cirq.Gateset, ) -> Sequence[cirq.CompilationTargetGateset]:
    """Detects compilation target gatesets based on what gates are inside the gateset.

    If a device contains gates which yield multiple compilation target gatesets, the user can only
    choose one target gateset to compile to. For example, a device may contain both SYC and
    SQRT_ISWAP gates which yield two separate target gatesets, but a circuit can only be compiled to
    either SYC or SQRT_ISWAP for its two-qubit gates, not both.

    TODO(#5050) when cirq-google CompilationTargetGateset subclasses are implemented, mention that
    gates which are part of the gateset but not the compilation target gateset are untouched when
    compiled.
    """

    # TODO(#5050) Subclass core CompilationTargetGatesets in cirq-google.

    target_gatesets: List[cirq.CompilationTargetGateset] = []
    if cirq.CZ in gateset:
        target_gatesets.append(cirq.CZTargetGateset())
    if ops.SYC in gateset:
        target_gatesets.append(transformers.SycamoreTargetGateset())
    if cirq.SQRT_ISWAP in gateset:
        target_gatesets.append(
            cirq.SqrtIswapTargetGateset(
                use_sqrt_iswap_inv=cirq.SQRT_ISWAP_INV in gateset))

    return tuple(target_gatesets)
def test_optimizes_single_inv_sqrt_iswap():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.SQRT_ISWAP_INV(a, b))
    assert_optimization_not_broken(c)
    c = cirq.optimize_for_target_gateset(
        c, gateset=cirq.SqrtIswapTargetGateset(), ignore_failures=False
    )
    assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 1
def test_optimizes_single_iswap_require3():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.ISWAP(a, b))  # Minimum 2 sqrt-iSWAP but 3 possible
    assert_optimization_not_broken(c, required_sqrt_iswap_count=3)
    c = cirq.optimize_for_target_gateset(
        c, gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=3), ignore_failures=False
    )
    assert len([1 for op in c.all_operations() if len(op.qubits) == 2]) == 3
Example #13
0
def test_grid_device_from_proto():
    grid_qubits, spec = _create_device_spec_with_horizontal_couplings()

    device = cirq_google.GridDevice.from_proto(spec)

    assert len(device.metadata.qubit_set) == len(grid_qubits)
    assert device.metadata.qubit_set == frozenset(grid_qubits)
    assert all(
        frozenset((cirq.GridQubit(row, 0), cirq.GridQubit(row, 1))) in device.metadata.qubit_pairs
        for row in range(GRID_HEIGHT)
    )
    assert device.metadata.gateset == cirq.Gateset(
        cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]),
        cirq.ops.phased_x_z_gate.PhasedXZGate,
        cirq.ops.common_gates.XPowGate,
        cirq.ops.common_gates.YPowGate,
        cirq.ops.phased_x_gate.PhasedXPowGate,
        cirq.GateFamily(
            cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()]
        ),
        cirq.GateFamily(
            cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()]
        ),
        cirq_google.experimental.ops.coupler_pulse.CouplerPulse,
        cirq.ops.measurement_gate.MeasurementGate,
        cirq.ops.wait_gate.WaitGate,
    )
    assert tuple(device.metadata.compilation_target_gatesets) == (
        cirq.CZTargetGateset(),
        cirq_google.SycamoreTargetGateset(),
        cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True),
    )

    base_duration = cirq.Duration(picos=1_000)
    assert device.metadata.gate_durations == {
        cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]): base_duration * 0,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]): base_duration * 1,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]): base_duration * 2,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]): base_duration * 3,
        cirq.GateFamily(cirq.ops.phased_x_z_gate.PhasedXZGate): base_duration * 4,
        cirq.GateFamily(cirq.ops.common_gates.XPowGate): base_duration * 4,
        cirq.GateFamily(cirq.ops.common_gates.YPowGate): base_duration * 4,
        cirq.GateFamily(cirq.ops.phased_x_gate.PhasedXPowGate): base_duration * 4,
        cirq.GateFamily(
            cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()]
        ): base_duration
        * 5,
        cirq.GateFamily(
            cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()]
        ): base_duration
        * 6,
        cirq.GateFamily(cirq_google.experimental.ops.coupler_pulse.CouplerPulse): base_duration * 7,
        cirq.GateFamily(cirq.ops.measurement_gate.MeasurementGate): base_duration * 8,
        cirq.GateFamily(cirq.ops.wait_gate.WaitGate): base_duration * 9,
    }
Example #14
0
def assert_optimization_not_broken(
        circuit: cirq.Circuit,
        required_sqrt_iswap_count: Optional[int] = None):
    c_new = cirq.optimize_for_target_gateset(
        circuit,
        gateset=cirq.SqrtIswapTargetGateset(
            required_sqrt_iswap_count=required_sqrt_iswap_count),
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        circuit, c_new, atol=1e-6)
    c_new = cirq.optimize_for_target_gateset(
        circuit,
        gateset=cirq.SqrtIswapTargetGateset(
            use_sqrt_iswap_inv=True,
            required_sqrt_iswap_count=required_sqrt_iswap_count),
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        circuit, c_new, atol=1e-6)
Example #15
0
def test_optimizes_single_iswap_require0_raises():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.CNOT(a, b))  # Minimum 2 sqrt-iSWAP
    with pytest.raises(
            ValueError,
            match='cannot be decomposed into exactly 0 sqrt-iSWAP gates'):
        _ = cirq.optimize_for_target_gateset(
            c,
            gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=0))
def test_optimizes_single_iswap_require2_raises():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(cirq.SWAP(a, b))  # Minimum 3 sqrt-iSWAP
    with pytest.raises(ValueError, match='cannot be decomposed into exactly 2 sqrt-iSWAP gates'):
        c = cirq.optimize_for_target_gateset(
            c,
            gateset=cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=2),
            ignore_failures=False,
        )
def test_convert_to_sqrt_iswap_preserving_moment_structure():
    q = cirq.LineQubit.range(5)
    op = lambda q0, q1: cirq.H(q1).controlled_by(q0)
    c_orig = cirq.Circuit(
        cirq.Moment(cirq.X(q[2])),
        cirq.Moment(op(q[0], q[1]), op(q[2], q[3])),
        cirq.Moment(op(q[2], q[1]), op(q[4], q[3])),
        cirq.Moment(op(q[1], q[2]), op(q[3], q[4])),
        cirq.Moment(op(q[3], q[2]), op(q[1], q[0])),
        cirq.measure(*q[:2], key="m"),
        cirq.X(q[2]).with_classical_controls("m"),
        cirq.CZ(*q[3:]).with_classical_controls("m"),
    )
    # Classically controlled operations are not part of the gateset, so failures should be ignored
    # during compilation.
    c_new = cirq.optimize_for_target_gateset(
        c_orig, gateset=cirq.SqrtIswapTargetGateset(), ignore_failures=True
    )

    assert c_orig[-2:] == c_new[-2:]
    c_orig, c_new = c_orig[:-2], c_new[:-2]

    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c_orig, c_new, atol=1e-6)
    assert all(
        (
            all_gates_of_type(m, cirq.Gateset(cirq.PhasedXZGate))
            or all_gates_of_type(m, cirq.Gateset(cirq.SQRT_ISWAP))
        )
        for m in c_new
    )

    c_new = cirq.optimize_for_target_gateset(
        c_orig, gateset=cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True), ignore_failures=False
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c_orig, c_new, atol=1e-6)
    assert all(
        (
            all_gates_of_type(m, cirq.Gateset(cirq.PhasedXZGate))
            or all_gates_of_type(m, cirq.Gateset(cirq.SQRT_ISWAP_INV))
        )
        for m in c_new
    )
Example #18
0
    if tabulation is not None:
        # coverage: ignore
        raise ValueError("Gate tabulation not supported for xmon")
    return [
        convert_to_xmon_gates.ConvertToXmonGates().optimize_circuit,
    ]


_OPTIMIZER_TYPES = {
    'xmon': _get_xmon_optimizers,
    'xmon_partial_cz': _get_xmon_optimizers_part_cz,
}

_TARGET_GATESETS = {
    'sqrt_iswap':
    lambda atol, _: cirq.SqrtIswapTargetGateset(atol=atol),
    'sycamore':
    lambda atol, tabulation: sycamore_gateset.SycamoreTargetGateset(
        atol=atol, tabulation=tabulation),
    'xmon':
    lambda atol, _: cirq.CZTargetGateset(atol=atol),
    'xmon_partial_cz':
    lambda atol, _: cirq.CZTargetGateset(atol=atol, allow_partial_czs=True),
}


@lru_cache()
def _gate_product_tabulation_cached(
        optimizer_type: str,
        tabulation_resolution: float) -> cirq.TwoQubitGateTabulation:
    random_state = np.random.RandomState(51)
Example #19
0
def test_griddevice_metadata_equality():
    qubits = cirq.GridQubit.rect(2, 3)
    qubit_pairs = [(a, b) for a in qubits for b in qubits
                   if a != b and a.is_adjacent(b)]
    gateset = cirq.Gateset(cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate,
                           cirq.CZ, cirq.SQRT_ISWAP)
    duration = {
        cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=1),
        cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=3),
        cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=2),
        cirq.GateFamily(cirq.CZ): cirq.Duration(nanos=4),
        cirq.GateFamily(cirq.SQRT_ISWAP): cirq.Duration(nanos=5),
    }
    duration2 = {
        cirq.GateFamily(cirq.XPowGate): cirq.Duration(nanos=10),
        cirq.GateFamily(cirq.YPowGate): cirq.Duration(picos=13),
        cirq.GateFamily(cirq.ZPowGate): cirq.Duration(picos=12),
        cirq.GateFamily(cirq.CZ): cirq.Duration(nanos=14),
        cirq.GateFamily(cirq.SQRT_ISWAP): cirq.Duration(nanos=15),
    }
    isolated_qubits = [cirq.GridQubit(9, 9)]
    target_gatesets = [cirq.CZTargetGateset(), cirq.SqrtIswapTargetGateset()]
    metadata = cirq.GridDeviceMetadata(qubit_pairs,
                                       gateset,
                                       gate_durations=duration)
    metadata2 = cirq.GridDeviceMetadata(qubit_pairs[:2],
                                        gateset,
                                        gate_durations=duration)
    metadata3 = cirq.GridDeviceMetadata(qubit_pairs,
                                        gateset,
                                        gate_durations=None)
    metadata4 = cirq.GridDeviceMetadata(qubit_pairs,
                                        gateset,
                                        gate_durations=duration2)
    metadata5 = cirq.GridDeviceMetadata(reversed(qubit_pairs),
                                        gateset,
                                        gate_durations=duration)
    metadata6 = cirq.GridDeviceMetadata(qubit_pairs,
                                        gateset,
                                        gate_durations=duration,
                                        all_qubits=qubits + isolated_qubits)
    metadata7 = cirq.GridDeviceMetadata(
        qubit_pairs, gateset, compilation_target_gatesets=target_gatesets)
    metadata8 = cirq.GridDeviceMetadata(
        qubit_pairs,
        gateset,
        compilation_target_gatesets=target_gatesets[::-1])
    metadata9 = cirq.GridDeviceMetadata(
        qubit_pairs,
        gateset,
        compilation_target_gatesets=tuple(target_gatesets))
    metadata10 = cirq.GridDeviceMetadata(
        qubit_pairs, gateset, compilation_target_gatesets=set(target_gatesets))

    eq = cirq.testing.EqualsTester()
    eq.add_equality_group(metadata)
    eq.add_equality_group(metadata2)
    eq.add_equality_group(metadata3)
    eq.add_equality_group(metadata4)
    eq.add_equality_group(metadata6)
    eq.add_equality_group(metadata7, metadata8, metadata9, metadata10)

    assert metadata == metadata5
Example #20
0
def _create_device_spec_with_horizontal_couplings():
    # Qubit layout:
    #   x -- x
    #   x -- x
    #   x -- x
    #   x -- x
    #   x -- x

    grid_qubits = [
        cirq.GridQubit(i, j) for i in range(GRID_HEIGHT) for j in range(2)
    ]

    spec = v2.device_pb2.DeviceSpecification()

    spec.valid_qubits.extend([v2.qubit_to_proto_id(q) for q in grid_qubits])

    qubit_pairs = []
    grid_targets = spec.valid_targets.add()
    grid_targets.name = '2_qubit_targets'
    grid_targets.target_ordering = v2.device_pb2.TargetSet.SYMMETRIC
    for row in range(int(GRID_HEIGHT / 2)):
        qubit_pairs.append((cirq.GridQubit(row, 0), cirq.GridQubit(row, 1)))
    for row in range(int(GRID_HEIGHT / 2), GRID_HEIGHT):
        # Flip the qubit pair order for the second half of qubits
        # to verify GridDevice properly handles pair symmetry.
        qubit_pairs.append((cirq.GridQubit(row, 1), cirq.GridQubit(row, 0)))
    for pair in qubit_pairs:
        new_target = grid_targets.targets.add()
        new_target.ids.extend([v2.qubit_to_proto_id(q) for q in pair])

    gate_names = [
        'syc',
        'sqrt_iswap',
        'sqrt_iswap_inv',
        'cz',
        'phased_xz',
        'virtual_zpow',
        'physical_zpow',
        'coupler_pulse',
        'meas',
        'wait',
    ]
    gate_durations = [(n, i * 1000) for i, n in enumerate(gate_names)]
    for gate_name, duration in sorted(gate_durations):
        gate = spec.valid_gates.add()
        getattr(gate, gate_name).SetInParent()
        gate.gate_duration_picos = duration

    expected_gateset = cirq.Gateset(
        cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]),
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]),
        cirq.ops.phased_x_z_gate.PhasedXZGate,
        cirq.ops.common_gates.XPowGate,
        cirq.ops.common_gates.YPowGate,
        cirq.ops.phased_x_gate.PhasedXPowGate,
        cirq.GateFamily(cirq.ops.common_gates.ZPowGate,
                        tags_to_ignore=[cirq_google.PhysicalZTag()]),
        cirq.GateFamily(cirq.ops.common_gates.ZPowGate,
                        tags_to_accept=[cirq_google.PhysicalZTag()]),
        cirq_google.experimental.ops.coupler_pulse.CouplerPulse,
        cirq.ops.measurement_gate.MeasurementGate,
        cirq.ops.wait_gate.WaitGate,
    )

    base_duration = cirq.Duration(picos=1_000)
    expected_gate_durations = {
        cirq_google.FSimGateFamily(gates_to_accept=[cirq_google.SYC]):
        base_duration * 0,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP]):
        base_duration * 1,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.SQRT_ISWAP_INV]):
        base_duration * 2,
        cirq_google.FSimGateFamily(gates_to_accept=[cirq.CZ]):
        base_duration * 3,
        cirq.GateFamily(cirq.ops.phased_x_z_gate.PhasedXZGate):
        base_duration * 4,
        cirq.GateFamily(cirq.ops.common_gates.XPowGate):
        base_duration * 4,
        cirq.GateFamily(cirq.ops.common_gates.YPowGate):
        base_duration * 4,
        cirq.GateFamily(cirq.ops.phased_x_gate.PhasedXPowGate):
        base_duration * 4,
        cirq.GateFamily(cirq.ops.common_gates.ZPowGate,
                        tags_to_ignore=[cirq_google.PhysicalZTag()]):
        base_duration * 5,
        cirq.GateFamily(cirq.ops.common_gates.ZPowGate,
                        tags_to_accept=[cirq_google.PhysicalZTag()]):
        base_duration * 6,
        cirq.GateFamily(cirq_google.experimental.ops.coupler_pulse.CouplerPulse):
        base_duration * 7,
        cirq.GateFamily(cirq.ops.measurement_gate.MeasurementGate):
        base_duration * 8,
        cirq.GateFamily(cirq.ops.wait_gate.WaitGate):
        base_duration * 9,
    }

    expected_target_gatesets = (
        cirq.CZTargetGateset(),
        cirq_google.SycamoreTargetGateset(),
        cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=True),
    )

    return (
        _DeviceInfo(
            grid_qubits,
            qubit_pairs,
            expected_gateset,
            expected_gate_durations,
            expected_target_gatesets,
        ),
        spec,
    )
Example #21
0
        cirq.SqrtIswapTargetGateset(),
        cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=False))
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6,
                                    required_sqrt_iswap_count=0,
                                    use_sqrt_iswap_inv=True))
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6,
                                    required_sqrt_iswap_count=3,
                                    use_sqrt_iswap_inv=True))


@pytest.mark.parametrize(
    'gateset',
    [
        cirq.SqrtIswapTargetGateset(),
        cirq.SqrtIswapTargetGateset(
            atol=1e-6, required_sqrt_iswap_count=2, use_sqrt_iswap_inv=True),
    ],
)
def test_sqrt_iswap_gateset_repr(gateset):
    cirq.testing.assert_equivalent_repr(gateset)


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)]),
def test_sqrt_iswap_gateset_raises():
    with pytest.raises(ValueError, match="`required_sqrt_iswap_count` must be 0, 1, 2, or 3"):
        _ = cirq.SqrtIswapTargetGateset(required_sqrt_iswap_count=4)
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(), cirq.SqrtIswapTargetGateset(use_sqrt_iswap_inv=False)
    )
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6, required_sqrt_iswap_count=0, use_sqrt_iswap_inv=True)
    )
    eq.add_equality_group(
        cirq.SqrtIswapTargetGateset(atol=1e-6, required_sqrt_iswap_count=3, use_sqrt_iswap_inv=True)
    )
    eq.add_equality_group(cirq.SqrtIswapTargetGateset(additional_gates=[cirq.XPowGate]))


@pytest.mark.parametrize(
    'gateset',
    [
        cirq.SqrtIswapTargetGateset(),
        cirq.SqrtIswapTargetGateset(
            atol=1e-6,
            required_sqrt_iswap_count=2,
            use_sqrt_iswap_inv=True,
            additional_gates=[
                cirq.CZ,
                cirq.XPowGate,
                cirq.YPowGate,
                cirq.GateFamily(cirq.ZPowGate, tags_to_accept=['test_tag']),
            ],
        ),
        cirq.SqrtIswapTargetGateset(additional_gates=()),
    ],
)
def test_sqrt_iswap_gateset_repr(gateset):