Sari la conținutul principal
Acest proiect este în versiune beta. Ai găsit o eroare? Deschide un issue pe GitHub. Ai o întrebare sau o idee? Întreabă în Discussions — ne-ar plăcea să aflăm părerea ta!
Cum este calitatea traducerii pe această pagină?

Hardware

notă

Masao Tokunari și Tamiya Onodera (14 iunie 2024)

Acest curs se bazează pe un curs live susținut la Universitatea din Tokyo.

PDF-ul cu slide-urile acestei lecții a fost împărțit în două părți. Descarcă partea 1 și descarcă partea 2. Reține că unele fragmente de cod ar putea deveni învechite, deoarece acestea sunt imagini statice.

1. Introducere​

Această lecție explorează hardware-ul modern de calcul cuantic.

Vom începe prin a verifica unele versiuni și a importa câteva pachete relevante.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import statistics

from qiskit_ibm_runtime import QiskitRuntimeService

2. Backend și Target​

Qiskit oferă un API pentru a obține informații, atât statice cât și dinamice, despre un dispozitiv cuantic. Folosim o instanță Backend pentru a interacționa cu un dispozitiv, care include o instanță Target — un model abstract de mașină ce rezumă caracteristicile relevante, cum ar fi arhitectura setului de instrucțiuni (ISA) și orice proprietăți sau constrângeri asociate acestuia. Să folosim aceste instanțe backend pentru a obține unele dintre informațiile pe care le vezi pe pagina Resurse de calcul din IBM Quantum® Platform. Mai întâi, creăm o instanță backend pentru un dispozitiv de interes. În cele ce urmează, alegem „ibm_kyoto", „ibm_kawasaki" sau cel mai puțin ocupat procesor Eagle. Accesul tău la QPU-uri poate fi diferit; actualizează numele backend-ului în consecință.

service = QiskitRuntimeService()
# backend = service.backend("ibm_kawasaki") # an Eagle, if you have access to ibm_kawasaki
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
) # Eagle
backend.name
'ibm_strasbourg'

Începem cu câteva informații de bază (statice) despre dispozitiv.

print(
f"""
{backend.name}, {backend.num_qubits} qubits
processor type = {backend.processor_type}
basis gates = {backend.basis_gates}
"""
)
ibm_strasbourg, 127 qubits
processor type = {'family': 'Eagle', 'revision': 3}
basis gates = ['ecr', 'id', 'rz', 'sx', 'x']

2.1 Exercițiu​

Încearcă să obții informațiile de bază despre un dispozitiv Heron, „ibm_strasbourg". Încearcă pe cont propriu, dar mai jos a fost adăugat cod pentru a te putea verifica.

a_heron = service.backend("ibm_strasbourg") # a Heron

# your code here
print(
f"""
{backend.name}, {a_heron.num_qubits} qubits
processor type = {a_heron.processor_type}
basis gates = {a_heron.basis_gates}
"""
)
ibm_strasbourg, 133 qubits
processor type = {'family': 'Heron', 'revision': '1'}
basis gates = ['cz', 'id', 'rz', 'sx', 'x']

2.2 Harta de cuplare​

Acum desenăm harta de cuplare a dispozitivului. Cum poți vedea, nodurile sunt qubiți numerotați. Muchiile indică perechile de qubiți cărora le poți aplica direct poarta cu 2 qubiți care generează entanglement. Topologia se numește „rețea heavy-hex".

# This function requires that Graphviz is installed. If you need to install Graphviz
# you can refer to:
# https://graphviz.org/download/#executable-packages for instructions.
try:
fig = backend.coupling_map.draw()
except RuntimeError as ex:
print(ex)
fig

Output of the previous code cell

3. Proprietățile qubiților​

Dispozitivul Eagle are 127 de qubiți. Să obținem proprietățile unora dintre ei.

for qn in range(backend.num_qubits):
if qn >= 5:
break
print(f"{qn}: {backend.qubit_properties(qn)}")
0: QubitProperties(t1=0.000183686508736532, t2=0.00023613944465408068, frequency=4832100227.116953)
1: QubitProperties(t1=0.00048794378526038294, t2=9.007098375327869e-05, frequency=4736264354.075363)
2: QubitProperties(t1=0.00021247781834456527, t2=7.81037910324034e-05, frequency=4859349851.150393)
3: QubitProperties(t1=0.0002936462084765663, t2=0.00011400214529510604, frequency=4679749549.503852)
4: QubitProperties(t1=0.00044229440258559125, t2=0.0003181648356339447, frequency=4845872064.050596)

Să calculăm mediana timpilor T1 ai qubiților. Compară rezultatul cu cel afișat pentru dispozitiv pe IBM Quantum Platform.

t1s = [backend.qubit_properties(qq).t1 for qq in range(backend.num_qubits)]
f"Median T1: {(statistics.median(t1s)*10**6):.2f} \u03bcs"
'Median T1: 285.43 μs'

3.1 Exercițiu​

Te rog să calculezi mediana timpilor T2 ai qubiților. Încearcă pe cont propriu, dar mai jos a fost adăugat cod pentru a te putea verifica.

# Your code here

t2s = [backend.qubit_properties(qq).t2 for qq in range(backend.num_qubits)]
f"Median T2: {(statistics.median(t2s)*10**6):.2f} \u03bcs"
'Median T2: 173.10 μs'

3.2 Erorile Gate-urilor și ale citirilor​

Acum ne îndreptăm atenția către erorile Gate-urilor. Mai întâi, studiem structura de date a instanței target. Este un dicționar ale cărui chei sunt numele operațiunilor.

target = backend.target
target.keys()
dict_keys(['measure', 'id', 'sx', 'delay', 'x', 'for_loop', 'rz', 'if_else', 'ecr', 'reset', 'switch_case'])

Valorile sale sunt și ele dicționare. Să ne uităm la câteva elemente ale valorii (dicționar) pentru operațiunea „sx".

for i, qq in enumerate(target["sx"]):
if i >= 5:
break
print(i, qq, target["sx"][qq])
0 (0,) InstructionProperties(duration=6e-08, error=0.0007401311759115297)
1 (1,) InstructionProperties(duration=6e-08, error=0.0003163759907528654)
2 (2,) InstructionProperties(duration=6e-08, error=0.0003183859004638003)
3 (3,) InstructionProperties(duration=6e-08, error=0.00042235914178831863)
4 (4,) InstructionProperties(duration=6e-08, error=0.011163151923589715)

Să facem același lucru pentru operațiunile „ecr" și „measure".

for i, edge in enumerate(target["ecr"]):
if i >= 5:
break
print(i, edge, target["ecr"][edge])
0 (0, 14) InstructionProperties(duration=6.6e-07, error=0.01486295709788732)
1 (1, 0) InstructionProperties(duration=6.6e-07, error=0.015201590794522601)
2 (2, 1) InstructionProperties(duration=6.6e-07, error=0.00697838102630724)
3 (2, 3) InstructionProperties(duration=6.6e-07, error=0.008075067943986797)
4 (3, 4) InstructionProperties(duration=6.6e-07, error=0.0630164507876913)
for i, qq in enumerate(target["measure"]):
if i >= 5:
break
print(i, qq, target["measure"][qq])
0 (0,) InstructionProperties(duration=1.6e-06, error=0.0078125)
1 (1,) InstructionProperties(duration=1.6e-06, error=0.155029296875)
2 (2,) InstructionProperties(duration=1.6e-06, error=0.057373046875)
3 (3,) InstructionProperties(duration=1.6e-06, error=0.02880859375)
4 (4,) InstructionProperties(duration=1.6e-06, error=0.01318359375)

Cum poți observa, erorile de citire tind să fie mai mari decât cele ale operațiunii cu 2 qubiți, care la rândul lor tind să fie mai mari decât cele ale operațiunii cu 1 qubit.

Înțelegând structurile de date, suntem pregătiți să calculăm erorile mediane pentru Gate-urile „sx" și „ecr". Din nou, compară rezultatele cu cele afișate pentru dispozitiv pe IBM Quantum Platform.

sx_errors = [inst_prop.error for inst_prop in target["sx"].values()]
f"Median SX error: {(statistics.median(sx_errors)):.3e}"
'Median SX error: 2.277e-04'
ecr_errors = [inst_prop.error for inst_prop in target["ecr"].values()]
f"Median ECR error: {(statistics.median(ecr_errors)):.3e}"
'Median ECR error: 6.895e-03'

4. Anexă​

O funcționalitate populară a Qiskit este capacitatea sa de vizualizare. Aceasta include vizualizatoare de circuit, de stare și distribuție, și vizualizator de target. Le-ai folosit deja pe primele două în notebook-urile Jupyter anterioare. Să folosim câteva funcționalități ale vizualizatorului de target.

from qiskit.visualization import plot_gate_map

plot_gate_map(backend, font_size=14)

Output of the previous code cell

from qiskit.visualization import plot_error_map

plot_error_map(backend)

Output of the previous code cell

# Check Qiskit version
import qiskit

qiskit.__version__
'2.0.2'