I-debug ang mga Qiskit Runtime job
Mga bersyon ng package
Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na requirements. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago pa.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
qiskit-aer~=0.17
Bago mag-submit ng resource-intensive na Qiskit Runtime workload para patakbuhin sa hardware, maaari mong gamitin ang Qiskit Runtime Neat (Noisy Estimator Analyzer Tool) class para ma-verify na tama ang setup ng iyong Estimator workload, malamang na magbabalik ito ng tumpak na resulta, gumagamit ng pinaka-angkop na mga opsyon para sa tinukoy na problema, at marami pa.
Ang Neat ay nag-Cliffordize ng mga input circuit para sa mas mahusay na simulation, habang pinapanatili ang istruktura at lalim nito. Ang mga Clifford circuit ay nakakaranas ng katulad na antas ng ingay at magandang proxy para pag-aralan ang orihinal na circuit na pinag-aaralan.
Ipinapakita ng mga sumusunod na halimbawa ang mga sitwasyon kung saan maaaring maging kapaki-pakinabang ang Neat.
Una, i-import ang mga kaugnay na package at mag-authenticate sa Qiskit Runtime service.
Ihanda ang kapaligiran​
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer qiskit-ibm-runtime
import numpy as np
import random
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit_ibm_runtime.debug_tools import Neat
from qiskit_aer.noise import NoiseModel, depolarizing_error
# Choose the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Generate a preset pass manager
# This will be used to convert the abstract circuit to an equivalent Instruction Set Architecture (ISA) circuit.
pm = generate_preset_pass_manager(backend=backend, optimization_level=0)
# Set the random seed
random.seed(10)
I-initialize ang target na circuit​
Isaalang-alang ang isang anim-na-qubit circuit na may mga sumusunod na katangian:
- Nagpapalitan sa pagitan ng mga random na
RZrotation at mga layer ngCNOTgate. - May mirror na istruktura, ibig sabihin, nag-apply ito ng unitary
Ukasunod ang inverse nito.
def generate_circuit(n_qubits, n_layers):
r"""
A function to generate a pseudo-random a circuit with ``n_qubits`` qubits and
``2*n_layers`` entangling layers of the type used in this notebook.
"""
# An array of random angles
angles = [
[random.random() for q in range(n_qubits)] for s in range(n_layers)
]
qc = QuantumCircuit(n_qubits)
qubits = list(range(n_qubits))
# do random circuit
for layer in range(n_layers):
# rotations
for q_idx, qubit in enumerate(qubits):
qc.rz(angles[layer][q_idx], qubit)
# cx gates
control_qubits = (
qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]
)
for qubit in control_qubits:
qc.cx(qubit, qubit + 1)
# undo random circuit
for layer in range(n_layers)[::-1]:
# cx gates
control_qubits = (
qubits[::2] if layer % 2 == 0 else qubits[1 : n_qubits - 1 : 2]
)
for qubit in control_qubits:
qc.cx(qubit, qubit + 1)
# rotations
for q_idx, qubit in enumerate(qubits):
qc.rz(-angles[layer][q_idx], qubit)
return qc
# Generate a random circuit
qc = generate_circuit(6, 3)
# Convert the abstract circuit to an equivalent ISA circuit.
isa_qc = pm.run(qc)
qc.draw("mpl", idle_wires=0)
Pumili ng single-Pauli Z operator bilang mga observable at gamitin ang mga ito para i-initialize ang mga primitive unified bloc (PUB).
# Initialize the observables
obs = ["ZIIIII", "IZIIII", "IIZIII", "IIIZII", "IIIIZI", "IIIIIZ"]
print(f"Observables: {obs}")
# Map the observables to the backend's layout
isa_obs = [SparsePauliOp(o).apply_layout(isa_qc.layout) for o in obs]
# Initialize the PUBs, which consist of six-qubit circuits with `n_layers` 1, ..., 6
all_n_layers = [1, 2, 3, 4, 5, 6]
pubs = [(pm.run(generate_circuit(6, n)), isa_obs) for n in all_n_layers]
Observables: ['ZIIIII', 'IZIIII', 'IIZIII', 'IIIZII', 'IIIIZI', 'IIIIIZ']
I-Cliffordize ang mga circuit​
Ang mga PUB circuit na tinukoy kanina ay hindi Clifford, kaya mahirap i-simulate nang klasikal. Gayunpaman, maaari mong gamitin ang Neat to_clifford method para i-map ang mga ito sa mga Clifford circuit para sa mas mahusay na simulation. Ang to_clifford method ay isang wrapper sa paligid ng ConvertISAToClifford transpiler pass, na maaari ring gamitin nang hiwalay. Sa partikular, pinapalitan nito ang mga non-Clifford single-qubit gate sa orihinal na circuit ng mga Clifford single-qubit gate, ngunit hindi nito binabago ang mga two-qubit gate, bilang ng qubit, o lalim ng circuit.
Tingnan ang Efficient simulation of stabilizer circuits with Qiskit Aer primitives para sa karagdagang impormasyon tungkol sa Clifford circuit simulation.
Una, i-initialize ang Neat.
# You could specify a custom `NoiseModel` here. If `None`, `Neat`
# pulls the noise model from the given backend
noise_model = None
# Initialize `Neat`
analyzer = Neat(backend, noise_model)
Susunod, i-Cliffordize ang mga PUB.
clifford_pubs = analyzer.to_clifford(pubs)
clifford_pubs[0].circuit.draw("mpl", idle_wires=0)
Aplikasyon 1: Suriin ang epekto ng ingay sa mga output ng circuit​
Ipinapakita ng halimbawang ito kung paano gamitin ang Neat para pag-aralan ang epekto ng iba't ibang noise model sa mga PUB bilang function ng lalim ng circuit sa pamamagitan ng pagpapatakbo ng mga simulation sa parehong ideal (ideal_sim) at maingay (noisy_sim) na kondisyon. Maaari itong maging kapaki-pakinabang para magtakda ng inaasahan sa kalidad ng mga eksperimental na resulta bago magpatakbo ng job sa QPU. Para matuto pa tungkol sa mga noise model, tingnan ang Exact and noisy simulation with Qiskit Aer primitives.
Ang mga simulate na resulta ay sumusuporta sa mga mathematical na operasyon, at samakatuwid ay maaaring ikumpara sa isa't isa (o sa mga eksperimental na resulta) para kalkulahin ang mga figure of merit.
Ang QPU ay maaaring maapektuhan ng iba't ibang uri ng ingay. Ang Qiskit Aer noise model na ginagamit dito ay nag-simulate lamang ng ilan sa mga ito at samakatuwid ay malamang na hindi gaanong matindi kumpara sa ingay sa tunay na QPU.
Para sa mga detalye kung anong mga error ang kasama kapag nag-initialize ng noise model mula sa isang QPU, tingnan ang Aer NoiseModel API reference.
Magsimula sa pagsasagawa ng ideal at maingay na klasikal na simulation.
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
print(f"Ideal results:\n {ideal_results}\n")
# Perform a noisy simulation with the backend's noise model
noisy_results = analyzer.noisy_sim(clifford_pubs)
print(f"Noisy results:\n {noisy_results}\n")
Ideal results:
NeatResult([NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.])), NeatPubResult(vals=array([1., 1., 1., 1., 1., 1.]))])
Noisy results:
NeatResult([NeatPubResult(vals=array([0.99023438, 0.99609375, 0.9921875 , 0.99023438, 0.99414062,
0.99414062])), NeatPubResult(vals=array([0.984375 , 0.99414062, 0.98242188, 0.98828125, 0.98632812,
0.99414062])), NeatPubResult(vals=array([0.96679688, 0.97070312, 0.95898438, 0.97851562, 0.98046875,
0.98828125])), NeatPubResult(vals=array([0.9453125 , 0.953125 , 0.97070312, 0.96875 , 0.98242188,
0.99023438])), NeatPubResult(vals=array([0.93164062, 0.9375 , 0.953125 , 0.96875 , 0.96484375,
0.98046875])), NeatPubResult(vals=array([0.92578125, 0.921875 , 0.93359375, 0.953125 , 0.95898438,
0.9765625 ]))])
Susunod, mag-apply ng mga mathematical na operasyon para kalkulahin ang absolute difference. Ang natitirang bahagi ng gabay ay gumagamit ng absolute difference bilang figure of merit para ikumpara ang mga ideal na resulta sa mga maingay o eksperimental na resulta, ngunit maaari ring mag-set up ng katulad na mga figure of merit.
Ipinapakita ng absolute difference na lumalaki ang epekto ng ingay habang lumalaki ang laki ng mga circuit.
# Figure of merit: Absolute difference
def rdiff(res1, re2):
r"""The absolute difference between `res1` and re2`.
--> The closer to `0`, the better.
"""
d = abs(res1 - re2)
return np.round(d.vals * 100, 2)
for idx, (ideal_res, noisy_res) in enumerate(
zip(ideal_results, noisy_results)
):
vals = rdiff(ideal_res, noisy_res)
# Print the mean absolute difference for the observables
mean_vals = np.round(np.mean(vals), 2)
print(
f"Mean absolute difference between ideal and noisy results for circuits with {all_n_layers[idx]} layers:\n {mean_vals}%\n"
)
Mean absolute difference between ideal and noisy results for circuits with 1 layers:
0.72%
Mean absolute difference between ideal and noisy results for circuits with 2 layers:
1.17%
Mean absolute difference between ideal and noisy results for circuits with 3 layers:
2.6%
Mean absolute difference between ideal and noisy results for circuits with 4 layers:
3.16%
Mean absolute difference between ideal and noisy results for circuits with 5 layers:
4.4%
Mean absolute difference between ideal and noisy results for circuits with 6 layers:
5.5%
Maaari mong sundin ang mga magaspang at simplipikadong alituntuning ito para mapabuti ang mga circuit ng ganitong uri:
- Kung ang mean absolute difference ay mas malaki sa 90%, malamang na hindi makakatulong ang mitigation.
- Kung ang mean absolute difference ay mas mababa sa 90%, malamang na mapapabuti ng Probabilistic Error Amplification (PEA) ang mga resulta.
- Kung ang mean absolute difference ay mas mababa sa 80%, malamang na mapapabuti rin ng ZNE with gate folding ang mga resulta.
Dahil lahat ng absolute difference sa itaas ay mas mababa sa 90%, ang pag-apply ng PEA sa orihinal na circuit ay malamang na magpapabuti ng kalidad ng mga resulta nito. Maaari kang tumukoy ng iba't ibang noise model sa analyzer. Ipinapakita ng sumusunod na halimbawa ang parehong test ngunit may dagdag na custom na noise model.
# Set up a noise model with strength 0.02 on every two-qubit gate
noise_model = NoiseModel()
for qubits in backend.coupling_map:
noise_model.add_quantum_error(
depolarizing_error(0.02, 2), ["ecr", "cx"], qubits
)
# Update the analyzer's noise model
analyzer.noise_model = noise_model
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
# Perform a noisy simulation with the backend's noise model
noisy_results = analyzer.noisy_sim(clifford_pubs)
# Compare the results
for idx, (ideal_res, noisy_res) in enumerate(
zip(ideal_results, noisy_results)
):
values = rdiff(ideal_res, noisy_res)
# Print the mean absolute difference for the observables
mean_values = np.round(np.mean(values), 2)
print(
f"Mean absolute difference between ideal and noisy results for circuits with {all_n_layers[idx]} layers:\n {mean_values}%\n"
)
Mean absolute difference between ideal and noisy results for circuits with 1 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 2 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 3 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 4 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 5 layers:
0.0%
Mean absolute difference between ideal and noisy results for circuits with 6 layers:
0.0%
Tulad ng ipinapakita, sa isang noise model, maaari mong subukang sukatin ang epekto ng ingay sa (Cliffordized na bersyon ng) mga PUB na pinag-aaralan bago patakbuhin ang mga ito sa QPU.
Aplikasyon 2: I-benchmark ang iba't ibang estratehiya​
Ginagamit ng halimbawang ito ang Neat para matukoy ang pinakamabuting mga opsyon para sa iyong mga PUB. Para gawin ito, isaalang-alang ang pagpapatakbo ng estimation problem gamit ang PEA, na hindi maaaring i-simulate gamit ang qiskit_aer. Maaari mong gamitin ang Neat para matukoy kung aling mga noise amplification factor ang pinaka-epektibo, pagkatapos ay gamitin ang mga factor na iyon kapag pinatakbo ang orihinal na eksperimento sa QPU.
# Generate a circuit with six qubits and six layers
isa_qc = pm.run(generate_circuit(6, 3))
# Use the same observables as previously
pubs = [(isa_qc, isa_obs)]
clifford_pubs = analyzer.to_clifford(pubs)
noise_factors = [
[1, 1.1],
[1, 1.1, 1.2],
[1, 1.5, 2],
[1, 1.5, 2, 2.5, 3],
[1, 4],
]
# Run the PUBs on a QPU
estimator = Estimator(backend)
estimator.options.default_shots = 100000
estimator.options.twirling.enable_gates = True
estimator.options.twirling.enable_measure = True
estimator.options.twirling.shots_per_randomization = 100
estimator.options.resilience.measure_mitigation = True
estimator.options.resilience.zne_mitigation = True
estimator.options.resilience.zne.amplifier = "pea"
jobs = []
for factors in noise_factors:
estimator.options.resilience.zne.noise_factors = factors
jobs.append(estimator.run(clifford_pubs))
results = [job.result() for job in jobs]
# Perform a noiseless simulation
ideal_results = analyzer.ideal_sim(clifford_pubs)
# Look at the mean absolute difference to quickly tell the best choice for your options
for factors, res in zip(noise_factors, results):
d = rdiff(ideal_results[0], res[0])
print(
f"Mean absolute difference for factors {factors}:\n {np.round(np.mean(d), 2)}%\n"
)
Mean absolute difference for factors [1, 1.1]:
6.83%
Mean absolute difference for factors [1, 1.1, 1.2]:
8.76%
Mean absolute difference for factors [1, 1.5, 2]:
8.03%
Mean absolute difference for factors [1, 1.5, 2, 2.5, 3]:
10.17%
Mean absolute difference for factors [1, 4]:
8.02%
Ang resulta na may pinakamaliit na pagkakaiba ay nagmumungkahi kung anong mga opsyon ang pipiliin.
Mga susunod na hakbang​
- Matuto tungkol sa Exact and noisy simulation with Qiskit Aer primitives.
- Matuto tungkol sa mga available na Qiskit Runtime option.
- Matuto tungkol sa mga teknik ng Error mitigation at suppression.
- Bisitahin ang paksa na Transpile with pass managers.
- Matuto kung paano mag-transpile ng mga circuit bilang bahagi ng mga Qiskit patterns workflow gamit ang Qiskit Runtime.
- Suriin ang Debugging tools API documentation.