Přeskočit na hlavní obsah

Zmírnění chyb s IBM Circuit function

Poznámka

Qiskit Functions jsou experimentální funkce dostupné pouze uživatelům plánů IBM Quantum® Premium Plan, Flex Plan a On-Prem (přes IBM Quantum Platform API). Jsou ve stavu předběžného vydání a mohou se změnit.

Odhad využití: 26 minut na procesoru Eagle (POZNÁMKA: Jedná se pouze o odhad. Skutečná doba běhu se může lišit.) Tento tutoriál provede příkladem sestavení a spuštění pracovního postupu pomocí IBM Circuit function. Tato funkce přijímá Primitive Unified Blocs (PUBs) jako vstupy a vrací očekávané hodnoty se zmírněnými chybami jako výstupy. Poskytuje automatizovaný a přizpůsobený pipeline pro optimalizaci Circuit a spuštění na kvantovém hardwaru, takže se výzkumníci mohou soustředit na objevování algoritmů a aplikací.

Navštiv dokumentaci pro úvod do Qiskit Functions a zjisti, jak začít s IBM Circuit function.

Pozadí

Tento tutoriál uvažuje obecný hardwarově efektivní Trotterizovaný obvod časového vývoje pro 2D transverzální Isingův model a počítá globální magnetizaci. Takový Circuit je užitečný v různých aplikačních oblastech, jako je fyzika kondenzované hmoty, chemie a strojové učení. Více informací o struktuře tohoto modelu najdeš v Nature 618, 500–505 (2023).

IBM Circuit function kombinuje možnosti ze služby Qiskit transpiler a Qiskit Runtime Estimator a poskytuje zjednodušené rozhraní pro spouštění Circuit. Funkce provádí transpilaci, potlačení chyb, zmírnění chyb a provádění Circuit v rámci jediné spravované služby, takže se můžeme soustředit na mapování problému na Circuit, místo abychom sami budovali každý krok vzoru.

Požadavky

Před zahájením tohoto tutoriálu se ujisti, že máš nainstalováno následující:

  • Qiskit SDK v1.2 nebo novější (pip install qiskit)
  • Qiskit Runtime v0.28 nebo novější (pip install qiskit-ibm-runtime)
  • IBM Qiskit Functions Catalog client v0.0.0 nebo novější (pip install qiskit-ibm-catalog)
  • Qiskit Aer v0.15.0 nebo novější (pip install qiskit-aer)

Nastavení

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-catalog qiskit-ibm-runtime rustworkx
import rustworkx
from collections import defaultdict
from numpy import pi, mean

from qiskit_ibm_runtime import QiskitRuntimeService

from qiskit_ibm_catalog import QiskitFunctionsCatalog

from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.quantum_info import SparsePauliOp

Krok 1: Mapování klasických vstupů na kvantový problém

  • Vstup: Parametry pro vytvoření kvantového Circuit
  • Výstup: Abstraktní Circuit a observables

Sestavení Circuit

Circuit, který vytvoříme, je hardwarově efektivní Trotterizovaný obvod časového vývoje pro 2D transverzální Isingův model. Začínáme výběrem Backend. Vlastnosti tohoto Backend (tedy jeho coupling map) budou použity k definování kvantového problému a zajistí jeho hardwarovou efektivitu.

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

Dále získáme coupling map z Backend.

coupling_graph = backend.coupling_map.graph.to_undirected(multigraph=False)
layer_couplings = defaultdict(list)

Musíme být opatrní v tom, jak navrhujeme vrstvy našeho Circuit. Uděláme to obarvením hran coupling map (tedy seskupením disjunktních hran) a použijeme toto obarvení k efektivnějšímu umístění Gate v Circuit. To povede k mělčímu Circuit s vrstvami Gate, které lze na hardwaru provádět současně.

edge_coloring = rustworkx.graph_bipartite_edge_color(coupling_graph)

for edge_idx, color in edge_coloring.items():
layer_couplings[color].append(
coupling_graph.get_edge_endpoints_by_index(edge_idx)
)
layer_couplings = [
sorted(layer_couplings[i]) for i in sorted(layer_couplings.keys())
]

Dále napíšeme jednoduchou pomocnou funkci, která implementuje hardwarově efektivní Trotterizovaný obvod časového vývoje pro 2D transverzální Isingův model pomocí výše získaného obarvení hran.

def construct_trotter_circuit(
num_qubits: int,
num_trotter_steps: int,
layer_couplings: list,
barrier: bool = True,
) -> QuantumCircuit:
theta, phi = Parameter("theta"), Parameter("phi")
circuit = QuantumCircuit(num_qubits)

for _ in range(num_trotter_steps):
circuit.rx(theta, range(num_qubits))
for layer in layer_couplings:
for edge in layer:
if edge[0] < num_qubits and edge[1] < num_qubits:
circuit.rzz(phi, edge[0], edge[1])
if barrier:
circuit.barrier()

return circuit

Zvolíme počet Qubit a Trotterových kroků a pak sestavíme Circuit.

num_qubits = 100
num_trotter_steps = 2

circuit = construct_trotter_circuit(
num_qubits, num_trotter_steps, layer_couplings
)
circuit.draw("mpl", fold=-1)

Output of the previous code cell

Abychom mohli porovnat kvalitu spuštění s ideálním výsledkem, musíme jej porovnat s ideálním výsledkem. Zvolený Circuit přesahuje možnosti hrubé síly klasické simulace. Proto zafixujeme parametry všech Gate Rx v Circuit na 00 a všech Gate Rzz na π\pi. Tím se Circuit stane Cliffordovým, což umožňuje provést ideální simulaci a získat ideální výsledek pro porovnání. V tomto případě víme, že výsledek bude 1.0.

parameters = [0, pi]

Sestavení observable

Nejprve vypočítej globální magnetizaci podél z^\hat{z} pro problém s NN Qubit: Mz=i=1NZi/NM_z = \sum_{i=1}^N \langle Z_i \rangle / N. To vyžaduje nejprve výpočet magnetizace jednotlivých míst Zi\langle Z_i \rangle pro každý Qubit ii, která je definována v následujícím kódu.

observables = []
for i in range(num_qubits):
obs = "I" * (i) + "Z" + "I" * (num_qubits - i - 1)
observables.append(SparsePauliOp(obs))

print(observables[0])
SparsePauliOp(['ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],
coeffs=[1.+0.j])

Kroky 2 a 3: Optimalizace problému pro spuštění na kvantovém hardwaru a spuštění s IBM Circuit function

  • Vstup: Abstraktní Circuit a observables
  • Výstup: Zmírněné očekávané hodnoty

Nyní můžeme předat abstraktní Circuit a observables IBM Circuit function. Ta za nás zajistí transpilaci a spuštění na kvantovém hardwaru a vrátí zmírněné očekávané hodnoty. Nejprve načteme funkci z IBM Qiskit Functions Catalog.

catalog = QiskitFunctionsCatalog(
token="<YOUR_API_KEY>"
) # Use the 44-character API_KEY you created and saved from the IBM Quantum Platform Home dashboard
function = catalog.load("ibm/circuit-function")

IBM Circuit function přijímá pubs, backend_name a také volitelné vstupy pro konfiguraci transpilace, zmírnění chyb a podobně. Vytvoříme pub z abstraktního Circuit, observables a parametrů Circuit. Název Backend by měl být zadán jako řetězec.

pubs = [(circuit, observables, parameters)]
backend_name = backend.name

Můžeme také nakonfigurovat options pro transpilaci, potlačení chyb a zmírnění chyb. Pokud je nechceme specifikovat, budou použita výchozí nastavení. IBM Circuit function přichází s běžně používanými možnostmi pro optimization_level, který řídí rozsah optimalizace Circuit, a mitigation_level, který určuje míru potlačení a zmírnění chyb. Upozorňujeme, že mitigation_level IBM Circuit function se liší od resilience_level používaného v Qiskit Runtime Estimator. Podrobný popis těchto běžně používaných možností i dalších pokročilých možností najdeš v dokumentaci pro IBM Circuit function.

V tomto tutoriálu nastavíme default_precision, optimization_level: 3 a mitigation_level: 3, což zapne gate twirling a Zero Noise Extrapolation (ZNE) prostřednictvím Probabilistic Error Amplification (PEA) nad výchozím nastavením úrovně 1.

options = {
"default_precision": 0.011,
"optimization_level": 3,
"mitigation_level": 3,
}

Po zadání vstupů odešleme úlohu do IBM Circuit function pro optimalizaci a spuštění.

job = function.run(backend_name=backend_name, pubs=pubs, options=options)

Krok 4: Post-processing a vrácení výsledku v požadovaném klasickém formátu

  • Vstup: Výsledky z IBM Circuit function
  • Výstup: Globální magnetizace

Výpočet globální magnetizace

Výsledek spuštění funkce má stejný formát jako výstup Estimator.

result = job.result()[0]

Z tohoto výsledku získáme zmírněné a nezmírněné očekávané hodnoty. Tyto očekávané hodnoty představují magnetizaci jednotlivých míst podél směru z^\hat{z}. Zprůměrujeme je, abychom získali globální magnetizaci, a porovnáme s ideální hodnotou 1.0 pro tuto instanci problému.

mitigated_expvals = result.data.evs
magnetization_mitigated = mean(mitigated_expvals)

print("mitigated:", magnetization_mitigated)

unmitigated_expvals = [
result.data.evs_extrapolated[i][0][1] for i in range(num_qubits)
]
magnetization_unmitigated = mean(unmitigated_expvals)

print("unmitigated:", magnetization_unmitigated)
mitigated: 0.9749883476088692
unmitigated: 0.7832977198447583

Průzkum k tutoriálu

Vyplň prosím tento krátký průzkum a poskytni zpětnou vazbu k tomuto tutoriálu. Tvé poznatky nám pomohou zlepšit naše obsahové nabídky a uživatelský zážitek.

Odkaz na průzkum

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.