Skip to main content
IBM Quantum Platform

Schnellstart

Diese Anleitung zeigt ein minimales, funktionsfähiges Beispiel für das qiskit-paulice Paket. Wir nutzen Raumzeit-Pauli-Prüfungen, um Fehler während der Ausführung eines Clifford-Schaltkreises zu erkennen, und wählen anschließend nur diejenigen Stichproben aus, bei denen kein Fehler festgestellt wurde. Einen ausführlicheren End-to-End-Workflow, der die Verbesserung der Wiedergabetreue quantifiziert, finden Sie im ausführlichen Tutorial.

Workflowschritte

  1. Bereiten Sie die Eingaben vor: eine Clifford-Payload-Schaltung, die Ziel- und Ancilla-Qubits für die Checks sowie ein Rauschmodell.
  2. Finde geeignete Pauli-Prüfungen für die Raumzeit und füge sie dem Schaltkreis hinzu.
  3. Messen Sie die geprüfte Schaltung.
  4. Wählen Sie anschließend nur die Proben aus, bei denen kein Fehler festgestellt wurde.

1. Bereiten Sie die Eingaben vor

add_pauli_checks als Eingabe eine Cliff ord-Schaltung mit mindestens einer Endpunktmessung, die Ziel-Qubits, die zur Implementierung der Prüfungen verwendet werden sollen, sowie ein Rauschmodell, das zur Bewertung der in Frage kommenden Prüfungen dient. ibm_bostonHier bauen wir eine flache zufällige Clifford-Schaltung auf, ordnen sie auf einer „ 1D “-Kette physikalischer Qubits an, ordnen jedem Payload-Qubit ein benachbartes Ancilla-Qubit zu (sodass für eine Überprüfung keine SWAP-Gatter benötigt werden) und leiten aus Backend-Benchmark-Daten ein grobes Modell für depolarisierendes Rauschen ab.

import numpy as np
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_paulice.layout import get_check_qubits
from qiskit_paulice.noise_models import NoiseModel

# Backend and a 1D chain of physical qubits to run on
backend = QiskitRuntimeService().backend("ibm_boston")
layout = [68, 69, 78, 89, 90, 91, 98, 111, 112, 113, 119, 133]

# A shallow brickwork random Clifford payload circuit
rng = np.random.default_rng(1764)
circuit = QuantumCircuit(len(layout))
circuit.h(range(circuit.num_qubits))
for d in range(4):
    for i in range(d % 2, circuit.num_qubits - 1, 2):
        circuit.cz(i, i + 1)
    for q in range(circuit.num_qubits):
        if rng.integers(0, 2):
            circuit.sx(q)
        if rng.integers(0, 2):
            circuit.s(q)
circuit.measure_all()

# Pair each payload qubit with a neighboring ancilla to host a check (no SWAPs needed)
target_qubits, ancilla_qubits = get_check_qubits(backend.coupling_map, layout)

# A rough depolarizing noise model from backend benchmark data, used to score checks
noise_model = NoiseModel.from_backend(
    backend, layout, uniform_gate_noise=True
)

circuit.draw("mpl", fold=-1)

Output:

Output of the previous code cell

2. Raumzeit-Pauli-Prüfungen suchen und hinzufügen

add_pauli_checks sucht nach effektiven, gewichtsarmen Prüfungen für jedes Ziel-Qubit, fügt diese dem Schaltkreis hinzu und gibt eine Folge von CheckedCircuit Instanzen zurück. Die CheckedCircuit Instanzen enthalten eine steigende Anzahl von Prüfungen, von 0 Prüfungen bis hin zu einer Prüfung pro Ziel-Qubit. Jede Überprüfung verbessert die Fehlererkennungsfähigkeit, was jedoch mit einer geringfügig höheren Schaltungstiefe einhergeht. In diesem Beispiel verwenden wir die Schaltung, bei der jedes Ziel-Qubit überprüft wird.

from qiskit_paulice import add_pauli_checks

# The circuit has virtual qubits, so we specify our target qubits with virtual indices
target_qubits_v = [layout.index(q) for q in target_qubits]

# Add spacetime Pauli checks
checked_circuit = add_pauli_checks(circuit, target_qubits_v, noise_model)[-1]
checked_circuit.circuit.draw("mpl", fold=-1, scale=0.4, idle_wires=False)

Output:

Output of the previous code cell

3. Die geprüfte Schaltung abtasten

ibm_bostonBevor wir eine Abtastung durchführen, transpilieren wir die geprüfte Schaltung auf physikalische Qubits (initial_layout = layout + ancilla_qubits) und in den nativen Basis-Gatensatz von. Um eine verrauschte QPU zu emulieren, führen wir eine Stichprobenauswertung mit einem verrauschten Aer-Stabilisator-Backend durch, dessen Fehlerraten mit denen noise_model übereinstimmen, die zur Auswahl der Prüfzahlen verwendet wurden.

from qiskit import transpile
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel as AerNoiseModel
from qiskit_aer.noise import ReadoutError, depolarizing_error

# Transpile once: lay the checked circuit out on our qubits and into the native basis
isa_circuit = transpile(
    checked_circuit.circuit,
    backend,
    initial_layout=layout + ancilla_qubits,
    optimization_level=0,
)

# Build an Aer noise model matching the depolarizing model used to pick checks
aer_noise = AerNoiseModel()
aer_noise.add_all_qubit_quantum_error(
    depolarizing_error(noise_model.gate_noise, 2), ["cz"]
)
p = noise_model.readout_noise
aer_noise.add_all_qubit_readout_error(ReadoutError([[1 - p, p], [p, 1 - p]]))
simulator = AerSimulator(method="stabilizer", noise_model=aer_noise)

counts = (
    simulator.run(isa_circuit, shots=1000, seed_simulator=1764)
    .result()
    .get_counts()
)
print(f"sampled {sum(counts.values())} shots")

Output:

sampled 1000 shots

4. Proben, bei denen nach der Auswahl kein Fehler festgestellt wurde

get_postselection_method ordnet jeden Schuss seinem Syndromvektor zu; wir behalten nur die Schüsse mit einem Syndrom, das ausschließlich aus Nullen besteht – also diejenigen, bei denen bei keiner Prüfung ein Fehler festgestellt wurde. Durch das Verwerfen der markierten Aufnahmen werden erkannte Fehler aus der verbleibenden Verteilung entfernt, wodurch deren Genauigkeit verbessert wird – allerdings auf Kosten einer geringeren Abtastrate. Einen quantitativen Vergleich der Genauigkeit finden Sie im Tutorial.

# Keep only the shots in which no check reported an error
ps_fn = checked_circuit.get_postselection_method()
counts_postselected = {
    bs: n for bs, n in counts.items() if not ps_fn(bs).any()
}

kept, total = sum(counts_postselected.values()), sum(counts.values())
print(f"kept {kept} of {total} shots ({kept / total:.0%})")

Output:

kept 927 of 1000 shots (93%)
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.