Пример #1
0
def test_sycamore_gateset_compiles_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,
    )
    gateset = cirq_google.SycamoreTargetGateset()
    compiled_circuit1 = cirq.optimize_for_target_gateset(circuit1,
                                                         gateset=gateset)
    compiled_circuit2 = cirq.optimize_for_target_gateset(circuit2,
                                                         gateset=gateset)
    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)
Пример #2
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)
Пример #3
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)))
Пример #4
0
def test_convert_to_cz_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"),
    )
    c_new = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=cirq.CZTargetGateset())

    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.AnyUnitaryGateFamily(1)))
         or all_gates_of_type(m, cirq.Gateset(cirq.CZ))) for m in c_new)

    c_new = cirq.optimize_for_target_gateset(
        c_orig,
        gateset=cirq.CZTargetGateset(allow_partial_czs=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.AnyUnitaryGateFamily(1)))
         or all_gates_of_type(m, cirq.Gateset(cirq.CZPowGate))) for m in c_new)
Пример #5
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}),
        )
def test_two_qubit_compilation_leaves_single_gates_in_gateset():
    q = cirq.LineQubit.range(2)
    gateset = DummyCXTargetGateset()

    c = cirq.Circuit(cirq.X(q[0]) ** 0.5)
    cirq.testing.assert_same_circuits(cirq.optimize_for_target_gateset(c, gateset=gateset), c)

    c = cirq.Circuit(cirq.CNOT(*q[:2]))
    cirq.testing.assert_same_circuits(cirq.optimize_for_target_gateset(c, gateset=gateset), c)
Пример #7
0
def assert_optimization_not_broken(circuit: cirq.Circuit):
    c_new = cirq.optimize_for_target_gateset(circuit,
                                             gateset=cirq.CZTargetGateset())
    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.CZTargetGateset(allow_partial_czs=True))
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        circuit, c_new, atol=1e-6)
Пример #8
0
def test_unsupported_gate():
    class UnknownGate(cirq.testing.TwoQubitGate):
        pass

    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(UnknownGate()(q0, q1))
    with pytest.raises(ValueError, match='Unable to convert'):
        cirq.optimize_for_target_gateset(
            circuit, gateset=cirq_google.SycamoreTargetGateset(), ignore_failures=False
        )
Пример #9
0
def test_optimize_for_target_gateset():
    q = cirq.LineQubit.range(4)
    c_orig = cirq.Circuit(
        cirq.QuantumFourierTransformGate(4).on(*q),
        cirq.Y(q[0]).with_tags("ignore"),
        cirq.Y(q[1]).with_tags("ignore"),
        cirq.CNOT(*q[2:]).with_tags("ignore"),
        cirq.measure(*q[:2], key="m"),
        cirq.CZ(*q[2:]).with_classical_controls("m"),
        cirq.inverse(cirq.QuantumFourierTransformGate(4).on(*q)),
    )

    cirq.testing.assert_has_diagram(
        c_orig,
        '''
0: ───qft───Y['ignore']───M───────qft^-1───
      │                   ║       │
1: ───#2────Y['ignore']───M───────#2───────
      │                   ║       │
2: ───#3────@['ignore']───╫───@───#3───────
      │     │             ║   ║   │
3: ───#4────X─────────────╫───@───#4───────
                          ║   ║
m: ═══════════════════════@═══^════════════
''',
    )
    gateset = MatrixGateTargetGateset()
    context = cirq.TransformerContext(tags_to_ignore=("ignore", ))
    c_new = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=gateset,
                                             context=context)
    cirq.testing.assert_has_diagram(
        c_new,
        '''
                                         ┌────────┐                         ┌────────┐                 ┌────────┐
0: ───M[1]──────────M[1]──────────────────────M[1]────Y['ignore']───M────────M[1]───────────────────────────M[1]────M[1]───M[1]───
      │             │                         │                     ║        │                              │       │      │
1: ───M[2]───M[1]───┼─────────────M[1]────M[1]┼───────Y['ignore']───M────────┼───M[1]───────────M[1]────M[1]┼───────┼──────M[2]───
             │      │             │       │   │                     ║        │   │              │       │   │       │
2: ──────────M[2]───M[2]───M[1]───┼───────M[2]┼───────@['ignore']───╫───@────┼───M[2]────M[1]───┼───────M[2]┼───────M[2]──────────
                           │      │           │       │             ║   ║    │           │      │           │
3: ────────────────────────M[2]───M[2]────────M[2]────X─────────────╫───@────M[2]────────M[2]───M[2]────────M[2]──────────────────
                                                                    ║   ║
m: ═════════════════════════════════════════════════════════════════@═══^═════════════════════════════════════════════════════════
                                         └────────┘                         └────────┘                 └────────┘
        ''',
    )

    with pytest.raises(ValueError, match="Unable to convert"):
        # Raises an error due to CCO and Measurement gate, which are not part of the gateset.
        _ = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=gateset,
                                             context=context,
                                             ignore_failures=False)
Пример #10
0
def test_not_decompose_partial_czs():
    circuit = cirq.Circuit(
        cirq.CZPowGate(exponent=0.1,
                       global_shift=-0.5)(*cirq.LineQubit.range(2)), )
    cirq.optimize_for_target_gateset(circuit, gateset=cirq.CZTargetGateset())
    cz_gates = [
        op.gate for op in circuit.all_operations()
        if isinstance(op, cirq.GateOperation)
        and isinstance(op.gate, cirq.CZPowGate)
    ]
    num_full_cz = sum(1 for cz in cz_gates if cz.exponent % 2 == 1)
    num_part_cz = sum(1 for cz in cz_gates if cz.exponent % 2 != 1)
    assert num_full_cz == 0
    assert num_part_cz == 1
Пример #11
0
def test_composite_gates_without_matrix():
    class CompositeDummy(cirq.SingleQubitGate):
        def _decompose_(self, qubits):
            yield cirq.X(qubits[0])
            yield cirq.Y(qubits[0])**0.5

    class CompositeDummy2(cirq.testing.TwoQubitGate):
        def _decompose_(self, qubits):
            yield cirq.CZ(qubits[0], qubits[1])
            yield CompositeDummy()(qubits[1])

    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(
        CompositeDummy()(q0),
        CompositeDummy2()(q0, q1),
    )
    expected = cirq.Circuit(
        cirq.X(q0),
        cirq.Y(q0)**0.5,
        cirq.CZ(q0, q1),
        cirq.X(q1),
        cirq.Y(q1)**0.5,
    )
    c_new = cirq.optimize_for_target_gateset(circuit,
                                             gateset=cirq.CZTargetGateset())

    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        c_new, expected, atol=1e-6)
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        c_new, circuit, atol=1e-6)
Пример #12
0
def test_decompose_multi_qubit_cirq_gates(gate, qubits):
    circuit = cirq.Circuit(gate(*cirq.LineQubit.range(qubits)))
    decomposed_circuit = cirq.optimize_for_target_gateset(
        circuit, gateset=ionq_target_gateset, ignore_failures=False)
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        circuit, decomposed_circuit, atol=1e-8)
    assert ionq_target_gateset.validate(decomposed_circuit)
Пример #13
0
def test_avoids_decompose_when_matrix_available():
    class OtherXX(cirq.testing.TwoQubitGate):
        # coverage: ignore
        def _has_unitary_(self) -> bool:
            return True

        def _unitary_(self) -> np.ndarray:
            m = np.array([[0, 1], [1, 0]])
            return np.kron(m, m)

        def _decompose_(self, qubits):
            assert False

    class OtherOtherXX(cirq.testing.TwoQubitGate):
        # coverage: ignore
        def _has_unitary_(self) -> bool:
            return True

        def _unitary_(self) -> np.ndarray:
            m = np.array([[0, 1], [1, 0]])
            return np.kron(m, m)

        def _decompose_(self, qubits):
            assert False

    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit(OtherXX()(a, b), OtherOtherXX()(a, b))
    c = cirq.optimize_for_target_gateset(c, gateset=cirq.CZTargetGateset())
    assert len(c) == 0
Пример #14
0
def optimized_for_sycamore(
    circuit: cirq.Circuit,
    *,
    qubit_map: Callable[[cirq.Qid], cirq.GridQubit] = lambda e: cast(cirq.GridQubit, e),
    optimizer_type: str = 'sqrt_iswap',
    tolerance: float = 1e-5,
    tabulation_resolution: Optional[float] = None,
) -> cirq.Circuit:
    """Optimizes a circuit for Google devices.

    Uses a set of optimizers that will compile to the proper gateset for the
    device (xmon, sqrt_iswap, or sycamore gates) and then use optimizers to
    compress the gate depth down as much as is easily algorithmically possible
    by merging rotations, ejecting Z gates, etc.

    Args:
        circuit: The circuit to optimize.
        qubit_map: Transforms the qubits (e.g. so that they are GridQubits).
        optimizer_type: A string defining the optimizations to apply.
            Possible values are  'xmon', 'xmon_partial_cz', 'sqrt_iswap',
            'sycamore'
        tolerance: The tolerance passed to the various circuit optimization
            passes.
        tabulation_resolution: If provided, compute a gateset tabulation
            with the specified resolution and use it to approximately
            compile arbitrary two-qubit gates for which an analytic compilation
            is not known.
    Returns:
        The optimized circuit.

    Raises:
        ValueError: If the `optimizer_type` is not a supported type.
    """
    copy = circuit.copy()
    if optimizer_type not in _TARGET_GATESETS:
        raise ValueError(
            f'{optimizer_type} is not an allowed type.  Allowed '
            f'types are: {_TARGET_GATESETS.keys()}'
        )

    tabulation: Optional[cirq.TwoQubitGateTabulation] = None
    if tabulation_resolution is not None:
        tabulation = _gate_product_tabulation_cached(optimizer_type, tabulation_resolution)

    if optimizer_type in _TARGET_GATESETS:
        copy = cirq.optimize_for_target_gateset(
            circuit,
            gateset=_TARGET_GATESETS[optimizer_type](tolerance, tabulation),
            context=cirq.TransformerContext(deep=True),
        )
    copy = cirq.merge_single_qubit_gates_to_phxz(copy, atol=tolerance)
    copy = cirq.eject_phased_paulis(copy, atol=tolerance)
    copy = cirq.eject_z(copy, atol=tolerance)
    copy = cirq.drop_negligible_operations(copy, atol=tolerance)

    ret = cirq.Circuit(
        (op.transform_qubits(qubit_map) for op in copy.all_operations()),
        strategy=cirq.InsertStrategy.EARLIEST,
    )
    return ret
Пример #15
0
def test_two_qubit_compilation_merge_and_replace_to_target_gateset():
    q = cirq.LineQubit.range(2)
    c_orig = cirq.Circuit(
        cirq.Moment(cirq.Z(q[1]), cirq.X(q[0])),
        cirq.Moment(cirq.CZ(*q).with_tags("no_compile")),
        cirq.Moment(cirq.Z.on_each(*q)),
        cirq.Moment(cirq.X(q[0])),
        cirq.Moment(cirq.CZ(*q)),
        cirq.Moment(cirq.Z.on_each(*q)),
        cirq.Moment(cirq.X(q[0])),
    )
    cirq.testing.assert_has_diagram(
        c_orig,
        '''
0: ───X───@['no_compile']───Z───X───@───Z───X───
          │                         │
1: ───Z───@─────────────────Z───────@───Z───────
''',
    )
    c_new = cirq.optimize_for_target_gateset(
        c_orig,
        gateset=DummyCXTargetGateset(),
        context=cirq.TransformerContext(tags_to_ignore=("no_compile", )),
    )
    cirq.testing.assert_has_diagram(
        c_new,
        '''
0: ───X───@['no_compile']───X───@───Y───@───Z───
          │                     │       │
1: ───Z───@─────────────────X───X───Y───X───Z───
''',
    )
Пример #16
0
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 = cirq.optimize_for_target_gateset(
        circuit, gateset=cirq_google.SycamoreTargetGateset())
    cirq.testing.assert_same_circuits(circuit, compiled_circuit)
Пример #17
0
def decompose_to_device(operation: cirq.Operation,
                        atol: float = 1e-8) -> cirq.OP_TREE:
    """Decompose operation to ionq native operations.


    Merges single qubit operations and decomposes two qubit operations
    into CZ gates.

    Args:
        operation: `cirq.Operation` to decompose.
        atol: absolute error tolerance to use when declaring two unitary
            operations equal.

    Returns:
        cirq.OP_TREE containing decomposed operations.

    Raises:
        ValueError: If supplied operation cannot be decomposed
            for the ionq device.

    """
    return cirq.optimize_for_target_gateset(
        cirq.Circuit(operation),
        gateset=ionq_gateset.IonQTargetGateset(),
        ignore_failures=False).all_operations()
Пример #18
0
def test_avoids_decompose_fallback_when_matrix_available_two_qubit():
    class OtherCZ(cirq.testing.TwoQubitGate):
        def _unitary_(self) -> np.ndarray:
            return np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                             [0, 0, 0, -1]])

    class OtherOtherCZ(cirq.testing.TwoQubitGate):
        def _decompose_(self, qubits):
            return OtherCZ().on(*qubits)

    q00 = cirq.GridQubit(0, 0)
    q01 = cirq.GridQubit(0, 1)
    c = cirq.Circuit(OtherCZ().on(q00, q01), OtherOtherCZ().on(q00, q01))
    expected_diagram = """
(0, 0): ───@───@───
           │   │
(0, 1): ───@───@───
"""
    converted = cirq.optimize_for_target_gateset(
        c, gateset=cirq.neutral_atoms.NeutralAtomGateset())
    cirq.testing.assert_has_diagram(converted, expected_diagram)
    with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset",
                                        deadline='v0.16',
                                        count=2):
        cirq.neutral_atoms.ConvertToNeutralAtomGates().optimize_circuit(c)
        cirq.testing.assert_has_diagram(c, expected_diagram)
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,
        )
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,
    )
Пример #21
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
Пример #22
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
Пример #23
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 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
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
Пример #26
0
def test_convert_to_sycamore_equivalent_unitaries(gate):
    circuit = cirq.Circuit(gate.on(*cirq.LineQubit.range(2)))
    converted_circuit = cirq.optimize_for_target_gateset(
        circuit, gateset=cirq_google.SycamoreTargetGateset()
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        circuit, converted_circuit, atol=1e-8
    )
Пример #27
0
def test_optimizes_tagged_partial_cz():
    a, b = cirq.LineQubit.range(2)
    c = cirq.Circuit((cirq.CZ**0.5)(a, b).with_tags('mytag'))
    assert_optimization_not_broken(c)
    c = cirq.optimize_for_target_gateset(c, gateset=cirq.CZTargetGateset())
    assert (len([
        1 for op in c.all_operations() if len(op.qubits) == 2
    ]) == 2), 'It should take 2 CZ gates to decompose a CZ**0.5 gate'
Пример #28
0
def test_gateset(op: cirq.Operation, is_in_gateset: bool):
    gateset = nag.NeutralAtomGateset(max_parallel_z=4, max_parallel_xy=3)
    assert gateset.validate(op) == is_in_gateset
    converted_ops = cirq.optimize_for_target_gateset(cirq.Circuit(op),
                                                     gateset=gateset)
    if is_in_gateset:
        assert converted_ops == cirq.Circuit(op)
        assert gateset.validate(converted_ops)
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,
        )
Пример #30
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)