Lewati ke konten utama

Circuit cutting untuk pengurangan kedalaman

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

Latar Belakang​

Tutorial ini menunjukkan cara membangun Qiskit pattern untuk memotong gate dalam quantum circuit guna mengurangi kedalaman circuit. Untuk diskusi lebih mendalam tentang circuit cutting, kunjungi dokumentasi circuit cutting Qiskit addon.

Persyaratan​

Sebelum memulai tutorial ini, pastikan kamu sudah menginstal hal-hal berikut:

  • Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
  • Qiskit Runtime v0.22 atau lebih baru (pip install qiskit-ibm-runtime)
  • Circuit cutting Qiskit addon v0.9.0 atau lebih baru (pip install qiskit-addon-cutting)

Setup​

# Added by doQumentation β€” required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-cutting qiskit-ibm-runtime
import numpy as np

from qiskit.circuit.library import EfficientSU2
from qiskit.quantum_info import PauliList, Statevector, SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

from qiskit_addon_cutting import (
cut_gates,
generate_cutting_experiments,
reconstruct_expectation_values,
)

from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2

Langkah 1: Petakan input klasik ke masalah kuantum​

Kita akan mengimplementasikan pola Qiskit menggunakan empat langkah yang diuraikan dalam dokumentasi. Dalam hal ini, kita akan menyimulasikan nilai ekspektasi pada circuit dengan kedalaman tertentu dengan cara memotong gate yang menghasilkan swap gate dan menjalankan subeksperimen pada circuit yang lebih dangkal. Gate cutting relevan untuk Langkah 2 (mengoptimalkan circuit untuk eksekusi kuantum dengan mengurai gate yang berjauhan) dan Langkah 4 (pasca-pemrosesan untuk merekonstruksi nilai ekspektasi pada circuit asli). Pada langkah pertama, kita akan membuat circuit dari library circuit Qiskit dan mendefinisikan beberapa observable.

  • Input: Parameter klasik untuk mendefinisikan sebuah circuit
  • Output: Circuit abstrak dan observable
circuit = EfficientSU2(num_qubits=4, entanglement="circular").decompose()
circuit.assign_parameters([0.4] * len(circuit.parameters), inplace=True)
observables = PauliList(["ZZII", "IZZI", "IIZZ", "XIXI", "ZIZZ", "IXIX"])
circuit.draw("mpl", scale=0.8, style="iqp")

Output of the previous code cell

Langkah 2: Optimalkan masalah untuk eksekusi pada perangkat keras kuantum​

  • Input: Circuit abstrak dan observable
  • Output: Circuit target dan observable yang dihasilkan dengan memotong gate yang berjauhan untuk mengurangi kedalaman circuit setelah transpile

Kita memilih tata letak awal yang membutuhkan dua swap untuk menjalankan gate antara Qubit 3 dan 0, serta dua swap lagi untuk mengembalikan qubit ke posisi awalnya. Kita memilih optimization_level=3, yaitu tingkat optimasi tertinggi yang tersedia dengan preset pass manager.

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

pm = generate_preset_pass_manager(
optimization_level=3, initial_layout=[0, 1, 2, 3], backend=backend
)
transpiled_qc = pm.run(circuit)

Coupling map showing the qubits that will need to be swapped

print(f"Transpiled circuit depth: {transpiled_qc.depth()}")
transpiled_qc.draw("mpl", scale=0.4, idle_wires=False, style="iqp", fold=-1)
Transpiled circuit depth: 103

Output of the previous code cell

Temukan dan potong gate yang berjauhan: Kita akan mengganti gate yang berjauhan (gate yang menghubungkan qubit non-lokal, 0 dan 3) dengan objek TwoQubitQPDGate dengan menentukan indeksnya. cut_gates akan mengganti gate pada indeks yang ditentukan dengan objek TwoQubitQPDGate dan juga mengembalikan daftar instansi QPDBasis β€” satu untuk setiap dekomposisi gate. Objek QPDBasis berisi informasi tentang cara mengurai gate yang dipotong menjadi operasi qubit tunggal.

# Find the indices of the distant gates
cut_indices = [
i
for i, instruction in enumerate(circuit.data)
if {circuit.find_bit(q)[0] for q in instruction.qubits} == {0, 3}
]

# Decompose distant CNOTs into TwoQubitQPDGate instances
qpd_circuit, bases = cut_gates(circuit, cut_indices)

qpd_circuit.draw("mpl", scale=0.8)

Output of the previous code cell

Buat subeksperimen untuk dijalankan pada Backend: generate_cutting_experiments menerima circuit yang mengandung instansi TwoQubitQPDGate dan observable berupa PauliList.

Untuk menyimulasikan nilai ekspektasi dari circuit berukuran penuh, banyak subeksperimen dibuat dari distribusi kuasiprobabilitas gabungan gate yang diurai, lalu dieksekusi pada satu atau lebih backend. Jumlah sampel yang diambil dari distribusi dikontrol oleh num_samples, dan satu koefisien gabungan diberikan untuk setiap sampel unik. Untuk informasi lebih lanjut tentang cara koefisien dihitung, lihat materi penjelasan.

# Generate the subexperiments and sampling coefficients
subexperiments, coefficients = generate_cutting_experiments(
circuits=qpd_circuit, observables=observables, num_samples=np.inf
)

Sebagai perbandingan, kita melihat bahwa subeksperimen QPD akan lebih dangkal setelah memotong gate yang berjauhan: Berikut ini adalah contoh subeksperimen yang dipilih secara acak dari circuit QPD. Kedalamannya telah berkurang lebih dari setengahnya. Banyak subeksperimen probabilistik seperti ini harus dibuat dan dievaluasi untuk merekonstruksi nilai ekspektasi dari circuit yang lebih dalam.

# Transpile the decomposed circuit to the same layout
transpiled_qpd_circuit = pm.run(subexperiments[100])

print(f"Original circuit depth after transpile: {transpiled_qc.depth()}")
print(
f"QPD subexperiment depth after transpile: {transpiled_qpd_circuit.depth()}"
)
transpiled_qpd_circuit.draw(
"mpl", scale=0.6, style="iqp", idle_wires=False, fold=-1
)
Original circuit depth after transpile: 103
QPD subexperiment depth after transpile: 46

Output of the previous code cell

Di sisi lain, pemotongan mengakibatkan kebutuhan sampling tambahan. Di sini kita memotong tiga gate CNOT, sehingga menghasilkan overhead sampling sebesar 939^3. Untuk lebih lanjut tentang overhead sampling yang ditimbulkan oleh circuit cutting, lihat dokumentasi Circuit Knitting Toolbox.

print(f"Sampling overhead: {np.prod([basis.overhead for basis in bases])}")
Sampling overhead: 729.0

Langkah 3: Jalankan menggunakan Qiskit primitives​

Jalankan circuit target ("subeksperimen") dengan Sampler Primitive.

  • Input: Circuit target
  • Output: Distribusi kuasiprobabilitas
# Transpile the subexperiments to the backend's instruction set architecture (ISA)
isa_subexperiments = pm.run(subexperiments)

# Set up the Qiskit Runtime Sampler primitive. For a fake backend, this will use a local simulator.
sampler = SamplerV2(backend)

# Submit the subexperiments
job = sampler.run(isa_subexperiments)
# Retrieve the results
results = job.result()
print(job.job_id())
czypg1r6rr3g008mgp6g

Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasik yang diinginkan​

Gunakan hasil subeksperimen, subobservable, dan koefisien sampling untuk merekonstruksi nilai ekspektasi dari circuit asli.

Input: Distribusi kuasiprobabilitas Output: Nilai ekspektasi yang telah direkonstruksi

reconstructed_expvals = reconstruct_expectation_values(
results,
coefficients,
observables,
)
# Reconstruct final expectation value
final_expval = np.dot(reconstructed_expvals, [1] * len(observables))
print("Final reconstructed expectation value")
print(final_expval)
Final reconstructed expectation value
1.0751342773437473
ideal_expvals = [
Statevector(circuit).expectation_value(SparsePauliOp(observable))
for observable in observables
]
print("Ideal expectation value")
print(np.dot(ideal_expvals, [1] * len(observables)).real)
Ideal expectation value
1.2283177520039992

Survei tutorial​

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

Tautan ke survei

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 27 Apr 2026
English version on doQumentation β€” updated 7 Mei 2026
This translation based on the English version of 9 Apr 2026