コード例 #1
0
def test_compile_circuit_multiple_routing_attempts():
    """Tests that we make multiple attempts at routing and keep the best one."""
    qubits = cirq.LineQubit.range(3)
    initial_mapping = dict(zip(qubits, qubits))
    more_operations = cirq.Circuit([
        cirq.X.on_each(qubits),
        cirq.Y.on_each(qubits),
    ])
    more_qubits = cirq.Circuit([
        cirq.X.on_each(cirq.LineQubit.range(4)),
    ])
    well_routed = cirq.Circuit([
        cirq.X.on_each(qubits),
    ])
    router_mock = MagicMock(side_effect=[
        ccr.SwapNetwork(more_operations, initial_mapping),
        ccr.SwapNetwork(well_routed, initial_mapping),
        ccr.SwapNetwork(more_qubits, initial_mapping),
    ])
    compiler_mock = MagicMock(side_effect=lambda circuit: circuit)
    model_circuit = cirq.Circuit([cirq.X.on_each(qubits)])

    compilation_result = cirq.contrib.quantum_volume.compile_circuit(
        model_circuit,
        device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
        compiler=compiler_mock,
        router=router_mock,
        routing_attempts=3)

    assert compilation_result.mapping == initial_mapping
    assert router_mock.call_count == 3
    compiler_mock.assert_called_with(well_routed)
コード例 #2
0
def test_nx_qubit_layout():
    foxtail_graph = ccr.xmon_device_to_graph(cirq.google.Foxtail)
    pos = ccr.nx_qubit_layout(foxtail_graph)
    assert len(pos) == len(foxtail_graph)
    for k, (x, y) in pos.items():
        assert x == k.col
        assert y == -k.row
コード例 #3
0
def test_compile_circuit_replaces_swaps():
    """Tests that the compiler never sees the SwapPermutationGates from the
    router."""
    compiler_mock = MagicMock(side_effect=lambda circuit: circuit)
    a, b, c = cirq.LineQubit.range(3)
    # Create a circuit that will require some swaps.
    model_circuit = cirq.Circuit([
        cirq.Moment([cirq.CNOT(a, b)]),
        cirq.Moment([cirq.CNOT(a, c)]),
        cirq.Moment([cirq.CNOT(b, c)]),
    ])
    compilation_result = cirq.contrib.quantum_volume.compile_circuit(
        model_circuit,
        device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
        compiler=compiler_mock,
        routing_attempts=1)

    # Assert that there were some swaps in the result
    compiler_mock.assert_called_with(compilation_result.circuit)
    assert len(
        list(
            compilation_result.circuit.findall_operations_with_gate_type(
                cirq.ops.SwapPowGate))) > 0
    # Assert that there were not SwapPermutations in the result.
    assert len(
        list(
            compilation_result.circuit.findall_operations_with_gate_type(
                cirq.contrib.acquaintance.SwapPermutationGate))) == 0
コード例 #4
0
def test_compile_circuit_with_readout_correction():
    """Tests that we are able to compile a model circuit with readout error
    correction."""
    compiler_mock = MagicMock(side_effect=lambda circuit: circuit)
    router_mock = MagicMock(
        side_effect=lambda circuit, network: ccr.SwapNetwork(circuit, {}))
    a, b, c = cirq.LineQubit.range(3)
    ap, bp, cp = cirq.LineQubit.range(3, 6)
    model_circuit = cirq.Circuit([
        cirq.Moment([cirq.X(a), cirq.Y(b), cirq.Z(c)]),
    ])
    compilation_result = cirq.contrib.quantum_volume.compile_circuit(
        model_circuit,
        device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
        compiler=compiler_mock,
        router=router_mock,
        routing_attempts=1,
        add_readout_error_correction=True)

    assert compilation_result.circuit == cirq.Circuit([
        cirq.Moment([cirq.X(a), cirq.Y(b), cirq.Z(c)]),
        cirq.Moment([cirq.X(a), cirq.X(b), cirq.X(c)]),
        cirq.Moment([cirq.CNOT(a, ap),
                     cirq.CNOT(b, bp),
                     cirq.CNOT(c, cp)]),
        cirq.Moment([cirq.X(a), cirq.X(b), cirq.X(c)]),
    ])
コード例 #5
0
def compile_circuit(
    circuit: cirq.Circuit,
    *,
    device: cirq.google.XmonDevice,
    routing_attempts: int,
    compiler: Callable[[cirq.Circuit], cirq.Circuit] = None,
    routing_algo_name: Optional[str] = None,
    router: Optional[Callable[..., ccr.SwapNetwork]] = None,
) -> ccr.SwapNetwork:
    """Compile the given model circuit onto the given device. This uses a
    different compilation method than described in
    https://arxiv.org/pdf/1811.12926.pdf Appendix A. The latter goes through a
    7-step process involving various decompositions, routing, and optimization
    steps. We route the model circuit and then run a series of optimizers on it
    (which can be passed into this function).

    Args:
        circuit: The model circuit to compile.
        device: The device to compile onto.
        routing_attempts: See doc for calculate_quantum_volume.
        compiler: An optional function to deconstruct the model circuit's
            gates down to the target devices gate set and then optimize it.

    Returns: A tuple where the first value is the compiled circuit and the
        second value is the final mapping from the model circuit to the compiled
        circuit. The latter is necessary in order to preserve the measurement
        order.

    """
    compiled_circuit = circuit.copy()
    # Swap Mapping (Routing). Ensure the gates can actually operate on the
    # target qubits given our topology.
    if router is None and routing_algo_name is None:
        routing_algo_name = 'greedy'

    best_swap_network: Union[ccr.SwapNetwork, None] = None
    best_score = None
    for _ in range(routing_attempts):
        swap_network = ccr.route_circuit(compiled_circuit,
                                         ccr.xmon_device_to_graph(device),
                                         router=router,
                                         algo_name=routing_algo_name)
        score = len(swap_network.circuit)
        if best_score is None or score < best_score:
            best_swap_network = swap_network
            best_score = score
    if best_swap_network is None:
        raise AssertionError('Unable to get routing for circuit')

    # Compile. This should decompose the routed circuit down to a gate set that
    # our device supports, and then optimize. The paper uses various
    # compiling techniques - because Quantum Volume is intended to test those
    # as well, we allow this to be passed in. This compiler is not allowed to
    # change the order of the qubits.
    if compiler:
        best_swap_network.circuit = compiler(best_swap_network.circuit)

    return best_swap_network
コード例 #6
0
def test_compile_circuit_router():
    """Tests that the given router is used."""
    router_mock = MagicMock()
    cirq.contrib.quantum_volume.compile_circuit(
        cirq.Circuit(),
        device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
        router=router_mock,
        routing_attempts=1)
    router_mock.assert_called()
コード例 #7
0
ファイル: device_test.py プロジェクト: ybc1991/Cirq
def test_xmon_device_to_graph():
    with cirq.testing.assert_deprecated("gridqubits_to_graph_device", deadline="v0.12"):

        class TestDevice:
            qubits = cirq.GridQubit.rect(2, 11)

        foxtail_graph = ccr.xmon_device_to_graph(TestDevice())
        two_by_eleven_grid_graph = ccr.get_grid_device_graph(2, 11)
        assert foxtail_graph.nodes == two_by_eleven_grid_graph.nodes
        assert foxtail_graph.edges() == two_by_eleven_grid_graph.edges()
コード例 #8
0
def test_compile_circuit_no_routing_attempts():
    """Tests that setting no routing attempts throws an error."""
    a, b, c = cirq.LineQubit.range(3)
    model_circuit = cirq.Circuit([
        cirq.Moment([cirq.X(a), cirq.Y(b), cirq.Z(c)]),
    ])

    with pytest.raises(AssertionError) as e:
        cirq.contrib.quantum_volume.compile_circuit(
            model_circuit,
            device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
            routing_attempts=0)
    assert e.match('Unable to get routing for circuit')
コード例 #9
0
def test_compile_circuit():
    """Tests that we are able to compile a model circuit."""
    compiler_mock = MagicMock(side_effect=lambda circuit: circuit)
    a, b, c = cirq.LineQubit.range(3)
    model_circuit = cirq.Circuit([
        cirq.Moment([cirq.X(a), cirq.Y(b), cirq.Z(c)]),
    ])
    compilation_result = cirq.contrib.quantum_volume.compile_circuit(
        model_circuit,
        device_graph=ccr.xmon_device_to_graph(cirq.google.Bristlecone),
        compiler=compiler_mock,
        routing_attempts=1)

    assert len(compilation_result.mapping) == 3
    assert cirq.contrib.routing.ops_are_consistent_with_device_graph(
        compilation_result.circuit.all_operations(),
        cirq.contrib.routing.xmon_device_to_graph(cirq.google.Bristlecone))
    compiler_mock.assert_called_with(compilation_result.circuit)
コード例 #10
0
def _fake_calib_data():
    err_graph = ccr.xmon_device_to_graph(Sycamore23)
    nx.set_edge_attributes(err_graph, 0.005, 'weight')
    nx.set_node_attributes(err_graph, 0.05, 'weight')
    return err_graph
コード例 #11
0
def compile_circuit(
    circuit: cirq.Circuit,
    *,
    device: cirq.google.XmonDevice,
    routing_attempts: int,
    compiler: Callable[[cirq.Circuit], cirq.Circuit] = None,
    routing_algo_name: Optional[str] = None,
    router: Optional[Callable[..., ccr.SwapNetwork]] = None,
    add_readout_error_correction=False,
) -> CompilationResult:
    """Compile the given model circuit onto the given device. This uses a
    different compilation method than described in
    https://arxiv.org/pdf/1811.12926.pdf Appendix A. The latter goes through a
    7-step process involving various decompositions, routing, and optimization
    steps. We route the model circuit and then run a series of optimizers on it
    (which can be passed into this function).

    Args:
        circuit: The model circuit to compile.
        device: The device to compile onto.
        routing_attempts: See doc for calculate_quantum_volume.
        compiler: An optional function to deconstruct the model circuit's
            gates down to the target devices gate set and then optimize it.
        add_readout_error_correction: If true, add some parity bits that will
            later be used to detect readout error.

    Returns: A tuple where the first value is the compiled circuit and the
        second value is the final mapping from the model circuit to the compiled
        circuit. The latter is necessary in order to preserve the measurement
        order.

    """
    compiled_circuit = circuit.copy()

    # Optionally add some the parity check bits.
    parity_map: Dict[cirq.Qid, cirq.Qid] = {}  # original -> parity
    if add_readout_error_correction:
        num_qubits = len(compiled_circuit.all_qubits())
        # Sort just to make it deterministic.
        for idx, qubit in enumerate(sorted(compiled_circuit.all_qubits())):
            # For each qubit, create a new qubit that will serve as its parity
            # check. This parity bit is initialized to 0 and then CNOTed with
            # the original qubit. Later, these two qubits will be checked for
            # equality - if they don't match, there was likely a readout error.
            qubit_num = idx + num_qubits
            parity_qubit = cirq.LineQubit(qubit_num)
            compiled_circuit.append(cirq.X(parity_qubit))
            compiled_circuit.append(cirq.CNOT(qubit, parity_qubit))
            parity_map[qubit] = parity_qubit

    # Swap Mapping (Routing). Ensure the gates can actually operate on the
    # target qubits given our topology.
    if router is None and routing_algo_name is None:
        # TODO: The routing algorithm sometimes does a poor job with the parity
        # qubits, adding SWAP gates that are unnecessary. This should be fixed,
        # or we can add the parity qubits manually after routing.
        routing_algo_name = 'greedy'

    swap_networks: List[ccr.SwapNetwork] = []
    for _ in range(routing_attempts):
        swap_network = ccr.route_circuit(compiled_circuit,
                                         ccr.xmon_device_to_graph(device),
                                         router=router,
                                         algo_name=routing_algo_name)
        swap_networks.append(swap_network)
    assert len(swap_networks) > 0, 'Unable to get routing for circuit'

    swap_networks.sort(key=lambda swap_network: len(swap_network.circuit))

    if not compiler:
        return CompilationResult(swap_network=swap_networks[0],
                                 parity_map=parity_map)

    # Compile. This should decompose the routed circuit down to a gate set that
    # our device supports, and then optimize. The paper uses various
    # compiling techniques - because Quantum Volume is intended to test those
    # as well, we allow this to be passed in. This compiler is not allowed to
    # change the order of the qubits.
    swap_networks[0].circuit = compiler(swap_networks[0].circuit)
    return CompilationResult(swap_network=swap_networks[0],
                             parity_map=parity_map)
コード例 #12
0
def test_xmon_device_to_graph():
    foxtail_graph = ccr.xmon_device_to_graph(cirq.google.Foxtail)
    two_by_eleven_grid_graph = ccr.get_grid_device_graph(2, 11)
    assert foxtail_graph.nodes == two_by_eleven_grid_graph.nodes
    assert foxtail_graph.edges() == two_by_eleven_grid_graph.edges()
コード例 #13
0
            simulator run extremely slowly for any width/depth of 4 or more,
            because it doubles the circuit size. In reality, the simulator
            shouldn't need to use this larger circuit for the majority of
            operations, since they only come into play at the end.

    Returns: A list of QuantumVolumeResults that contains all of the information
        for running the algorithm and its results.

    """
    circuits = prepare_circuits(num_qubits=num_qubits,
                                depth=depth,
                                num_circuits=num_circuits,
                                random_state=random_state)

    # Get the device graph from the given qubits or device.
    device_graph = None
    if isinstance(device_or_qubits, list):
        device_graph = ccr.gridqubits_to_graph_device(device_or_qubits)
    else:
        device_graph = ccr.xmon_device_to_graph(device_or_qubits)

    return execute_circuits(
        circuits=circuits,
        device_graph=device_graph,
        compiler=compiler,
        samplers=samplers,
        repetitions=repetitions,
        routing_attempts=routing_attempts,
        add_readout_error_correction=add_readout_error_correction,
    )
コード例 #14
0
def _qubit_index_edges(device, qubit_to_index):
    """Helper function in `_device_to_tket_device`"""
    dev_graph = ccr.xmon_device_to_graph(device)
    for n1, n2 in dev_graph.edges:
        yield qubit_to_index[n1], qubit_to_index[n2]
コード例 #15
0
def _qubit_index_edges(device):
    """Helper function in `_device_to_tket_device`"""
    dev_graph = ccr.xmon_device_to_graph(device)
    for n1, n2 in dev_graph.edges:
        yield Node('grid', n1.row, n1.col), Node('grid', n2.row, n2.col)