Langkau ke kandungan utama

Penanda aras litar dinamik dengan pasangan Bell yang dipotong

Anggaran penggunaan: 22 saat pada pemproses Heron r2 (NOTA: Ini adalah anggaran sahaja. Masa jalan sebenar anda mungkin berbeza.)

Hasil pembelajaran

Selepas melalui tutorial ini, pengguna harus memahami:

  • Cara membina Circuit dinamik dengan pengukuran litar tengah dan suap balik klasik ke depan untuk mengangkut pembelitan antara qubit yang jauh;
  • Cara mengira dan mentafsir metrik ralat bagi mengukur kesetiaan pasangan Bell merentasi sebuah peranti;
  • Cara mengenal pasti pasangan qubit yang paling sesuai untuk operasi berasaskan LOCC menggunakan hasil penanda aras.

Prasyarat

Kami mencadangkan pengguna membiasakan diri dengan topik-topik berikut sebelum melalui tutorial ini:

Latar belakang

Perkakasan kuantum biasanya terhad kepada interaksi tempatan, tapi banyak algoritma memerlukan pembelitan qubit yang jauh atau bahkan qubit pada pemproses berasingan. Litar dinamik — iaitu litar dengan pengukuran pertengahan litar dan suap balik ke depan — menyediakan cara untuk mengatasi batasan ini dengan menggunakan komunikasi klasik masa nyata untuk melaksanakan operasi kuantum bukan setempat secara berkesan. Dalam pendekatan ini, hasil pengukuran dari satu bahagian litar (atau satu QPU) boleh mencetuskan gate secara bersyarat pada bahagian lain, membolehkan kita mengangkut pembelitan merentasi jarak jauh. Ini membentuk asas skim operasi setempat dan komunikasi klasik (LOCC), di mana kita menggunakan keadaan sumber yang terikat (pasangan Bell) dan berkomunikasi hasil pengukuran secara klasik untuk menghubungkan qubit yang jauh.

Salah satu kegunaan LOCC yang menjanjikan ialah untuk merealisasikan gate CNOT jarak jauh maya melalui teleportasi, seperti yang ditunjukkan dalam tutorial pembelitan jarak jauh. Daripada CNOT jarak jauh terus (yang mungkin tidak dibenarkan oleh sambungan perkakasan), kita cipta pasangan Bell dan lakukan pelaksanaan gate berasaskan teleportasi. Walau bagaimanapun, ketepatan operasi sedemikian bergantung pada ciri-ciri perkakasan. Penyahaskoheranan qubit semasa kelewatan yang diperlukan (semasa menunggu hasil pengukuran) dan kependaman komunikasi klasik boleh merendahkan keadaan yang terikat. Selain itu, ralat pada pengukuran pertengahan litar lebih sukar untuk diperbetulkan berbanding ralat pada pengukuran akhir kerana ia merambat ke seluruh litar melalui gate bersyarat.

Dalam eksperimen rujukan, para pengarang memperkenalkan penanda aras ketepatan pasangan Bell untuk mengenal pasti bahagian mana dalam peranti yang paling sesuai untuk pembelitan berasaskan LOCC. Ideanya ialah untuk menjalankan litar dinamik kecil pada setiap kumpulan empat qubit yang bersambung dalam pemproses. Litar empat-Qubit ini pertama sekali mencipta pasangan Bell pada dua qubit tengah, kemudian menggunakannya sebagai sumber untuk membelit dua qubit tepi menggunakan LOCC. Secara konkrit, qubit 1 dan 2 disediakan secara setempat dalam pasangan Bell tidak dipotong (pasangan Bell yang dicipta terus dengan Hadamard dan CNOT, tanpa teleportasi), dan kemudian rutin teleportasi menggunakan pasangan Bell itu untuk membelit qubit 0 dan 3. Qubit 1 dan 2 diukur semasa pelaksanaan litar, dan berdasarkan hasil tersebut, pembetulan Pauli (X pada qubit 3 dan Z pada qubit 0) dikenakan. Qubit 0 dan 3 kemudiannya ditinggalkan dalam keadaan Bell di penghujung litar.

Untuk mengukur kualiti pasangan terikat akhir ini, kita ukur penstabilnya: khususnya, pariti dalam asas ZZ (Z0Z3Z_0Z_3) dan dalam asas XX (X0X3X_0X_3). Untuk pasangan Bell yang sempurna, kedua-dua jangkaan ini bersamaan +1. Dalam amalan, hingar perkakasan akan mengurangkan nilai-nilai ini. Oleh itu, kita ulang litar dua kali untuk setiap pasangan qubit: satu litar mengukur qubit 0 dan 3 dalam asas ZZ, dan satu lagi mengukurnya dalam asas XX. Daripada hasilnya, kita mendapat anggaran Z0Z3\langle Z_0Z_3\rangle dan X0X3\langle X_0X_3\rangle untuk pasangan qubit tersebut. Kita gunakan min kuasa dua ralat (MSE) penstabil ini berbanding nilai ideal (1) sebagai metrik mudah untuk ketepatan pembelitan. MSE yang lebih rendah bermakna dua qubit mencapai keadaan Bell yang lebih hampir kepada ideal (ketepatan lebih tinggi), manakala MSE yang lebih tinggi menunjukkan lebih banyak ralat. Dengan mengimbas eksperimen ini merentasi peranti, kita boleh menanda aras keupayaan pengukuran-dan-suap-balik kumpulan qubit yang berbeza dan mengenal pasti pasangan qubit terbaik untuk operasi LOCC.

Tutorial ini menunjukkan eksperimen pada peranti IBM Quantum® untuk menggambarkan cara litar dinamik boleh digunakan untuk menjana dan menilai pembelitan antara qubit yang jauh. Kita akan memetakan semua rantai empat-Qubit linear pada peranti, menjalankan litar teleportasi pada setiap satunya, kemudian menggambarkan taburan nilai MSE. Prosedur hujung-ke-hujung ini menunjukkan cara memanfaatkan Qiskit Runtime dan ciri litar dinamik untuk memaklumkan pilihan yang sedar perkakasan bagi memotong litar atau mengedarkan algoritma kuantum merentasi sistem modular.

Keperluan

Sebelum memulakan tutorial ini, pastikan anda telah memasang yang berikut:

  • Qiskit SDK v2.0 atau lebih baharu, dengan sokongan visualisasi
  • Qiskit Runtime v0.40 atau lebih baharu (pip install qiskit-ibm-runtime)
  • Qiskit Aer v0.17 atau lebih baharu (pip install qiskit-aer)

Persediaan

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime
from qiskit import QuantumCircuit

from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
from qiskit.transpiler import generate_preset_pass_manager

import numpy as np
import matplotlib.pyplot as plt

def create_bell_stab(initial_layouts):
"""
Create a circuit for a 1D chain of qubits (number
of qubits must be a multiple of 4), where a middle
Bell pair is consumed to create a Bell at the edge.
Takes as input a list of lists, where each element
of the list is a 1D chain of physical qubits that is
used as the initial_layout for the transpiled circuit.
Returns a list of length-2 tuples, each tuple
contains a circuit to measure the ZZ stabilizer and
a circuit to measure the XX stabilizer of the edge
Bell state.
"""
bell_circuits = []
for (
initial_layout
) in initial_layouts: # Iterate over chains of physical qubits
assert (
len(initial_layout) % 4 == 0
), "The length of the chain must be a multiple of 4, "
f"len(inital_layout)={len(initial_layout)}"
num_pairs = len(initial_layout) // 4

bell_parallel = QuantumCircuit(4 * num_pairs, 4 * num_pairs)

for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(c0, c1) = pair_idx * 4, pair_idx * 4 + 3 # edge qubits
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits

bell_parallel.h(q0)
bell_parallel.h(q1)
bell_parallel.cx(q1, q2)
bell_parallel.cx(q0, q1)
bell_parallel.cx(q2, q3)
bell_parallel.h(q2)

# add barrier BEFORE measurements and add id in conditional
bell_parallel.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits

bell_parallel.measure(q1, ca0)
bell_parallel.measure(q2, ca1)
# bell_parallel.barrier() #remove barrier after measurement

for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(ca0, ca1) = pair_idx * 4 + 1, pair_idx * 4 + 2 # middle qubits
with bell_parallel.if_test((ca0, 1)):
bell_parallel.x(q3)
with bell_parallel.if_test((ca1, 1)):
bell_parallel.z(q0)
bell_parallel.id(q0) # add id here for correct alignment

bell_zz = bell_parallel.copy()
bell_zz.barrier()
bell_xx = bell_parallel.copy()
bell_xx.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
bell_xx.h(q0)
bell_xx.h(q3)
bell_xx.barrier()
for pair_idx in range(num_pairs):
(q0, q1, q2, q3) = (
pair_idx * 4,
pair_idx * 4 + 1,
pair_idx * 4 + 2,
pair_idx * 4 + 3,
)
(c0, c1) = pair_idx * 4, pair_idx * 4 + 3 # edge qubits

bell_zz.measure(q0, c0)
bell_zz.measure(q3, c1)

bell_xx.measure(q0, c0)
bell_xx.measure(q3, c1)

bell_circuits.append(bell_zz)
bell_circuits.append(bell_xx)

return bell_circuits

def get_mse(result, initial_layouts):
"""
given a result object and the initial layouts,
returns a dict of layouts and their mse
"""
layout_mse = {}
for layout_idx, initial_layout in enumerate(initial_layouts):
layout_mse[tuple(initial_layout)] = {}

num_pairs = len(initial_layout) // 4

counts_zz = result[2 * layout_idx].data.c.get_counts()
total_shots = sum(counts_zz.values())

# Get ZZ expectation value
exp_zz_list = []
for pair_idx in range(num_pairs):
exp_zz = 0
for bitstr, shots in counts_zz.items():
bitstr = bitstr[::-1] # reverse order to big endian
b1, b0 = (
bitstr[pair_idx * 4],
bitstr[pair_idx * 4 + 3],
) # parse bitstring to get edge measurements for each 4-q chain
z_val0 = 1 if b0 == "0" else -1
z_val1 = 1 if b1 == "0" else -1
exp_zz += z_val0 * z_val1 * shots
exp_zz /= total_shots
exp_zz_list.append(exp_zz)

counts_xx = result[2 * layout_idx + 1].data.c.get_counts()
total_shots = sum(counts_xx.values())

# Get XX expectation value
exp_xx_list = []
for pair_idx in range(num_pairs):
exp_xx = 0
for bitstr, shots in counts_xx.items():
bitstr = bitstr[::-1] # reverse order to big endian
b1, b0 = (
bitstr[pair_idx * 4],
bitstr[pair_idx * 4 + 3],
) # parse bitstring to get edge measurements for each 4-q chain
x_val0 = 1 if b0 == "0" else -1
x_val1 = 1 if b1 == "0" else -1
exp_xx += x_val0 * x_val1 * shots
exp_xx /= total_shots
exp_xx_list.append(exp_xx)

mse_list = [
((exp_zz - 1) ** 2 + (exp_xx - 1) ** 2) / 2
for exp_zz, exp_xx in zip(exp_zz_list, exp_xx_list)
]

print(f"layout {initial_layout}")
for idx in range(num_pairs):
layout_mse[tuple(initial_layout)][
tuple(initial_layout[4 * idx : 4 * idx + 4])
] = mse_list[idx]
print(
f"qubits: {initial_layout[4*idx:4*idx+4]}, mse:, "
f"{round(mse_list[idx],4)}"
)
# print(f'exp_zz: {round(exp_zz_list[idx],4)},
# exp_xx: {round(exp_xx_list[idx],4)}')
print(" ")
return layout_mse

def plot_mse_ecdfs(layouts_mse, combine_layouts=False):
"""
Plot CDF of MSE data for multiple layouts.
Optionally combine all data in a single CDF
"""

if not combine_layouts:
for initial_layout, layouts in layouts_mse.items():
sorted_layouts = dict(
sorted(layouts.items(), key=lambda item: item[1])
) # sort layouts by mse

# get layouts and mses
layout_list = list(sorted_layouts.keys())
mse_list = np.asarray(list(sorted_layouts.values()))

# convert to numpy
x = np.array(mse_list)
y = np.arange(1, len(x) + 1) / len(x)

# Prepend (x[0], 0) to start CDF at zero
x = np.insert(x, 0, x[0])
y = np.insert(y, 0, 0)

# Create the plot
plt.plot(
x,
y,
marker="x",
linestyle="-",
label=f"qubits: {initial_layout}",
)

# add qubits labels for the edge pairs
for xi, yi, q in zip(x[1:], y[1:], layout_list):
plt.annotate(
[q[0], q[3]],
(xi, yi),
textcoords="offset points",
xytext=(5, -10),
ha="left",
fontsize=8,
)

elif combine_layouts:
all_layouts = {}
all_initial_layout = []
for (
initial_layout,
layouts,
) in layouts_mse.items(): # puts together all layout information
all_layouts.update(layouts)
all_initial_layout += initial_layout

sorted_layouts = dict(
sorted(all_layouts.items(), key=lambda item: item[1])
) # sort layouts by mse

# get layouts and mses
layout_list = list(sorted_layouts.keys())
mse_list = np.asarray(list(sorted_layouts.values()))

# convert to numpy
x = np.array(mse_list)
y = np.arange(1, len(x) + 1) / len(x)

# Prepend (x[0], 0) to start CDF at zero
x = np.insert(x, 0, x[0])
y = np.insert(y, 0, 0)

# Create the plot
plt.plot(
x,
y,
marker="x",
linestyle="-",
label=f"qubits: {sorted(list(set(all_initial_layout)))}",
)

# add qubit labels for the edge pairs
for xi, yi, q in zip(x[1:], y[1:], layout_list):
plt.annotate(
[q[0], q[3]],
(xi, yi),
textcoords="offset points",
xytext=(5, -10),
ha="left",
fontsize=8,
)

plt.xscale("log")
plt.xlabel("Mean squared error of ⟨ZZ⟩ and ⟨XX⟩")
plt.ylabel("Cumulative distribution function")
plt.title("CDF for different initial layouts")
plt.grid(alpha=0.3)
plt.show()

Contoh simulator berskala kecil

Sebelum menjalankan pada QPU sebenar, kita mengesahkan bahawa Circuit menghasilkan pasangan Bell dengan mengujinya pada simulator tanpa hingar menggunakan rantai empat-Qubit [0, 1, 2, 3]. Kita menggunakan Qiskit Runtime Sampler dengan AerSimulator sebagai mod Backend untuk melaksanakan Circuit.

Langkah 1: Petakan input klasik kepada masalah kuantum

Langkah pertama adalah mencipta satu set Circuit kuantum untuk menilai semua calon pautan Bell-pair yang disesuaikan dengan topologi peranti. Kita mulakan dengan membina Circuit sedemikian menggunakan rantai empat-Qubit [0, 1, 2, 3].

Rutin create_bell_stab() melakukan perkara berikut untuk setiap rantai:

  • Sediakan pasangan Bell tengah: Gunakan Hadamard pada qubit 1 dan CNOT dari qubit 1 ke qubit 2. Ini melilit qubit 1 dan 2 (mewujudkan keadaan Bell Φ+=(00+11)/2|\Phi^+\rangle = (|00\rangle + |11\rangle)/\sqrt{2}).
  • Lilit qubit tepi: Gunakan CNOT dari qubit 0 ke qubit 1, dan CNOT dari qubit 2 ke qubit 3. Ini menghubungkan pasangan yang berasingan sebelum ini supaya qubit 0 dan 3 akan menjadi terikat selepas langkah seterusnya. Hadamard pada qubit 2 juga digunakan (ini, digabungkan dengan CNOT sebelumnya, membentuk sebahagian daripada pengukuran Bell pada qubit 1 dan 2). Pada ketika ini, qubit 0 dan 3 belum terikat, tetapi qubit 1 dan 2 terikat dengan mereka dalam keadaan empat-Qubit yang lebih besar.
  • Pengukuran litar tengah dan suap balas: Qubit 1 dan 2 (qubit tengah) diukur dalam asas pengkomputeran, menghasilkan dua bit klasik. Berdasarkan keputusan pengukuran tersebut, kita menggunakan operasi bersyarat: jika pengukuran qubit 1 (panggil bit ini m12m_{12}) adalah 1, kita gunakan gate XX pada qubit 3; jika pengukuran qubit 2 (m21m_{21}) adalah 1, kita gunakan gate ZZ pada qubit 0. Gate bersyarat ini (yang direalisasikan menggunakan konstruk if_test/if_else Qiskit) melaksanakan pembetulan teleportasi standard. Ia "membatalkan" balik Pauli rawak yang berlaku akibat memproyeksikan qubit 1 dan 2, memastikan qubit 0 dan 3 berakhir dalam keadaan Bell yang diketahui, tanpa mengira keputusan pengukuran. Selepas langkah ini, qubit 0 dan 3 seharusnya secara idealnya terikat dalam keadaan Bell Φ+|\Phi^+\rangle.
  • Ukur penstabil pasangan Bell: Kita kemudian membahagi kepada dua versi Circuit. Dalam versi pertama, kita mengukur penstabil ZZZZ pada qubit 0 dan 3. Dalam versi kedua, kita mengukur penstabil XXXX pada qubit-Qubit ini.

Untuk setiap susun atur awal empat-Qubit, fungsi di atas mengembalikan dua Circuit (satu untuk pengukuran penstabil ZZZZ, satu lagi untuk XXXX). Circuit-circuit ini termasuk pengukuran litar tengah dan operasi bersyarat (if/else), yang merupakan arahan utama Circuit dinamik.

from qiskit_aer import AerSimulator

# 4-qubit chain for simulation
sim_layout = [[0, 1, 2, 3]]

aer_backend = AerSimulator()
sim_circuits = create_bell_stab(sim_layout)
sim_circuits[1].draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan kuantum

Sebelum melaksanakan Circuit kita, kita perlu mentranspil circuit-circuit tersebut kepada operasi gate yang disokong pada Backend yang dinyatakan. Transpilasi akan memetakan Circuit abstrak kepada qubit fizikal dan set gate Backend yang dipilih. Memandangkan kita telah memilih qubit fizikal tertentu untuk setiap rantai (dengan menyediakan initial_layout kepada penjana Circuit), kita menggunakan optimization_level=0 Transpiler dengan susun atur tetap tersebut. Ini memberitahu Qiskit untuk tidak menetapkan semula qubit atau melakukan sebarang pengoptimuman berat yang boleh mengubah struktur Circuit. Kita mahu mengekalkan urutan operasi (terutamanya gate bersyarat) tepat seperti yang dinyatakan.

pm_sim = generate_preset_pass_manager(
optimization_level=0, backend=aer_backend, initial_layout=sim_layout[0]
)
isa_sim_circuits = pm_sim.run(sim_circuits)
isa_sim_circuits[1].draw("mpl", fold=-1, idle_wires=False)

Langkah 3: Laksanakan menggunakan primitif Qiskit

Kita kini boleh menjalankan eksperimen pada Backend simulator tanpa hingar.

# Run on noiseless simulator
sampler_sim = Sampler(mode=aer_backend)
sim_job = sampler_sim.run(isa_sim_circuits)
sim_mse = get_mse(sim_job.result(), sim_layout)
layout [0, 1, 2, 3]
qubits: [0, 1, 2, 3], mse:, 0.0

Langkah 4: Proses selepas dan kembalikan keputusan dalam format klasik yang dikehendaki

Langkah terakhir adalah mengira metrik ralat min kuasa dua (MSE) untuk setiap kumpulan qubit yang diuji dan merumuskan keputusan. Untuk setiap rantai, kita kini mempunyai Z0Z3\langle Z_0Z_3\rangle dan X0X3\langle X_0X_3\rangle yang diukur. Jika qubit 0 dan 3 terikat sempurna dalam keadaan Bell Φ+|\Phi^+\rangle, kita menjangkakan kedua-duanya bernilai +1. Kita mengukur penyelewengan menggunakan MSE:

MSE=(Z0Z31)2+(X0X31)22.\text{MSE} = \frac{( \langle Z_0Z_3\rangle - 1)^2 + (\langle X_0X_3\rangle - 1)^2}{2}.

Nilai ini adalah 0 untuk pasangan Bell yang sempurna, dan meningkat apabila keadaan terikat menjadi lebih berderau (dengan keputusan rawak memberikan jangkaan sekitar 0, MSE akan menghampiri 1). Kod ini mengira MSE untuk setiap kumpulan empat-Qubit. Tanpa hingar, kita dapat MSE = 0 dalam contoh simulator berskala kecil ini, seperti yang dijangkakan.

Contoh perkakasan berskala besar

Di sini kita menggabungkan semua butiran ini ke dalam satu aliran kerja tunggal pada skala yang lebih besar, yang kemudian dijalankan pada perkakasan kuantum sebenar.

service = QiskitRuntimeService()
backend = service.least_busy(operational=True)

Kita mencari secara aturcara peta gandingan peranti untuk semua rantai empat qubit yang bersambung secara linear. Setiap rantai sedemikian (dilabel dengan indeks qubit [q0q1q2q3][q0-q1-q2-q3]) berfungsi sebagai kes ujian untuk Circuit pertukaran keterikatan. Dengan mengenal pasti semua laluan panjang-4 yang mungkin, kita memastikan liputan maksimum untuk pengelompokan qubit yang boleh merealisasikan protokol ini.

Kita menjana rantai-rantai ini dengan menggunakan fungsi pembantu yang melakukan carian tamak pada graf peranti. Ia mengembalikan "jalur" empat rantai empat-Qubit yang dibundel kepada kumpulan 16-Qubit. Pembundelan membolehkan kita menjalankan pelbagai eksperimen empat-Qubit secara selari pada bahagian cip yang berbeza, dan menggunakan keseluruhan peranti dengan cekap. Setiap jalur 16-Qubit mengandungi empat rantai yang tidak bertindih, bermakna tiada qubit yang digunakan semula dalam kumpulan tersebut. Sebagai contoh, satu jalur mungkin terdiri daripada rantai [0123][0-1-2-3], [4567][4-5-6-7], [891011][8-9-10-11], dan [12131415][12-13-14-15] semuanya dibungkus bersama. Sebarang qubit yang tidak disertakan dalam jalur dikembalikan dalam pembolehubah leftover.

from itertools import chain
from collections import defaultdict

def stripes16_from_backend(backend):
"""
Creates stripes of 16 qubits, four non-overlapping
four-qubit chains, that cover as much of the coupling
map as possible. Returns any unused qubits as leftovers.
"""
# get the undirected adjacency list
edges = backend.coupling_map.get_edges()
graph = defaultdict(set)
for u, v in edges:
graph[u].add(v)
graph[v].add(u)

qubits = sorted(graph) # all qubit indices that appear

# greedy search for 4-long linear chains (blocks) ────────────
used = set() # qubits already placed in a block
blocks = [] # each block is a four-qubit list

for q in qubits: # deterministic order for reproducibility
if q in used:
continue # already consumed by earlier block

# depth-first "straight" walk of length 3 without revisiting nodes
def extend(path):
if len(path) == 4:
return path
tip = path[-1]
for nbr in sorted(graph[tip]): # deterministic
if nbr not in path and nbr not in used:
maybe = extend(path + [nbr])
if maybe:
return maybe
return None

block = extend([q])
if block: # found a 4-node path
blocks.append(block)
used.update(block)

# bundle four four-qubit blocks into one 16-qubit
# stripe (max number of measurement compatible with if-else)
stripes = [
list(chain.from_iterable(blocks[i : i + 4]))
for i in range(0, len(blocks) // 4 * 4, 4) # full groups of four
]

leftovers = set(qubits) - set(chain.from_iterable(stripes))
return stripes, leftovers
initial_layouts, leftover = stripes16_from_backend(backend)

Seterusnya, kita membina Circuit untuk setiap jalur 16-Qubit menggunakan fungsi create_bell_stab(). Di penghujung langkah ini, kita mempunyai senarai Circuit yang merangkumi setiap rantai empat-Qubit pada peranti. Kita kemudian mentranspil dan menjalankan Circuit pada Backend sebenar dan memproses hasilnya.

# -------------------------Step 1-------------------------
circuits = create_bell_stab(initial_layouts)

# -------------------------Step 2-------------------------
isa_circuits = []
for ind, init_layout in enumerate(initial_layouts):
pm = generate_preset_pass_manager(
optimization_level=0, backend=backend, initial_layout=init_layout
)
isa_circ = pm.run(circuits[ind * 2 : ind * 2 + 2])
isa_circuits.extend(isa_circ)
isa_circuits[1].draw("mpl", fold=-1, idle_wires=False)

# -------------------------Step 3-------------------------
sampler = Sampler(mode=backend)
sampler.options.environment.job_tags = ["TUT_BDC"]
job = sampler.run(isa_circuits)

# -------------------------Step 4-------------------------
layouts_mse = get_mse(job.result(), initial_layouts)
layout [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
qubits: [0, 1, 2, 3], mse:, 0.6302
qubits: [4, 5, 6, 7], mse:, 0.0949
qubits: [8, 9, 10, 11], mse:, 0.1729
qubits: [12, 13, 14, 15], mse:, 0.0473

layout [16, 23, 22, 21, 17, 27, 26, 25, 18, 31, 30, 29, 19, 35, 34, 33]
qubits: [16, 23, 22, 21], mse:, 0.0533
qubits: [17, 27, 26, 25], mse:, 0.2966
qubits: [18, 31, 30, 29], mse:, 0.0447
qubits: [19, 35, 34, 33], mse:, 0.0392

layout [36, 41, 42, 43, 37, 45, 46, 47, 38, 49, 50, 51, 39, 53, 54, 55]
qubits: [36, 41, 42, 43], mse:, 0.1577
qubits: [37, 45, 46, 47], mse:, 0.0705
qubits: [38, 49, 50, 51], mse:, 0.2914
qubits: [39, 53, 54, 55], mse:, 0.1711

layout [56, 63, 62, 61, 57, 67, 66, 65, 58, 71, 70, 69, 59, 75, 74, 73]
qubits: [56, 63, 62, 61], mse:, 0.1236
qubits: [57, 67, 66, 65], mse:, 0.9969
qubits: [58, 71, 70, 69], mse:, 0.0631
qubits: [59, 75, 74, 73], mse:, 0.0301

layout [76, 81, 82, 83, 77, 85, 86, 87, 78, 89, 90, 91, 79, 93, 94, 95]
qubits: [76, 81, 82, 83], mse:, 0.2787
qubits: [77, 85, 86, 87], mse:, 0.0497
qubits: [78, 89, 90, 91], mse:, 0.1271
qubits: [79, 93, 94, 95], mse:, 0.0468

layout [96, 103, 102, 101, 97, 107, 106, 105, 98, 111, 110, 109, 99, 115, 114, 113]
qubits: [96, 103, 102, 101], mse:, 0.8657
qubits: [97, 107, 106, 105], mse:, 0.0399
qubits: [98, 111, 110, 109], mse:, 0.0667
qubits: [99, 115, 114, 113], mse:, 0.2444

layout [116, 121, 122, 123, 117, 125, 126, 127, 118, 129, 130, 131, 119, 133, 134, 135]
qubits: [116, 121, 122, 123], mse:, 0.0429
qubits: [117, 125, 126, 127], mse:, 0.0487
qubits: [118, 129, 130, 131], mse:, 0.0823
qubits: [119, 133, 134, 135], mse:, 0.0583

layout [136, 143, 142, 141, 137, 147, 146, 145, 138, 151, 150, 149, 139, 155, 154, 153]
qubits: [136, 143, 142, 141], mse:, 0.0209
qubits: [137, 147, 146, 145], mse:, 0.0384
qubits: [138, 151, 150, 149], mse:, 0.4941
qubits: [139, 155, 154, 153], mse:, 0.1062

Keputusan mendedahkan julat kualiti keterikatan yang luas merentas peranti. Ini mengesahkan penemuan makalah bahawa terdapat variasi lebih daripada satu tertib magnitud dalam kesetiaan keadaan Bell bergantung pada qubit fizikal yang digunakan. Dari segi praktikal, ini bermakna kawasan atau pautan tertentu dalam cip jauh lebih baik dalam melakukan operasi pengukuran litar tengah dan suap balas berbanding yang lain. Faktor seperti ralat bacaan qubit, jangka hayat qubit, dan crosstalk kemungkinan menyumbang kepada perbezaan ini. Sebagai contoh, jika satu rantai termasuk qubit bacaan yang sangat berderau, pengukuran litar tengah boleh menjadi tidak boleh dipercayai, menyebabkan kesetiaan yang lemah untuk pasangan terikat tersebut (MSE tinggi).

Akhir sekali, kita menggambarkan prestasi keseluruhan dengan memplot fungsi taburan kumulatif (CDF) nilai MSE untuk semua rantai. Plot CDF menunjukkan ambang MSE pada paksi-x, dan pecahan pasangan qubit yang mempunyai MSE paling banyak pada ambang tersebut di paksi-y. Lengkung ini bermula dari sifar dan menghampiri satu apabila ambang berkembang untuk merangkumi semua titik data. Kenaikan curam berhampiran MSE rendah menunjukkan bahawa banyak pasangan mempunyai kesetiaan tinggi; kenaikan perlahan bermakna banyak pasangan mempunyai ralat yang lebih besar. Kita memberi anotasi pada CDF dengan identiti pasangan terbaik. Dalam plot, setiap titik dalam CDF sepadan dengan MSE satu rantai empat-Qubit, dan kita melabelkan titik tersebut dengan pasangan indeks qubit [q0,q3][q0, q3] yang terikat dalam eksperimen tersebut. Ini memudahkan pengesanan pasangan qubit fizikal mana yang merupakan pemain terbaik (titik paling kiri pada CDF).

plot_mse_ecdfs(layouts_mse, combine_layouts=True)

Output of the previous code cell

Langkah seterusnya

Cadangan

Jika anda mendapati kerja ini menarik, anda mungkin berminat dengan bahan-bahan berikut:

Rujukan

[1] Carrera Vazquez, A., Tornow, C., Ristè, D. et al. Combining quantum processors with real-time classical communication. Nature 636, 75-79 (2024).