Exemple #1
0
 def __call__(self, strategy: 'cirq.Circuit'):
     if not is_acquaintance_strategy(strategy):
         raise TypeError('not is_acquaintance_strategy(strategy)')
     expose_acquaintance_gates(strategy)
     strategy.device = self.execution_strategy.device
     super().optimize_circuit(strategy)
     return self.mapping.copy()
Exemple #2
0
def remove_redundant_acquaintance_opportunities(
        strategy: circuits.Circuit) -> None:
    """Removes redundant acquaintance opportunities."""
    if not is_acquaintance_strategy(strategy):
        raise TypeError('not is_acquaintance_strategy(circuit)')

    qubits = tuple(strategy.all_qubits())
    mapping = {q: i for i, q in enumerate(qubits)}

    expose_acquaintance_gates(strategy)
    annotated_strategy = strategy.copy()
    LogicalAnnotator(mapping)(annotated_strategy)

    new_moments = []  # type: List[ops.Moment]
    acquaintance_opps = set()  # type: Set[FrozenSet[int]]
    for moment in annotated_strategy:
        new_moment = []  # type: List[ops.Operation]
        for op in moment:
            if isinstance(op, AcquaintanceOperation):
                opp = frozenset(cast(Sequence[int], op.logical_indices))
                if opp not in acquaintance_opps:
                    acquaintance_opps.add(opp)
                    new_moment.append(acquaint(*op.qubits))
            else:
                new_moment.append(op)
        new_moments.append(ops.Moment(new_moment))
    strategy._moments = new_moments
Exemple #3
0
def complete_acquaintance_strategy(qubit_order: Sequence[ops.Qid],
                                   acquaintance_size: int=0,
                                   ) -> circuits.Circuit:
    """
    Returns an acquaintance strategy capable of executing a gate corresponding
    to any set of at most acquaintance_size qubits.

    Args:
        qubit_order: The qubits on which the strategy should be defined.
        acquaintance_size: The maximum number of qubits to be acted on by
        an operation.

    Returns:
        An circuit capable of implementing any set of k-local
        operation.
    """
    if acquaintance_size < 0:
        raise ValueError('acquaintance_size must be non-negative.')
    elif acquaintance_size == 0:
        return circuits.Circuit(device=UnconstrainedAcquaintanceDevice)

    if acquaintance_size > len(qubit_order):
        return circuits.Circuit(device=UnconstrainedAcquaintanceDevice)
    if acquaintance_size == len(qubit_order):
        return circuits.Circuit.from_ops(
                acquaint(*qubit_order), device=UnconstrainedAcquaintanceDevice)

    strategy = circuits.Circuit.from_ops(
            (acquaint(q) for q in qubit_order),
            device=UnconstrainedAcquaintanceDevice)
    for size_to_acquaint in range(2, acquaintance_size + 1):
        expose_acquaintance_gates(strategy)
        replace_acquaintance_with_swap_network(
                strategy, qubit_order, size_to_acquaint)
    return strategy
Exemple #4
0
def remove_redundant_acquaintance_opportunities(strategy: 'cirq.Circuit') -> int:
    """Removes redundant acquaintance opportunities."""

    qubits = sorted(strategy.all_qubits())
    mapping = {q: i for i, q in enumerate(qubits)}

    expose_acquaintance_gates(strategy)
    annotated_strategy = strategy.copy()
    LogicalAnnotator(mapping)(annotated_strategy)

    new_moments: List['cirq.Moment'] = []
    acquaintance_opps: Set[FrozenSet[int]] = set()
    n_removed = 0
    for moment in annotated_strategy:
        new_moment: List['cirq.Operation'] = []
        for op in moment:
            if isinstance(op, AcquaintanceOperation):
                opp = frozenset(cast(Sequence[int], op.logical_indices))
                if opp not in acquaintance_opps:
                    acquaintance_opps.add(opp)
                    new_moment.append(acquaint(*op.qubits))
                else:
                    n_removed += 1
            else:
                new_moment.append(op)
        new_moments.append(ops.Moment(new_moment))
    strategy._moments = new_moments
    return n_removed
Exemple #5
0
def complete_acquaintance_strategy(
        qubit_order: Sequence['cirq.Qid'],
        acquaintance_size: int = 0,
        swap_gate: 'cirq.Gate' = ops.SWAP) -> 'cirq.Circuit':
    """Returns an acquaintance strategy with can handle the given number of qubits.

    Args:
        qubit_order: The qubits on which the strategy should be defined.
        acquaintance_size: The maximum number of qubits to be acted on by
        an operation.
        swap_gate: The gate used to swap logical indices.

    Returns:
        A circuit capable of implementing any set of k-local operations.

    Raises:
        ValueError: If `acquaintance_size` is negative.
    """
    if acquaintance_size < 0:
        raise ValueError('acquaintance_size must be non-negative.')
    if acquaintance_size == 0:
        return circuits.Circuit()

    if acquaintance_size > len(qubit_order):
        return circuits.Circuit()
    if acquaintance_size == len(qubit_order):
        return circuits.Circuit(acquaint(*qubit_order))

    strategy = circuits.Circuit((acquaint(q) for q in qubit_order))
    for size_to_acquaint in range(2, acquaintance_size + 1):
        expose_acquaintance_gates(strategy)
        replace_acquaintance_with_swap_network(strategy, qubit_order,
                                               size_to_acquaint, swap_gate)
    return strategy
def get_acquaintance_dag(strategy: 'cirq.Circuit',
                         initial_mapping: LogicalMapping):
    strategy = strategy.copy()
    expose_acquaintance_gates(strategy)
    LogicalAnnotator(initial_mapping)(strategy)
    acquaintance_ops = (op for moment in strategy._moments
                        for op in moment.operations
                        if isinstance(op, AcquaintanceOperation))
    return circuits.CircuitDag.from_ops(acquaintance_ops)
Exemple #7
0
def quartic_paired_acquaintance_strategy(
    qubit_pairs: Iterable[Tuple['cirq.Qid', ops.Qid]]
) -> Tuple['cirq.Circuit', Sequence['cirq.Qid']]:
    """Acquaintance strategy for pairs of pairs.

    Implements UpCCGSD ansatz from arXiv:1810.02327.
    """

    qubit_pairs = tuple(
        cast(Tuple['cirq.Qid', ops.Qid], tuple(qubit_pair)) for qubit_pair in qubit_pairs
    )
    qubits = qubit_pairs_to_qubit_order(qubit_pairs)
    n_qubits = len(qubits)
    swap_network = SwapNetworkGate((1,) * n_qubits, 2)(*qubits)
    strategy = circuits.Circuit(swap_network, device=UnconstrainedAcquaintanceDevice)
    expose_acquaintance_gates(strategy)
    for i in reversed(range(0, n_qubits, 2)):
        moment = ops.Moment([acquaint(*qubits[j : j + 4]) for j in range(i % 4, n_qubits - 3, 4)])
        strategy.insert(2 * i, moment)
    return strategy, qubits
Exemple #8
0
 def __call__(self, strategy: 'cirq.Circuit'):
     expose_acquaintance_gates(strategy)
     super().optimize_circuit(strategy)
     return self.mapping.copy()