Lewati ke konten utama

Circuit cutting untuk kondisi batas periodik

Perkiraan penggunaan: Dua menit pada prosesor Eagle (CATATAN: Ini hanya perkiraan. Waktu proses kamu mungkin berbeda.)

Latar Belakang​

Dalam notebook ini, kita mempertimbangkan simulasi rantai periodik Qubit di mana terdapat operasi dua Qubit antara setiap dua Qubit yang berdekatan, termasuk yang pertama dan yang terakhir. Rantai periodik sering ditemukan dalam masalah fisika dan kimia seperti model Ising dan simulasi molekuler.

Perangkat IBM Quantum® saat ini bersifat planar. Beberapa rantai periodik memungkinkan untuk disematkan langsung pada topologi di mana Qubit pertama dan terakhir bertetangga. Namun, untuk masalah yang cukup besar, Qubit pertama dan terakhir bisa berjauhan, sehingga membutuhkan banyak Gate SWAP untuk operasi 2-Qubit antara kedua Qubit ini. Masalah batas periodik semacam ini telah dipelajari dalam paper ini.

Dalam notebook ini kita menunjukkan penggunaan circuit cutting untuk menangani masalah rantai periodik skala utilitas seperti ini di mana Qubit pertama dan terakhir tidak bertetangga. Memotong konektivitas jarak jauh ini menghindari Gate SWAP ekstra dengan biaya mengeksekusi beberapa instans Circuit, dan beberapa post-processing klasik. Singkatnya, pemotongan dapat digabungkan untuk menghitung secara logis operasi 2-Qubit jarak jauh. Dengan kata lain, pendekatan ini mengarah pada peningkatan efektif konektivitas coupling map, sehingga menghasilkan jumlah Gate SWAP yang lebih sedikit.

Perlu dicatat bahwa ada dua jenis potongan — memotong kabel Circuit (disebut wire cutting), atau mengganti Gate 2-Qubit dengan beberapa operasi qubit tunggal (disebut gate cutting). Dalam notebook ini, kita akan fokus pada gate cutting. Untuk detail lebih lanjut tentang gate cutting, lihat materi penjelasan di qiskit-addon-cutting, dan referensi terkait. Untuk detail lebih lanjut tentang wire cutting, lihat tutorial Wire cutting untuk estimasi nilai ekspektasi, atau tutorial di qiskit-addon-cutting.

Persyaratan​

Sebelum memulai tutorial ini, pastikan kamu telah menginstal berikut ini:

  • 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)

Pengaturan​

# 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 menghasilkan Circuit TwoLocal dan mendefinisikan beberapa observable.

  • Input: Parameter untuk membuat Circuit
  • Output: Circuit abstrak dan observable

Kita mempertimbangkan entangler map yang efisien dari sisi hardware untuk Circuit TwoLocal dengan konektivitas periodik antara Qubit terakhir dan pertama dari entangler map. Interaksi jarak jauh ini dapat menyebabkan Gate SWAP ekstra selama transpilasi, sehingga meningkatkan kedalaman Circuit.

Pilih Backend dan tata letak awal​

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

Untuk notebook ini kita akan mempertimbangkan rantai 1D periodik 109 Qubit, yang merupakan rantai 1D terpanjang dalam topologi perangkat IBM Quantum 127-Qubit. Tidak mungkin mengatur rantai periodik 109 Qubit pada perangkat 127 Qubit sehingga Qubit pertama dan terakhir bertetangga tanpa menambahkan Gate SWAP ekstra.

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

Bangun 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 memungkinkan pengulangan rotation_blocks dan entangler map beberapa kali. Untuk kasus ini, jumlah pengulangan menentukan jumlah Gate periodik yang perlu dipotong. Karena overhead sampling meningkat secara eksponensial dengan jumlah potongan (lihat tutorial Wire cutting untuk estimasi nilai ekspektasi untuk detail lebih lanjut), kita akan menetapkan jumlah pengulangan ke 2 dalam notebook ini.

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)

Output of the previous code cell

Untuk memverifikasi kualitas hasil menggunakan circuit cutting, kita perlu mengetahui hasil idealnya. Circuit yang dipilih saat ini melampaui kemampuan simulasi klasik brute force. Oleh karena itu, kita menetapkan nilai parameter pada Circuit dengan hati-hati agar menjadi clifford.

Kita akan menetapkan nilai parameter 00 untuk dua lapisan pertama Gate Rx, dan nilai π\pi untuk lapisan terakhir. Ini memastikan bahwa hasil ideal dari Circuit ini adalah ∣1⟩⊗n|1\rangle^{\otimes n}, di mana nn adalah jumlah Qubit. Oleh karena itu, nilai ekspektasi ⟨Zi⟩\langle Z_i \rangle dan ⟨ZiZi+1⟩\langle Z_i Z_{i+1} \rangle, di mana ii adalah indeks Qubit, masing-masing adalah −1-1 dan +1+1.

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 observable​

Untuk mengkuantifikasi manfaat gate cutting, kita mengukur nilai ekspektasi dari observable 1n∑i=1n⟨Zi⟩\frac{1}{n}\sum_{i=1}^n \langle Z_i \rangle dan 1n−1∑i=1n−1⟨ZiZi+1⟩\frac{1}{n-1}\sum_{i=1}^{n-1} \langle Z_i Z_{i+1} \rangle. Seperti yang telah dibahas sebelumnya, nilai ekspektasi ideal masing-masing adalah −1-1 dan +1+1.

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: Optimasi masalah untuk eksekusi di perangkat keras kuantum​

  • Input: Sirkuit abstrak dan observabel
  • Output: Sirkuit target dan observabel yang dihasilkan dengan memotong gate jarak jauh

Transpilasi sirkuit​

Perlu diperhatikan bahwa sirkuit dapat ditranspilasi pada tahap ini, atau setelah pemotongan. Jika kita melakukan transpilasi setelah pemotongan, kita harus mentranspilasi setiap subeksperimen yang dihasilkan akibat overhead sampling. Oleh karena itu, lebih bijak untuk melakukan transpilasi pada tahap ini guna mengurangi overhead transpilasi.

Namun, jika transpilasi dilakukan pada tahap ini dengan konektivitas perangkat keras asli, transpiler akan menambahkan banyak gate SWAP untuk menempatkan operasi 2-qubit periodik — yang mengaburkan manfaat circuit cutting. Untuk menghindari masalah ini, kita dapat memanfaatkan pengetahuan kita tentang gate mana yang perlu dipotong. Secara khusus, kita bisa membuat coupling map virtual dengan menambahkan koneksi virtual antara qubit yang berjauhan untuk mengakomodasi gate 2-qubit periodik ini. Hal ini memastikan sirkuit dapat ditranspilasi pada tahap ini tanpa menambahkan gate SWAP ekstra.

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)

Output of the previous code cell

Potong konektivitas periodik jarak jauh​

Sekarang kita memotong gate-gate dalam sirkuit yang telah ditranspilasi. Perlu diperhatikan bahwa gate 2-qubit yang perlu dipotong adalah yang menghubungkan qubit pertama dan terakhir dari layout.

# 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 menerapkan layout dari sirkuit yang telah ditranspilasi ke observabel.

trans_observables = observables.apply_layout(virtual_mapped_circuit.layout)

Terakhir, subeksperimen dibuat dengan melakukan sampling atas berbagai basis pengukuran dan persiapan.

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 diperhatikan bahwa pemotongan interaksi jarak jauh menghasilkan eksekusi banyak sampel sirkuit yang berbeda dalam basis pengukuran dan persiapannya. Informasi lebih lanjut tentang ini dapat ditemukan di Constructing a virtual two-qubit gate by sampling single-qubit operations dan Cutting circuits with multiple two-qubit unitaries.

Jumlah gate periodik yang dipotong sama dengan jumlah pengulangan layer TwoLocal, yang didefinisikan sebagai num_reps di atas. Overhead sampling dari gate cutting adalah 6. Oleh karena itu, total jumlah subeksperimen akan menjadi 6num_reps6^{num\_reps}.

print(f"Number of subexperiments is {len(subexperiments)} = 6**{num_reps}")
Number of subexperiments is 36 = 6**2

Transpilasi subeksperimen​

Pada titik ini, subeksperimen berisi sirkuit dengan beberapa gate 1-qubit yang tidak termasuk dalam basis gate set. Hal ini karena qubit yang dipotong diukur dalam basis yang berbeda, dan gate rotasi yang digunakan untuk ini belum tentu termasuk dalam basis gate set. Misalnya, pengukuran dalam basis X berarti menerapkan gate Hadamard sebelum pengukuran biasa dalam basis Z. Namun Hadamard bukan bagian dari basis gate set.

Alih-alih menerapkan seluruh proses transpilasi pada setiap sirkuit dalam subeksperimen, kita bisa menggunakan pass transpilasi tertentu. Lihat dokumentasi ini untuk deskripsi lengkap semua pass transpilasi yang tersedia.

Kita akan menerapkan pass BasisTranslator lalu Optimize1qGatesDecomposition untuk memastikan semua gate dalam sirkuit ini termasuk dalam basis gate set. Menggunakan dua pass ini lebih cepat daripada proses transpilasi penuh, karena langkah-langkah lain seperti routing dan pemilihan initial layout tidak dilakukan lagi.

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: Eksekusi menggunakan primitif Qiskit​

  • Input: Sirkuit target
  • Output: Distribusi kuasi-probabilitas

Kita menggunakan primitif SamplerV2 untuk mengeksekusi sirkuit yang telah dipotong. Kita menonaktifkan dynamical decoupling dan twirling agar peningkatan yang kita peroleh dalam hasil semata-mata disebabkan oleh penerapan gate cutting yang efektif untuk jenis sirkuit 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 mengirimkan job menggunakan mode 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 hasil dalam format klasik yang diinginkan​

  • Input: Distribusi kuasi-probabilitas
  • Output: Nilai ekspektasi yang direkonstruksi
reconstructed_expvals = reconstruct_expectation_values(
result,
coefficients,
paulis,
)

Sekarang kita akan menghitung rata-rata dari observabel Z-type berbobot-1 dan berbobot-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

Verifikasi Silang: Dapatkan nilai ekspektasi tanpa pemotongan​

Berguna untuk memverifikasi silang keunggulan teknik circuit cutting dibandingkan tanpa pemotongan. Di sini kita akan menghitung nilai ekspektasi tanpa memotong sirkuit. Perlu diperhatikan bahwa sirkuit yang tidak dipotong akan menderita banyak gate SWAP yang diperlukan untuk mengimplementasikan operasi 2-qubit antara qubit pertama dan terakhir. Kita akan menggunakan fungsi sampled_expectation_value untuk mendapatkan nilai ekspektasi dari sirkuit yang tidak dipotong setelah mendapatkan distribusi probabilitas melalui SamplerV2. Hal ini memungkinkan penggunaan primitif yang seragam di semua instance. Namun perlu diperhatikan bahwa kita juga bisa menggunakan EstimatorV2 untuk langsung menghitung nilai ekspektasi.

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 menghitung rata-rata nilai ekspektasi dari semua observabel Z-type berbobot-1 dan berbobot-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​

Mari kita visualisasikan peningkatan yang diperoleh untuk observabel berbobot-1 dan berbobot-2 saat menggunakan gate cutting untuk sirkuit rantai periodik.

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()

Output of the previous code cell

Ringkasan​

Secara ringkas, kita menghitung rata-rata nilai ekspektasi dari observabel Z-type berbobot-1 dan berbobot-2 untuk rantai 1D periodik dengan 109 qubit. Untuk melakukan hal tersebut, kita:

  • membuat coupling map virtual dengan menambahkan konektivitas jarak jauh antara qubit pertama dan terakhir dari rantai 1D, lalu mentranspilasi sirkuit.
    • transpilasi pada tahap ini memungkinkan kita menghindari overhead transpilasi setiap subeksperimen secara terpisah setelah pemotongan,
    • menggunakan coupling map virtual memungkinkan kita menghindari gate SWAP ekstra untuk operasi 2-qubit antara qubit pertama dan terakhir.
  • menghapus konektivitas jarak jauh dari sirkuit yang telah ditranspilasi melalui gate cutting.
  • mengubah sirkuit yang dipotong ke dalam basis gate set dengan menerapkan pass transpilasi yang sesuai.
  • mengeksekusi sirkuit yang dipotong pada perangkat IBM Quantum menggunakan primitif SamplerV2.
  • mendapatkan nilai ekspektasi dengan merekonstruksi hasil dari sirkuit yang dipotong.

Kesimpulan​

Kita bisa melihat dari hasil bahwa rata-rata observabel ⟨Z⟩\langle Z \rangle berbobot-1 dan ⟨ZZ⟩\langle ZZ \rangle berbobot-2 meningkat secara signifikan dengan memotong gate periodik. Perlu diperhatikan bahwa studi ini tidak menyertakan teknik penekanan atau mitigasi error apa pun. Peningkatan yang diamati semata-mata disebabkan oleh penggunaan gate cutting yang tepat untuk masalah ini. Hasilnya dapat ditingkatkan lebih lanjut dengan menggunakan teknik mitigasi dan penekanan error.

Studi ini menunjukkan contoh penggunaan gate cutting secara efektif untuk meningkatkan performa komputasi.

Survei tutorial​

Silakan isi survei singkat ini untuk memberikan masukan tentang tutorial ini. Pendapat Anda akan membantu kami meningkatkan konten dan pengalaman pengguna.

Link to survey

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.

Source: IBM Quantum docs — updated 15 Jan 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of 9 Apr 2026