Перейти до основного вмісту

Створення менеджера проходів для динамічного розв'язування

Версії пакетів

Код на цій сторінці розроблено з використанням таких вимог. Рекомендуємо використовувати ці або новіші версії.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

Ця сторінка демонструє, як використовувати прохід PadDynamicalDecoupling, щоб додати до схеми техніку придушення помилок під назвою динамічне розв'язування.

Динамічне розв'язування працює шляхом додавання послідовностей імпульсів (відомих як послідовності динамічного розв'язування) до простоюючих кубітів, щоб перевернути їх навколо сфери Блоха. Це скасовує вплив каналів шуму та пригнічує декогеренцію. Такі імпульсні послідовності схожі на рефокусуючі імпульси, що використовуються в ядерному магнітному резонансі. Детальний опис можна знайти в роботі A Quantum Engineer's Guide to Superconducting Qubits.

Оскільки прохід PadDynamicalDecoupling працює лише з запланованими схемами та використовує гейти, які не обов'язково є базисними гейтами нашого цільового пристрою, тобі також знадобляться проходи ALAPScheduleAnalysis та BasisTranslator.

У цьому прикладі використовується ibm_fez, який було ініціалізовано раніше. Отримай інформацію про target із backend і збережи назви операцій як basis_gates, оскільки target потрібно буде змінити, щоб додати інформацію про часові характеристики гейтів, які використовуються в динамічному розв'язуванні.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_fez")

target = backend.target
basis_gates = list(target.operation_names)

Створи схему efficient_su2 як приклад. Спочатку транспілюй схему до бекенду, оскільки імпульси динамічного розв'язування потрібно додавати після того, як схему було транспільовано та заплановано. Динамічне розв'язування найкраще працює, коли в квантових схемах є багато часу простою — тобто коли одні кубіти не використовуються, поки інші активні. Це саме той випадок у цій схемі, оскільки двокубітні гейти ecr застосовуються послідовно в цьому ансаці.

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

Послідовність динамічного розв'язування — це серія гейтів, що в сукупності дають тотожну операцію і рівномірно розподілені в часі. Наприклад, почнемо зі створення простої послідовності XY4, що складається з чотирьох гейтів.

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

Через регулярний часовий розподіл послідовностей динамічного розв'язування, інформацію про YGate необхідно додати до target, оскільки він не є базисним гейтом, на відміну від XGate. Проте ми знаємо апріорі, що YGate має таку ж тривалість та похибку, що й XGate, тож можемо просто отримати ці властивості з target і додати їх для об'єктів YGate. Саме тому basis_gates були збережені окремо — ми додаємо інструкцію YGate до target, хоча вона не є фактичним базисним гейтом ibm_fez.

from qiskit.transpiler import InstructionProperties

y_gate_properties = {}
for qubit in range(target.num_qubits):
y_gate_properties.update(
{
(qubit,): InstructionProperties(
duration=target["x"][(qubit,)].duration,
error=target["x"][(qubit,)].error,
)
}
)

target.add_instruction(YGate(), y_gate_properties)

Схеми ансацу, такі як efficient_su2, є параметризованими, тому перед відправкою до бекенду до них необхідно прив'язати значення. Тут призначимо випадкові параметри.

import numpy as np

rng = np.random.default_rng(1234)
qc_t.assign_parameters(
rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)

Далі виконай власні проходи. Створи екземпляр PassManager з ALAPScheduleAnalysis і PadDynamicalDecoupling. Спочатку запусти ALAPScheduleAnalysis, щоб додати інформацію про часові характеристики квантової схеми — тільки після цього можна додавати рівномірно розподілені в часі послідовності динамічного розв'язування. Ці проходи запускаються на схемі за допомогою .run().

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)

dd_pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)
qc_dd = dd_pm.run(qc_t)

Використай інструмент візуалізації timeline_drawer, щоб побачити часові характеристики схеми та переконатися, що рівномірно розподілена послідовність об'єктів XGate і YGate присутня в схемі.

from qiskit.visualization import timeline_drawer

timeline_drawer(qc_dd, idle_wires=False, target=target)

Output of the previous code cell

Нарешті, оскільки YGate не є фактичним базисним гейтом нашого бекенду, застосуй прохід BasisTranslator вручну (це стандартний прохід, але він виконується до планування, тому його потрібно застосувати знову). Бібліотека еквівалентностей сесії — це бібліотека еквівалентностей схем, що дозволяє Transpiler розкладати схеми на базисні гейти; вона також задається як аргумент.

from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator

qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

Тепер об'єкти YGate відсутні в нашій схемі, а явна інформація про часові характеристики представлена у вигляді гейтів Delay. Ця транспільована схема з динамічним розв'язуванням готова до відправки на бекенд.

Наступні кроки

Рекомендації