def test_swap_permutation_gate():
    no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate ==
                            cirq.SWAP)
    a, b = cirq.NamedQubit('a'), cirq.NamedQubit('b')
    expander = cirq.ExpandComposite(no_decomp=no_decomp)
    circuit = cirq.Circuit.from_ops(cca.SwapPermutationGate()(a, b))
    expander(circuit)
    assert tuple(circuit.all_operations()) == (cirq.SWAP(a, b), )

    no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate ==
                            cirq.CZ)
    expander = cirq.ExpandComposite(no_decomp=no_decomp)
    circuit = cirq.Circuit.from_ops(cca.SwapPermutationGate(cirq.CZ)(a, b))
    expander(circuit)
    assert tuple(circuit.all_operations()) == (cirq.CZ(a, b), )
Exemple #2
0
def test_get_logical_operations():
    a, b, c, d = qubits = cirq.LineQubit.range(4)
    mapping = dict(zip(qubits, qubits))
    operations = [
        cirq.ZZ(a, b),
        cca.SwapPermutationGate()(b, c),
        cirq.SWAP(a, b),
        cca.SwapPermutationGate()(c, d),
        cca.SwapPermutationGate()(b, c),
        cirq.ZZ(a, b)
    ]
    assert list(cca.get_logical_operations(operations, mapping)) == [
        cirq.ZZ(a, b), cirq.SWAP(a, c),
        cirq.ZZ(a, d)
    ]
def test_update_mapping():
    gate = cca.SwapPermutationGate()
    a, b, c = (cirq.NamedQubit(s) for s in 'abc')
    mapping = {s: i for i, s in enumerate((a, b, c))}
    ops = [gate(a, b), gate(b, c)]
    cca.update_mapping(mapping, ops)
    assert mapping == {a: 1, b: 2, c: 0}
Exemple #4
0
def test_remove_redundant_acquaintance_opportunities():
    device = cca.UnconstrainedAcquaintanceDevice
    a, b, c, d, e = cirq.LineQubit.range(5)
    swap = cca.SwapPermutationGate()

    with pytest.raises(TypeError):
        ops = [cca.acquaint(a, b)]
        strategy = cirq.Circuit.from_ops(ops)
        cca.remove_redundant_acquaintance_opportunities(strategy)

    ops = [cca.acquaint(a, b), cca.acquaint(a, b)]
    strategy = cirq.Circuit.from_ops(ops, device=device)
    diagram_before = """
0: ───█───█───
      │   │
1: ───█───█───
    """
    ct.assert_has_diagram(strategy, diagram_before)
    cca.remove_redundant_acquaintance_opportunities(strategy)
    cca.remove_redundant_acquaintance_opportunities(strategy)
    diagram_after = """
0: ───█───────
      │
1: ───█───────
    """
    ct.assert_has_diagram(strategy, diagram_after)

    ops = [
        cca.acquaint(a, b),
        cca.acquaint(c, d),
        swap(d, e),
        swap(c, d),
        cca.acquaint(d, e)
    ]
    strategy = cirq.Circuit.from_ops(ops, device=device)
    diagram_before = """
0: ───█───────────────────
      │
1: ───█───────────────────

2: ───█─────────0↦1───────
      │         │
3: ───█───0↦1───1↦0───█───
          │           │
4: ───────1↦0─────────█───
    """
    ct.assert_has_diagram(strategy, diagram_before)
    cca.remove_redundant_acquaintance_opportunities(strategy)
    diagram_after = """
0: ───█───────────────────
      │
1: ───█───────────────────

2: ───█─────────0↦1───────
      │         │
3: ───█───0↦1───1↦0───────
          │
4: ───────1↦0─────────────
    """
    ct.assert_has_diagram(strategy, diagram_after)
Exemple #5
0
def test_swap_permutation_gate():
    no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate ==
                            cirq.SWAP)
    a, b = cirq.NamedQubit('a'), cirq.NamedQubit('b')
    gate = cca.SwapPermutationGate()
    assert gate.num_qubits() == 2
    circuit = cirq.Circuit(gate(a, b))
    circuit = cirq.expand_composite(circuit, no_decomp=no_decomp)
    assert tuple(circuit.all_operations()) == (cirq.SWAP(a, b), )

    no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate ==
                            cirq.CZ)
    circuit = cirq.Circuit(cca.SwapPermutationGate(cirq.CZ)(a, b))
    circuit = cirq.expand_composite(circuit, no_decomp=no_decomp)
    assert tuple(circuit.all_operations()) == (cirq.CZ(a, b), )

    assert cirq.commutes(gate, cirq.ZZ)
    with pytest.raises(TypeError):
        cirq.commutes(gate, cirq.CCZ)
def test_diagram():
    gate = cca.SwapPermutationGate()
    a, b = cirq.NamedQubit('a'), cirq.NamedQubit('b')
    circuit = cirq.Circuit.from_ops([gate(a, b)])
    actual_text_diagram = circuit.to_text_diagram()
    expected_text_diagram = """
a: ───0↦1───
      │
b: ───1↦0───
    """.strip()
    assert actual_text_diagram == expected_text_diagram
Exemple #7
0
def test_remove_redundant_acquaintance_opportunities():
    a, b, c, d, e = cirq.LineQubit.range(5)
    swap = cca.SwapPermutationGate()

    ops = [cca.acquaint(a, b), cca.acquaint(a, b)]
    strategy = cirq.Circuit(ops)
    diagram_before = """
0: ───█───█───
      │   │
1: ───█───█───
    """
    ct.assert_has_diagram(strategy, diagram_before)
    cca.remove_redundant_acquaintance_opportunities(strategy)
    diagram_after = """
0: ───█───────
      │
1: ───█───────
    """
    ct.assert_has_diagram(strategy, diagram_after)

    ops = [
        cca.acquaint(a, b),
        cca.acquaint(c, d),
        swap(d, e),
        swap(c, d),
        cca.acquaint(d, e)
    ]
    strategy = cirq.Circuit(ops)
    diagram_before = """
0: ───█───────────────────
      │
1: ───█───────────────────

2: ───█─────────0↦1───────
      │         │
3: ───█───0↦1───1↦0───█───
          │           │
4: ───────1↦0─────────█───
    """
    ct.assert_has_diagram(strategy, diagram_before)
    cca.remove_redundant_acquaintance_opportunities(strategy)
    diagram_after = """
0: ───█───────────────────
      │
1: ───█───────────────────

2: ───█─────────0↦1───────
      │         │
3: ───█───0↦1───1↦0───────
          │
4: ───────1↦0─────────────
    """
    ct.assert_has_diagram(strategy, diagram_after)
def test_final_mapping():
    n_qubits = 10
    qubits = cirq.LineQubit.range(n_qubits)
    initial_mapping = dict(zip(qubits, qubits))
    expected_final_mapping = dict(zip(qubits, reversed(qubits)))
    SWAP = cca.SwapPermutationGate()
    circuit = cirq.Circuit(
        cirq.Moment(
            SWAP(*qubits[i:i + 2]) for i in range(l % 2, n_qubits - 1, 2))
        for l in range(n_qubits))
    swap_network = ccr.SwapNetwork(circuit, initial_mapping)
    assert swap_network.final_mapping() == expected_final_mapping
Exemple #9
0
def test_validate_permutation_errors():
    validate_permutation = cca.PermutationGate.validate_permutation
    validate_permutation({})

    with pytest.raises(IndexError,
                       message='key and value sets must be the same.'):
        validate_permutation({0: 2, 1: 3})

    with pytest.raises(IndexError,
                       message='keys of the permutation must be non-negative.'):
        validate_permutation({-1: 0, 0: -1})

    with pytest.raises(IndexError, message='key is out of bounds.'):
        validate_permutation({0: 3, 3: 0}, 2)

    gate = cca.SwapPermutationGate()
    assert cirq.circuit_diagram_info(gate, default=None) is None
Exemple #10
0
def test_rectification():
    qubits = cirq.LineQubit.range(4)

    with pytest.raises(TypeError):
        cca.rectify_acquaintance_strategy(cirq.Circuit())

    perm_gate = cca.SwapPermutationGate()
    operations = [
        perm_gate(*qubits[:2]),
        cca.ACQUAINT(*qubits[2:]),
        cca.ACQUAINT(*qubits[:2]),
        perm_gate(*qubits[2:])
    ]

    strategy = cirq.Circuit.from_ops(
        operations, device=cca.UnconstrainedAcquaintanceDevice)
    cca.rectify_acquaintance_strategy(strategy)
    actual_text_diagram = strategy.to_text_diagram().strip()
    expected_text_diagram = """
0: ───────0↦1─────────█───
          │           │
1: ───────1↦0─────────█───

2: ───█─────────0↦1───────
      │         │
3: ───█─────────1↦0───────
    """.strip()
    assert actual_text_diagram == expected_text_diagram

    strategy = cirq.Circuit.from_ops(
        operations, device=cca.UnconstrainedAcquaintanceDevice)
    cca.rectify_acquaintance_strategy(strategy, False)
    actual_text_diagram = strategy.to_text_diagram()
    expected_text_diagram = """
0: ───0↦1───────█─────────
      │         │
1: ───1↦0───────█─────────

2: ─────────█───────0↦1───
            │       │
3: ─────────█───────1↦0───
    """.strip()
    assert actual_text_diagram == expected_text_diagram
Exemple #11
0
def test_rectification():
    qubits = cirq.LineQubit.range(4)

    perm_gate = cca.SwapPermutationGate()
    operations = [
        perm_gate(*qubits[:2]),
        cca.acquaint(*qubits[2:]),
        cca.acquaint(*qubits[:2]),
        perm_gate(*qubits[2:]),
    ]

    strategy = cirq.Circuit(operations)
    cca.rectify_acquaintance_strategy(strategy)
    actual_text_diagram = strategy.to_text_diagram().strip()
    expected_text_diagram = """
0: ───────0↦1─────────█───
          │           │
1: ───────1↦0─────────█───

2: ───█─────────0↦1───────
      │         │
3: ───█─────────1↦0───────
    """.strip()
    assert actual_text_diagram == expected_text_diagram

    strategy = cirq.Circuit(operations)
    cca.rectify_acquaintance_strategy(strategy, False)
    actual_text_diagram = strategy.to_text_diagram()
    expected_text_diagram = """
0: ───0↦1───────█─────────
      │         │
1: ───1↦0───────█─────────

2: ─────────█───────0↦1───
            │       │
3: ─────────█───────1↦0───
    """.strip()
    assert actual_text_diagram == expected_text_diagram
Exemple #12
0
def test_uses_consistent_swap_gate():
    a, b = cirq.LineQubit.range(2)
    circuit = cirq.Circuit.from_ops(
        [cca.SwapPermutationGate()(a, b),
         cca.SwapPermutationGate()(a, b)])
    assert cca.uses_consistent_swap_gate(circuit, cirq.SWAP)
    assert not cca.uses_consistent_swap_gate(circuit, cirq.CZ)
    circuit = cirq.Circuit.from_ops([
        cca.SwapPermutationGate(cirq.CZ)(a, b),
        cca.SwapPermutationGate(cirq.CZ)(a, b)
    ])
    assert cca.uses_consistent_swap_gate(circuit, cirq.CZ)
    assert not cca.uses_consistent_swap_gate(circuit, cirq.SWAP)
    circuit = cirq.Circuit.from_ops([
        cca.SwapPermutationGate()(a, b),
        cca.SwapPermutationGate(cirq.CZ)(a, b)
    ])
    assert not cca.uses_consistent_swap_gate(circuit, cirq.SWAP)
    assert not cca.uses_consistent_swap_gate(circuit, cirq.CZ)
Exemple #13
0
    TYPE_CHECKING,
)

import numpy as np
import networkx as nx

from cirq import circuits, ops, value
import cirq.contrib.acquaintance as cca
from cirq.contrib.routing.initialization import get_initial_mapping
from cirq.contrib.routing.swap_network import SwapNetwork
from cirq.contrib.routing.utils import get_time_slices, ops_are_consistent_with_device_graph

if TYPE_CHECKING:
    import cirq

SWAP = cca.SwapPermutationGate()
QidPair = Tuple[ops.Qid, ops.Qid]


def route_circuit_greedily(
    circuit: circuits.Circuit, device_graph: nx.Graph, **kwargs
) -> SwapNetwork:
    """Greedily routes a circuit on a given device.

    Alternates between heuristically picking a few SWAPs to change the mapping
    and applying all logical operations possible given the new mapping, until
    all logical operations have been applied.

    The SWAP selection heuristic is as follows. In every iteration, the
    remaining two-qubit gates are partitioned into time slices. (See
    utils.get_time_slices for details.) For each set of candidate SWAPs, the new
Exemple #14
0
def test_swap_gate_eq():
    assert cca.SwapPermutationGate() == cca.SwapPermutationGate(cirq.SWAP)
    assert cca.SwapPermutationGate() != cca.SwapPermutationGate(cirq.CZ)
    assert cca.SwapPermutationGate(cirq.CZ) == cca.SwapPermutationGate(cirq.CZ)
Exemple #15
0
0: ───4───█───4───╲0╱───2───────2─────────2───█───2───╲0╱───1───────1─────────1───█───1───╲0╱───3───
          │       │                           │       │                           │       │
1: ───2───█───2───╱1╲───4───█───4───╲0╱───1───█───1───╱1╲───2───█───2───╲0╱───3───█───3───╱1╲───1───
                            │       │                           │       │
2: ───0───█───0───╲0╱───1───█───1───╱1╲───4───█───4───╲0╱───3───█───3───╱1╲───2───█───2───╲0╱───0───
          │       │                           │       │                           │       │
3: ───1───█───1───╱1╲───0───█───0───╲0╱───3───█───3───╱1╲───4───█───4───╲0╱───0───█───0───╱1╲───2───
                            │       │                           │       │
4: ───3───────3─────────3───█───3───╱1╲───0───────0─────────0───█───0───╱1╲───4───────4─────────4───
"""
    cirq.testing.assert_has_diagram(circuit, expected_diagram)


@pytest.mark.parametrize('circuit', [
    cirq.Circuit.from_ops(
        cca.SwapPermutationGate()(*qubit_pair)
        for qubit_pair in
        [random.sample(cirq.LineQubit.range(10), 2)
         for _ in range(20)])
    for _ in range(4)
])
def test_return_to_initial_mapping(circuit):
    qubits = sorted(circuit.all_qubits())
    cca.return_to_initial_mapping(circuit)
    initial_mapping = {q: i for i, q in enumerate(qubits)}
    mapping = dict(initial_mapping)
    cca.update_mapping(mapping, circuit.all_operations())
    assert mapping == initial_mapping


def test_uses_consistent_swap_gate():