Langkau ke kandungan utama

Pemotongan Circuit untuk pengurangan kedalaman

Anggaran penggunaan: Lapan minit pada pemproses Eagle (NOTA: Ini hanyalah anggaran sahaja. Masa larian anda mungkin berbeza.)

Latar Belakang​

Tutorial ini menunjukkan cara membina Qiskit pattern untuk memotong gate dalam Circuit kuantum bagi mengurangkan kedalaman Circuit. Untuk perbincangan lebih mendalam tentang pemotongan Circuit, lawati dokumentasi addon Qiskit pemotongan Circuit.

Keperluan​

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

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

Persediaan​

# 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 kepada masalah kuantum​

Kita akan melaksanakan corak Qiskit menggunakan empat langkah yang digariskan dalam dokumentasi. Dalam kes ini, kita akan mensimulasikan nilai jangkaan pada Circuit dengan kedalaman tertentu dengan memotong gate yang menghasilkan swap gate dan melaksanakan subeksperimen pada Circuit yang lebih cetek. Pemotongan Gate berkaitan untuk Langkah 2 (optimumkan Circuit untuk pelaksanaan kuantum dengan menguraikan gate yang jauh) dan 4 (pasca-pemprosesan untuk merekonstruksi nilai jangkaan pada Circuit asal). Pada langkah pertama, kita akan menjana Circuit dari pustaka Circuit Qiskit dan mentakrifkan beberapa observable.

  • Input: Parameter klasik untuk mentakrifkan 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: Optimumkan masalah untuk pelaksanaan perkakasan kuantum​

  • Input: Circuit abstrak dan observable
  • Output: Circuit sasaran dan observable yang dihasilkan dengan memotong gate yang jauh untuk mengurangkan kedalaman Circuit yang ditranspil

Kita memilih susun atur awal yang memerlukan dua swap untuk melaksanakan gate antara Qubit 3 dan 0, serta dua swap lagi untuk memulangkan Qubit ke kedudukan asal mereka. Kita memilih optimization_level=3, yang merupakan tahap pengoptimuman tertinggi yang tersedia dengan pengurus laluan preset.

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

Cari dan potong gate yang jauh: Kita akan menggantikan gate yang jauh (gate yang menghubungkan Qubit bukan setempat, 0 dan 3) dengan objek TwoQubitQPDGate dengan menyatakan indeks mereka. cut_gates akan menggantikan gate pada indeks yang ditentukan dengan objek TwoQubitQPDGate dan juga mengembalikan senarai contoh QPDBasis -- satu untuk setiap penguraian gate. Objek QPDBasis mengandungi maklumat tentang cara menguraikan gate yang dipotong kepada operasi satu-Qubit.

# 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

Jana subeksperimen untuk dijalankan pada Backend: generate_cutting_experiments menerima Circuit yang mengandungi contoh TwoQubitQPDGate dan observable sebagai PauliList.

Untuk mensimulasikan nilai jangkaan Circuit bersaiz penuh, banyak subeksperimen dijana daripada taburan quasikemungkinan bersama gate yang diuraikan dan kemudian dilaksanakan pada satu atau lebih Backend. Bilangan sampel yang diambil dari taburan dikawal oleh num_samples, dan satu pekali gabungan diberikan untuk setiap sampel unik. Untuk maklumat lanjut tentang cara pekali dikira, rujuk bahan penjelasan.

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

Sebagai perbandingan, kita lihat bahawa subeksperimen QPD akan lebih cetek selepas memotong gate yang jauh: Berikut adalah contoh subeksperimen yang dipilih secara rawak yang dijana daripada Circuit QPD. Kedalamannya telah dikurangkan lebih daripada separuh. Banyak subeksperimen berkebarangkalian ini perlu dijana dan dinilai untuk merekonstruksi nilai jangkaan 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

Sebaliknya, pemotongan mengakibatkan keperluan pensampelan tambahan. Di sini kita memotong tiga gate CNOT, menghasilkan overhead pensampelan sebesar 939^3. Untuk maklumat lanjut tentang overhead pensampelan yang ditanggung oleh pemotongan Circuit, rujuk dokumentasi Circuit Knitting Toolbox.

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

Langkah 3: Laksanakan menggunakan primitif Qiskit​

Laksanakan Circuit sasaran ("subeksperimen") dengan Primitif Sampler.

  • Input: Circuit sasaran
  • Output: Taburan kuasi-kebarangkalian
# 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 dikehendaki​

Gunakan hasil subeksperimen, subobservable, dan pekali pensampelan untuk merekonstruksi nilai jangkaan Circuit asal.

Input: Taburan kuasi-kebarangkalian Output: Nilai jangkaan yang 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

Tinjauan tutorial​

Sila ambil tinjauan singkat ini untuk memberikan maklum balas tentang tutorial ini. Pandangan anda akan membantu kami menambah baik tawaran kandungan dan pengalaman pengguna kami.

Pautan ke tinjauan

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