Permulaan pantas
Panduan ini menunjukkan contoh kerja minimum bagi pakej qiskit-addon-obp. Kami menggunakan operator backpropagation (OBP) untuk mengurangkan kedalaman litar kuantum dengan menyerap gate di hujung litar ke dalam observable.
Nilai jangkaan tidak berubah jika kita mengupas blok gate di hujung litar dan mengkonjugasikan observable dengannya secara klasik. OBP menerapkan langkah ini berulang kali, menilai sebahagian litar secara klasik supaya hanya litar yang lebih cetek dijalankan pada perkakasan. Harganya ialah setiap gate yang diserap boleh mengembangkan observable kepada lebih banyak sebutan Pauli, jadi kedalaman yang dijimatkan mesti ditimbang berbanding pertumbuhan observable.
Untuk melihat contoh cara membina aliran kerja yang realistik dengan alat ini dan melaksanakannya pada perkakasan kuantum, lihat tutorial di IBM Quantum Platform (OBP Tutorial).
Sediakan input untuk OBP
OBP menerima senarai hirisan litar dan satu observable sebagai input. Ia merambat balik hirisan satu demi satu dari hujung litar ke dalam observable, mengurangkan kedalaman litar dengan kos sebutan Pauli tambahan dalam observable. Di sini kami menjana litar evolusi masa untuk model Heisenberg 10 qubit dan menghirisnya mengikut jenis gate.
Di bawah kami melukis litar asal, kemudian litar yang sama yang digabungkan semula dengan barrier yang menandakan sempadan hirisan — setiap hirisan ialah unit yang boleh diserap ke dalam observable dalam satu langkah perambatan balik.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_obp": "qiskit-addon-obp", "qiskit_addon_utils": "qiskit-addon-utils"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis import LieTrotter
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import (
generate_time_evolution_circuit,
generate_xyz_hamiltonian,
)
from qiskit_addon_utils.slicing import combine_slices, slice_by_gate_types
# Generate a circuit to reduce
coupling_map = CouplingMap.from_heavy_hex(3, bidirectional=False)
reduced_coupling_map = coupling_map.reduce(
[0, 13, 1, 14, 10, 16, 5, 12, 8, 18]
)
hamiltonian = generate_xyz_hamiltonian(
reduced_coupling_map,
coupling_constants=(np.pi / 8, np.pi / 4, np.pi / 2),
ext_magnetic_field=(np.pi / 3, np.pi / 6, np.pi / 9),
)
circuit = generate_time_evolution_circuit(
hamiltonian,
time=0.2,
synthesis=LieTrotter(reps=2),
)
# Slice the circuit and define an observable
slices = slice_by_gate_types(circuit)
observable = SparsePauliOp("IIIIIIIIIZ")
print(f"Original circuit depth: {circuit.depth()}")
print(f"Number of slices: {len(slices)}")
print(f"Observable terms: {len(observable)}")
Original circuit depth: 18
Number of slices: 18
Observable terms: 1
# Recombine the slices with barriers to make the slice boundaries visible
sliced_circuit = combine_slices(slices, include_barriers=True)
print("Original circuit:")
display(circuit.draw("mpl", scale=0.6, fold=-1))
print("Sliced circuit (recombined with barriers for visualization)")
sliced_circuit.draw("mpl", scale=0.6, fold=-1)
Original circuit:

Sliced circuit (recombined with barriers for visualization)

Kurangkan kedalaman litar dengan OBP
Kami memanggil backpropagate untuk menyerap hirisan ke dalam observable. Fungsi ini mengembalikan observable yang dikembangkan, hirisan litar yang tidak dirambati, dan metadata tentang prosedur tersebut.
Jika tidak dikawal, observable boleh berkembang kepada sebutan Pauli. operator_budget menghadkan pertumbuhan ini — di sini kami membenarkan paling banyak 8 kumpulan qubit-wise commuting, yang secara kasar menetapkan bilangan shot yang diperlukan untuk menilai observable pada QPU. Perambatan balik berhenti sebaik sahaja penyerapan hirisan seterusnya akan melebihi bajet, itulah yang berlaku di bawah: hanya 7 daripada 18 hirisan diserap sebelum observable memenuhi kesemua 8 kumpulan commuting dan prosedur berhenti.
Untuk pergi lebih dalam ke dalam litar, argumen kata kunci truncation_error_budget kepada backpropagate boleh digunakan untuk membuang sebutan Pauli berpekali kecil daripada observable semasa ia berkembang. Ini menyederhanakan pertumbuhan observable sebagai ganti beberapa ralat yang berkadar dengan magnitud sebutan Pauli yang dipangkas. Kedua-dua bajet ini saling melengkapi dan boleh digunakan bersama: operator_budget mengawal saiz observable, manakala truncation_error_budget mengawal ralat yang timbul akibat pembuangan sebutan.
from qiskit_addon_obp import backpropagate
from qiskit_addon_obp.utils.simplify import OperatorBudget
max_qwc_groups = 8
bp_obs, remaining_slices, metadata = backpropagate(
observable,
slices,
operator_budget=OperatorBudget(max_qwc_groups=max_qwc_groups),
)
reduced_circuit = combine_slices(remaining_slices)
num_groups = len(bp_obs.group_commuting(qubit_wise=True))
print(
f"Backpropagated {metadata.num_backpropagated_slices} of {len(slices)} slices."
)
print(
f"Reduced circuit depth: {reduced_circuit.depth()} (was {circuit.depth()})"
)
print(f"Observable grew from {len(observable)} to {len(bp_obs)} Pauli terms.")
print(
f"Filled {num_groups} of {max_qwc_groups} commuting groups, exhausting the budget."
)
Backpropagated 7 of 18 slices.
Reduced circuit depth: 11 (was 18)
Observable grew from 1 to 18 Pauli terms.
Filled 8 of 8 commuting groups, exhausting the budget.
reduced_circuit.draw("mpl", scale=0.6, fold=-1)