Pemotongan Circuit untuk syarat sempadan berkala
Anggaran penggunaan: Dua minit pada pemproses Eagle (NOTA: Ini hanya anggaran. Masa jalan sebenar anda mungkin berbeza.)
Latar belakang​
Dalam notebook ini, kita tengok simulasi rantai berkala Qubit di mana ada operasi dua Qubit antara setiap dua Qubit bersebelahan, termasuk yang pertama dan terakhir. Rantai berkala ni selalu dijumpai dalam masalah fizik dan kimia seperti model Ising dan simulasi molekul.
Peranti IBM Quantum® yang ada sekarang bersifat planar. Untuk beberapa rantai berkala, memang boleh letak terus pada topologi di mana Qubit pertama dan terakhir adalah jiran. Tapi untuk masalah yang cukup besar, Qubit pertama dan terakhir boleh jauh antara satu sama lain, lalu perlukan banyak Gate SWAP untuk operasi 2-Qubit antara dua Qubit tu. Masalah sempadan berkala macam ni dah dikaji dalam kertas ini.
Dalam notebook ni kita tunjuk cara guna circuit cutting untuk tangani masalah rantai berkala skala utiliti di mana Qubit pertama dan terakhir bukan jiran. Memotong ketersambungan jarak jauh ni elakkan Gate SWAP tambahan, dengan kos menjalankan beberapa contoh Circuit, dan sedikit pemprosesan klasik selepas tu. Ringkasnya, pemotongan boleh digabungkan untuk kira secara logik operasi 2-Qubit jarak jauh. Dengan kata lain, pendekatan ni membawa kepada peningkatan berkesan dalam ketersambungan peta gandingan, lalu menghasilkan bilangan Gate SWAP yang lebih sedikit.
Perlu tahu ada dua jenis potongan — memotong wayar Circuit (dipanggil wire cutting), atau menggantikan Gate 2-Qubit dengan beberapa operasi Qubit tunggal (dipanggil gate cutting). Dalam notebook ni, kita fokus pada gate cutting. Untuk maklumat lanjut tentang gate cutting, rujuk bahan penerangan dalam qiskit-addon-cutting, dan rujukan yang berkaitan. Untuk maklumat lanjut tentang wire cutting, rujuk tutorial Pemotongan wayar untuk anggaran nilai jangkaan, atau tutorial dalam qiskit-addon-cutting.
Keperluan​
Sebelum mula tutorial ni, pastikan benda-benda berikut dah dipasang:
- Qiskit SDK v1.2 atau lebih baru (
pip install qiskit) - Qiskit Runtime v0.3 atau lebih baru (
pip install qiskit-ibm-runtime) - Circuit cutting Qiskit addon v.9.0 atau lebih baru (
pip install qiskit-addon-cutting)
Persediaan​
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-addon-cutting qiskit-ibm-runtime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import (
BasisTranslator,
Optimize1qGatesDecomposition,
)
from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.converters import circuit_to_dag, dag_to_circuit
from qiskit.result import sampled_expectation_value
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import TwoLocal
from qiskit_addon_cutting import (
cut_gates,
generate_cutting_experiments,
reconstruct_expectation_values,
)
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2, SamplerOptions, Batch
Langkah 1: Petakan input klasik ke masalah kuantum​
Di sini, kita akan jana Circuit TwoLocal dan tentukan beberapa boleh cerap.
- Input: Parameter untuk cipta Circuit
- Output: Circuit abstrak dan boleh cerap
Kita tengok entangler map yang cekap perkakasan untuk Circuit TwoLocal dengan ketersambungan berkala antara Qubit terakhir dan pertama dalam entangler map. Interaksi jarak jauh ni boleh menyebabkan Gate SWAP tambahan semasa transpilasi, lalu menambah kedalaman Circuit.
Pilih Backend dan susun atur awal​
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
Untuk notebook ni kita akan guna rantai 1D berkala 109 Qubit, iaitu rantai 1D terpanjang dalam topologi peranti IBM Quantum 127-Qubit. Tak mungkin nak susun rantai berkala 109 Qubit pada peranti 127 Qubit supaya Qubit pertama dan terakhir jadi jiran tanpa menambah Gate SWAP tambahan.
init_layout = [
13,
12,
11,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1,
0,
14,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
36,
51,
50,
49,
48,
47,
46,
45,
44,
43,
42,
41,
40,
39,
38,
37,
52,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
74,
89,
88,
87,
86,
85,
84,
83,
82,
81,
80,
79,
78,
77,
76,
75,
90,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
112,
126,
125,
124,
123,
122,
121,
120,
119,
118,
117,
116,
115,
114,
113,
]
# the number of qubits in the circuit is governed by the length of the initial layout
num_qubits = len(init_layout)
num_qubits
109
Bina entangler map untuk Circuit TwoLocal​
coupling_map = [(i, i + 1) for i in range(0, len(init_layout) - 1)]
coupling_map.append(
(len(init_layout) - 1, 0)
) # adding in the periodic connectivity
Circuit TwoLocal membenarkan pengulangan rotation_blocks dan entangler map beberapa kali. Untuk kes ini, bilangan pengulangan menentukan bilangan Gate berkala yang perlu dipotong. Memandangkan overhed pensampelan meningkat secara eksponen dengan bilangan potongan (rujuk tutorial Pemotongan wayar untuk anggaran nilai jangkaan untuk maklumat lanjut), kita tetapkan bilangan pengulangan kepada 2 dalam notebook ni.
num_reps = 2
entangler_map = []
for even_edge in coupling_map[0 : len(coupling_map) : 2]:
entangler_map.append(even_edge)
for odd_edge in coupling_map[1 : len(coupling_map) : 2]:
entangler_map.append(odd_edge)
ansatz = TwoLocal(
num_qubits=num_qubits,
rotation_blocks="rx",
entanglement_blocks="cx",
entanglement=entangler_map,
reps=num_reps,
).decompose()
ansatz.draw("mpl", fold=-1)

Untuk sahkan kualiti hasil menggunakan circuit cutting, kita perlu tahu hasil yang ideal. Circuit yang dipilih sekarang ni melangkaui simulasi klasik secara kasar. Oleh itu, kita tetapkan parameter Circuit dengan teliti supaya jadi clifford.
Kita akan tetapkan nilai parameter untuk dua lapisan pertama Gate Rx, dan nilai untuk lapisan terakhir. Ini memastikan hasil ideal Circuit ni adalah , dengan ialah bilangan Qubit. Oleh itu, nilai jangkaan dan , di mana ialah indeks Qubit, masing-masing ialah dan .
params_last_layer = [np.pi] * ansatz.num_qubits
params = [0] * (ansatz.num_parameters - ansatz.num_qubits)
params.extend(params_last_layer)
ansatz.assign_parameters(params, inplace=True)
Pilih boleh cerap​
Untuk ukur manfaat gate cutting, kita ukur nilai jangkaan boleh cerap dan . Seperti yang dibincangkan sebelum ni, nilai jangkaan ideal ialah dan masing-masing.
observables = []
for i in range(num_qubits):
obs = "I" * (i) + "Z" + "I" * (num_qubits - i - 1)
observables.append(obs)
for i in range(num_qubits):
if i == num_qubits - 1:
obs = "Z" + "I" * (num_qubits - 2) + "Z"
else:
obs = "I" * i + "ZZ" + "I" * (num_qubits - i - 2)
observables.append(obs)
observables = SparsePauliOp(observables)
paulis = observables.paulis
coeffs = observables.coeffs
Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan kuantum​
- Input: Circuit dan boleh ukur (observable) yang abstrak
- Output: Circuit sasaran dan boleh ukur yang dihasilkan dengan memotong gate jarak jauh
Transpile Circuit tersebut​
Perlu diingat bahawa circuit boleh di-transpile pada peringkat ini, atau selepas pemotongan. Kalau kita transpile selepas pemotongan, kita perlu transpile setiap subeksperimen yang terhasil akibat overhead pensampelan. Oleh itu, lebih bijak untuk transpile pada peringkat ini bagi mengurangkan overhead transpilasi.
Walau bagaimanapun, jika transpilasi dilakukan pada peringkat ini dengan ketersambungan perkakasan asli, Transpiler akan menambahkan beberapa gate SWAP untuk menempatkan operasi 2-Qubit berkala — yang akan mengaburkan faedah pemotong circuit. Untuk elakkan masalah ini, kita boleh manfaatkan pengetahuan kita tentang gate yang tepat yang perlu dipotong. Khususnya, kita boleh cipta peta pasangan maya dengan menambah sambungan maya antara Qubit yang jauh bagi menampung gate 2-Qubit berkala ini. Ini akan memastikan circuit boleh di-transpile pada peringkat ini tanpa memasukkan gate SWAP tambahan.
coupling_map = backend.configuration().coupling_map
# create a virtual coupling map with long range connectivity
virtual_coupling_map = coupling_map.copy()
virtual_coupling_map.append([init_layout[-1], init_layout[0]])
virtual_coupling_map.append([init_layout[0], init_layout[-1]])
pm_virtual = generate_preset_pass_manager(
optimization_level=1,
coupling_map=virtual_coupling_map,
initial_layout=init_layout,
basis_gates=backend.configuration().basis_gates,
)
virtual_mapped_circuit = pm_virtual.run(ansatz)
virtual_mapped_circuit.draw("mpl", fold=-1, idle_wires=False)

Potong ketersambungan berkala jarak jauh​
Sekarang kita potong gate dalam circuit yang sudah di-transpile. Perlu diingat bahawa gate 2-Qubit yang perlu dipotong ialah gate yang menghubungkan Qubit pertama dan terakhir dalam susun atur.
# Find the indices of the distant gates
cut_indices = [
i
for i, instruction in enumerate(virtual_mapped_circuit.data)
if {virtual_mapped_circuit.find_bit(q)[0] for q in instruction.qubits}
== {init_layout[-1], init_layout[0]}
]
Kita akan menggunakan susun atur circuit yang telah di-transpile ke atas boleh ukur tersebut.
trans_observables = observables.apply_layout(virtual_mapped_circuit.layout)
Akhirnya, subeksperimen dijana dengan membuat pensampelan ke atas pelbagai asas pengukuran dan persediaan.
qpd_circuit, bases = cut_gates(virtual_mapped_circuit, cut_indices)
subexperiments, coefficients = generate_cutting_experiments(
circuits=qpd_circuit,
observables=trans_observables.paulis,
num_samples=np.inf,
)
Perlu diingat bahawa pemotongan interaksi jarak jauh menghasilkan pelaksanaan pelbagai sampel circuit yang berbeza dalam asas pengukuran dan persediaan. Maklumat lanjut tentang ini boleh didapati dalam Constructing a virtual two-qubit gate by sampling single-qubit operations dan Cutting circuits with multiple two-qubit unitaries.
Bilangan gate berkala yang perlu dipotong adalah sama dengan bilangan pengulangan lapisan TwoLocal, yang ditakrifkan sebagai num_reps di atas. Overhead pensampelan pemotongan gate ialah 6. Oleh itu, jumlah bilangan subeksperimen ialah .
print(f"Number of subexperiments is {len(subexperiments)} = 6**{num_reps}")
Number of subexperiments is 36 = 6**2
Transpile subeksperimen​
Pada ketika ini, subeksperimen mengandungi circuit dengan beberapa gate 1-Qubit yang tidak berada dalam set gate asas. Ini kerana Qubit yang dipotong diukur dalam asas yang berbeza, dan gate putaran yang digunakan untuk ini tidak semestinya tergolong dalam set gate asas. Contohnya, pengukuran dalam asas X bermakna menggunakan gate Hadamard sebelum pengukuran biasa dalam asas Z. Tetapi Hadamard bukan sebahagian daripada set gate asas.
Daripada menggunakan keseluruhan proses transpilasi pada setiap circuit dalam subeksperimen, kita boleh menggunakan laluan transpilasi tertentu. Rujuk dokumentasi ini untuk penerangan terperinci tentang semua laluan transpilasi yang tersedia.
Kita akan menggunakan laluan BasisTranslator dan kemudian Optimize1qGatesDecomposition untuk memastikan semua gate dalam circuit ini tergolong dalam set gate asas. Menggunakan kedua-dua laluan ini lebih pantas berbanding keseluruhan proses transpilasi, memandangkan langkah-langkah lain seperti penghalaan dan pemilihan susun atur awal tidak dilakukan semula.
pass_ = PassManager(
[Optimize1qGatesDecomposition(basis=backend.configuration().basis_gates)]
)
subexperiments = pass_.run(
[
dag_to_circuit(
BasisTranslator(sel, target_basis=backend.basis_gates).run(
circuit_to_dag(circ)
)
)
for circ in subexperiments
]
)
Langkah 3: Laksanakan menggunakan primitif Qiskit​
- Input: Circuit sasaran
- Output: Taburan kuasi-kebarangkalian
Kita menggunakan primitif SamplerV2 untuk melaksanakan circuit yang dipotong. Kita lumpuhkan dynamical decoupling dan twirling supaya sebarang peningkatan yang kita perolehi dalam keputusan adalah semata-mata disebabkan oleh penggunaan pemotongan gate yang berkesan untuk jenis circuit ini.
options = SamplerOptions()
options.default_shots = 10000
options.dynamical_decoupling.enable = False
options.twirling.enable_gates = False
options.twirling.enable_measure = False
Sekarang kita akan hantar kerja menggunakan mod batch.
with Batch(backend=backend) as batch:
sampler = SamplerV2(options=options)
cut_job = sampler.run(subexperiments)
print(f"Job ID {cut_job.job_id()}")
Job ID cwxf7wq60bqg008pvt8g
result = cut_job.result()
Langkah 4: Pasca-proses dan kembalikan keputusan dalam format klasik yang dikehendaki​
- Input: Taburan kuasi-kebarangkalian
- Output: Nilai jangkaan yang dibina semula
reconstructed_expvals = reconstruct_expectation_values(
result,
coefficients,
paulis,
)
Kita sekarang hitung purata bagi boleh ukur jenis Z dengan berat 1 dan berat 2.
cut_weight_1 = np.mean(reconstructed_expvals[:num_qubits])
cut_weight_2 = np.mean(reconstructed_expvals[num_qubits:])
print(f"Average of weight-1 expectation values is {cut_weight_1}")
print(f"Average of weight-2 expectation values is {cut_weight_2}")
Average of weight-1 expectation values is -0.741733944954063
Average of weight-2 expectation values is 0.6968862385320495
Semak Silang: Dapatkan nilai jangkaan tanpa pemotongan​
Berguna untuk membuat semak silang kelebihan teknik pemotongan circuit berbanding tanpa pemotongan. Di sini kita akan hitung nilai jangkaan tanpa memotong circuit. Perlu diingat bahawa circuit tanpa pemotongan sedemikian akan mengalami bilangan besar gate SWAP yang diperlukan untuk melaksanakan operasi 2-Qubit antara Qubit pertama dan terakhir. Kita akan menggunakan fungsi sampled_expectation_value untuk mendapatkan nilai jangkaan circuit tanpa pemotongan selepas mendapatkan taburan kebarangkalian melalui SamplerV2. Ini membolehkan penggunaan primitif yang seragam merentasi semua kes. Walau bagaimanapun, perlu diingat bahawa kita juga boleh menggunakan EstimatorV2 untuk mengira nilai jangkaan secara langsung.
if ansatz.num_clbits == 0:
ansatz.measure_all()
pm_uncut = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=init_layout
)
transpiled_circuit = pm_uncut.run(ansatz)
sampler = SamplerV2(mode=backend, options=options)
uncut_job = sampler.run([transpiled_circuit])
uncut_job_id = uncut_job.job_id()
print(f"The job id for the uncut clifford circuit is {uncut_job_id}")
The job id for the uncut clifford circuit is cwxfads2ac5g008jhe7g
uncut_result = uncut_job.result()[0]
uncut_counts = uncut_result.data.meas.get_counts()
Sekarang kita akan hitung purata nilai jangkaan bagi semua boleh ukur jenis Z dengan berat 1 dan berat 2 tanpa pemotongan.
uncut_expvals = [
sampled_expectation_value(uncut_counts, obs) for obs in paulis
]
uncut_weight_1 = np.mean(uncut_expvals[:num_qubits])
uncut_weight_2 = np.mean(uncut_expvals[num_qubits:])
print(f"Average of weight-1 expectation values is {uncut_weight_1}")
print(f"Average of weight-2 expectation values is {uncut_weight_2}")
Average of weight-1 expectation values is -0.32494128440366965
Average of weight-2 expectation values is 0.32340917431192656
Visualisasi​
Jom kita visualisasikan peningkatan yang diperoleh untuk boleh ukur berat-1 dan berat-2 apabila menggunakan pemotongan gate untuk circuit rantai berkala
mpl.rcParams.update(mpl.rcParamsDefault)
fig = plt.subplots(figsize=(12, 8), dpi=200)
width = 0.25
labels = ["Weight-1", "Weight-2"]
x = np.arange(len(labels))
ideal = [-1, 1]
cut = [cut_weight_1, cut_weight_2]
uncut = [uncut_weight_1, uncut_weight_2]
br1 = np.arange(len(ideal))
br2 = [x + width for x in br1]
br3 = [x + width for x in br2]
plt.bar(
br1, ideal, width=width, edgecolor="k", label="Ideal", color="#4589ff"
)
plt.bar(br2, cut, width=width, edgecolor="k", label="Cut", color="#a56eff")
plt.bar(
br3, uncut, width=width, edgecolor="k", label="Uncut", color="#009d9a"
)
plt.axhline(y=0, color="k", linestyle="-")
plt.xticks([r + width for r in range(len(ideal))], labels, fontsize=14)
plt.yticks(fontsize=14)
plt.legend(fontsize=14)
plt.show()

Ringkasan​
Secara ringkasnya, kita telah mengira purata nilai jangkaan boleh ukur jenis Z dengan berat-1 dan berat-2 untuk rantai 1D berkala dengan 109 Qubit. Untuk melakukan ini, kita telah
- mencipta peta pasangan maya dengan menambah ketersambungan jarak jauh antara Qubit pertama dan terakhir dalam rantai 1D, dan men-transpile circuit tersebut.
- transpilasi pada peringkat ini membolehkan kita mengelakkan overhead transpilasi setiap subeksperimen secara berasingan selepas pemotongan,
- menggunakan peta pasangan maya membolehkan kita mengelakkan gate SWAP tambahan untuk operasi 2-Qubit antara Qubit pertama dan terakhir.
- mengalih keluar ketersambungan jarak jauh dari circuit yang telah di-transpile melalui pemotongan gate.
- menukar circuit yang dipotong ke dalam set gate asas dengan menggunakan laluan transpilasi yang sesuai.
- melaksanakan circuit yang dipotong pada peranti IBM Quantum menggunakan primitif
SamplerV2. - mendapatkan nilai jangkaan dengan membina semula hasil circuit yang dipotong.
Inferens​
Kita perhatikan daripada keputusan bahawa purata boleh ukur jenis berat-1 dan berat-2 bertambah baik dengan ketara melalui pemotongan gate berkala. Perlu diingat bahawa kajian ini tidak memasukkan sebarang teknik pengurusan atau pengurangan ralat. Peningkatan yang diperhatikan adalah semata-mata disebabkan oleh penggunaan pemotongan gate yang betul untuk masalah ini. Keputusan boleh ditingkatkan lagi dengan menggunakan teknik mitigasi dan pengurusan ralat.
Kajian ini menunjukkan contoh penggunaan pemotongan gate yang berkesan untuk meningkatkan prestasi pengiraan.
Tinjauan tutorial​
Sila isi tinjauan ringkas ini untuk memberikan maklum balas tentang tutorial ini. Pandangan anda akan membantu kami menambah baik kandungan dan pengalaman pengguna kami.
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.