Skip to main content
IBM Quantum Platform

Avvio rapido

Questa guida illustra un esempio minimale funzionante del qiskit-paulice pacchetto. Utilizziamo i controlli di Pauli nello spazio-tempo per rilevare gli errori durante l'esecuzione di un circuito di Clifford, quindi selezioniamo a posteriori solo i campioni per i quali non è stato rilevato alcun errore. Per un flusso di lavoro completo e più dettagliato che quantifichi il miglioramento della fedeltà, consulta il tutorial approfondito.

Passi del flusso di lavoro

  1. Preparare gli input: un circuito di carico Clifford, i qubit target/ancilla su cui eseguire i controlli e un modello di rumore.
  2. Trova dei buoni controlli di Pauli nello spazio-tempo e aggiungili al circuito.
  3. Verificare il funzionamento del circuito contrassegnato.
  4. Selezionare solo i campioni per i quali non è stato rilevato alcun errore.

1. Preparare i dati di input

add_pauli_checks richiede un circuito di Clifford con almeno una misurazione terminale, i qubit di destinazione che saranno utilizzati per implementare i controlli e un modello di rumore utilizzato per valutare i controlli candidati. ibm_bostonIn questa sede costruiamo un circuito Clifford casuale a profondità ridotta, lo disponiamo su una catena di qubit fisici di tipo “ 1D ”, accoppiamo ciascun qubit di payload con un qubit ancilla adiacente (in modo che un controllo non richieda porte SWAP) e deduciamo un modello approssimativo di rumore depolarizzante dai dati dei benchmark del backend.

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. Individuare e aggiungere i controlli di Pauli nello spazio-tempo

add_pauli_checks cerca controlli efficaci e a basso peso per ciascun qubit di destinazione e li aggiunge al circuito, restituendo una sequenza di CheckedCircuit istanze. Le CheckedCircuit istanze contengono un numero crescente di controlli, che va da 0 controlli fino a un controllo per ogni qubit bersaglio. Ogni controllo migliora la capacità di rilevamento degli errori, a scapito di un leggero aumento della profondità del circuito. In questo esempio useremo il circuito che prevede un controllo su ogni qubit di destinazione.

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. Effettuare il campionamento del circuito controllato

ibm_bostonPrima di eseguire il campionamento, trasponiamo il circuito verificato sui qubit fisici (initial_layout = layout + ancilla_qubits) e nel set di gate della base nativa di. Per emulare una QPU soggetta a rumore, effettuiamo il campionamento utilizzando un backend stabilizzatore Aer soggetto a rumore, i cui tassi di errore corrispondono a quelli noise_model utilizzati per la selezione dei controlli.

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. Campioni post-selezione in cui non è stato rilevato alcun errore

get_postselection_method assegna a ogni scatto il proprio vettore di sindrome; conserviamo solo gli scatti con una sindrome composta interamente da zeri, ovvero quelli in cui nessun controllo ha rilevato un errore. L'eliminazione degli scatti contrassegnati rimuove gli errori rilevati dalla distribuzione rimanente, migliorandone la fedeltà a scapito di una frequenza di campionamento inferiore. Consulta il tutorial per un confronto quantitativo della fedeltà.

# 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%)
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.