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

Представлення квантових комп'ютерів для транспілятора

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

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

Щоб перетворити абстрактну схему на ISA-схему, яка може виконуватись на конкретному QPU (квантовому процесорі), транспілятору потрібна певна інформація про QPU. Ця інформація знаходиться в двох місцях: об'єкті BackendV2 (або застарілому BackendV1), до якого ти плануєш подавати завдання, та атрибуті Target бекенду.

  • Target містить усі відповідні обмеження пристрою, такі як його рідні базові вентилі, зв'язність кубітів та інформацію про імпульси або часування.
  • Backend за замовчуванням має Target, містить додаткову інформацію — наприклад, InstructionScheduleMap, — та надає інтерфейс для подачі завдань з квантовими схемами.

Ти також можеш явно надати інформацію для використання транспілятором, наприклад, якщо маєш конкретний сценарій використання, або якщо вважаєш, що ця інформація допоможе транспілятору згенерувати більш оптимізовану схему.

Точність, з якою транспілятор створює найбільш відповідну схему для конкретного апаратного забезпечення, залежить від того, скільки інформації про свої обмеження має Target або Backend.

примітка

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

На цій сторінці наведено кілька прикладів передачі інформації про QPU транспілятору. Ці приклади використовують ціль із імітаційного бекенду FakeSherbrooke.

Конфігурація за замовчуванням

Найпростіший спосіб використання транспілятора — надати всю інформацію про QPU, передавши Backend або Target. Щоб краще зрозуміти, як працює транспілятор, побудуй схему та транспілюй її з різною інформацією, як показано нижче.

Імпортуй необхідні бібліотеки та ініціалізуй QPU: Щоб перетворити абстрактну схему на ISA-схему, яка може виконуватись на конкретному процесорі, транспілятору потрібна певна інформація про процесор. Зазвичай ця інформація зберігається у Backend або Target, що передаються транспілятору, і ніяка додаткова інформація не потрібна. Однак ти також можеш явно надати інформацію для використання транспілятором, наприклад, якщо маєш конкретний сценарій використання, або якщо вважаєш, що ця інформація допоможе транспілятору згенерувати більш оптимізовану схему.

У цьому розділі наведено кілька прикладів передачі інформації транспілятору. Ці приклади використовують ціль із імітаційного бекенду FakeSherbrooke.

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

backend = FakeSherbrooke()
target = backend.target

Схема прикладу використовує екземпляр efficient_su2 з бібліотеки схем Qiskit.

from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)

qc.draw("mpl")

Вихідні дані попереднього блоку коду

У цьому прикладі використовуються параметри за замовчуванням для транспіляції до target бекенду, що надає всю необхідну інформацію для перетворення схеми на таку, що буде виконуватися на бекенді.

from qiskit.transpiler import generate_preset_pass_manager

pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)

Вихідні дані попереднього блоку к�оду

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

Карта зв'язності

Карта зв'язності — це граф, що показує, які кубіти з'єднані та мають між собою двокубітні вентилі. Іноді цей граф є напрямленим, тобто двокубітні вентилі можуть діяти лише в одному напрямку. Однак транспілятор завжди може змінити напрям вентиля, додаючи додаткові однокубітні вентилі. Абстрактна квантова схема завжди може бути представлена на цьому графі, навіть якщо його зв'язність обмежена, шляхом введення вентилів SWAP для переміщення квантової інформації.

Кубіти з наших абстрактних схем називаються віртуальними кубітами, а ті на карті зв'язності — фізичними кубітами. Транспілятор забезпечує відображення між віртуальними та фізичними кубітами. Один із перших кроків транспіляції — етап розміщення — виконує це відображення.

примітка

Хоча етап маршрутизації взаємопов'язаний з етапом розміщення — який вибирає фактичні кубіти — за замовчуванням цей матеріал розглядає їх як окремі етапи для простоти. Поєднання маршрутизації та розміщення називається відображенням кубітів. Докладніше про ці етапи дивись у матеріалі Етапи транспілятора.

Передай ключовий аргумент coupling_map, щоб побачити його вплив на транспілятор:

coupling_map = target.build_coupling_map()

pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)

Вихідні дані попереднього блоку коду

Як показано вище, було вставлено кілька вентилів SWAP (кожен з яких складається з трьох вентилів CX), що призведе до великої кількості помилок на поточних пристроях. Щоб побачити, які кубіти вибрані на фактичній топології кубітів, скористайся plot_circuit_layout з Qiskit Visualizations:

from qiskit.visualization import plot_circuit_layout

plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")

Вихідні дані попереднього блоку коду

Це показує, що наші віртуальні кубіти 0–11 були тривіально відображені на лінію фізичних кубітів 0–11. Повернімось до параметрів за замовчуванням (optimization_level=1), що використовує VF2Layout якщо потрібна будь-яка маршрутизація.

pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)

Вихідні дані попереднього блоку коду

Тепер вентилі SWAP не вставляються, а вибрані фізичні кубіти збігаються з тими, що при використанні класу target.

from qiskit.visualization import plot_circuit_layout

plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")

Вихідні дані попереднього блоку коду

Тепер розміщення утворює кільце. Оскільки це розміщення відповідає зв'язності схеми, вентилі SWAP відсутні, що забезпечує значно кращу схему для виконання.

Базові вентилі

Кожен квантовий комп'ютер підтримує обмежений набір інструкцій, що називається його базовими вентилями. Кожен вентиль у схемі має бути перетворений на елементи цього набору. Цей набір має складатися з однокубітних і двокубітних вентилів, що утворюють універсальний набір вентилів, тобто будь-яка квантова операція може бути розкладена на ці вентилі. Це виконується за допомогою BasisTranslator, а базові вентилі можна вказати як ключовий аргумент транспілятора для надання цієї інформації.

basis_gates = list(target.operation_names)
print(basis_gates)
['sx', 'switch_case', 'x', 'if_else', 'measure', 'for_loop', 'delay', 'ecr', 'id', 'reset', 'rz']

Однокубітні вентилі за замовчуванням на ibm_sherbrooke — це rz, x та sx, а двокубітний вентиль за замовчуванням — ecr (відлунний перехресний резонанс). Вентилі CX будуються з вентилів ecr, тому на деяких QPU ecr вказується як двокубітний базовий вентиль, тоді як на інших за замовчуванням використовується cx. Вентиль ecr є заплутуючою частиною вентиля cx. Крім керуючих вентилів, є також інструкції delay та measurement.

примітка

QPU мають базові вентилі за замовчуванням, але ти можеш вибрати будь-які вентилі, за умови надання інструкції або додавання імпульсних вентилів (дивись Створення проходів транспілятора.). Базові вентилі за замовчуванням — це ті, для яких виконані калібрування на QPU, тому не потрібно надавати додаткових інструкцій/імпульсних вентилів. Наприклад, на деяких QPU cx є двокубітним вентилем за замовчуванням, а на інших — ecr. Дивись список можливих рідних вентилів та операцій для отримання детальнішої інформації.

pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)

Вихідні дані попереднього блоку коду

Зауваж, що об'єкти CXGate були розкладені на вентилі ecr та однокубітні базові вентилі.

Частоти помилок пристрою

Клас Target може містити інформацію про частоти помилок для операцій на пристрої. Наприклад, наступний код отримує властивості для вентиля відлунного перехресного резонансу (ECR) між кубітами 1 та 0 (зауваж, що вентиль ECR є напрямленим):

target["ecr"][(1, 0)]
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)

Вихідні дані відображають тривалість вентиля (у секундах) та його частоту помилок. Щоб розкрити інформацію про помилки для транспілятора, побудуй цільову модель з basis_gates та coupling_map зверху і заповни її значеннями помилок з бекенду FakeSherbrooke.

from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp

err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)

for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)

Транспілюй з нашою новою ціллю err_targ як ціллю:

pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)

Вихідні дані попереднього блоку коду

Оскільки ціль включає інформацію про помилки, прохід VF2PostLayout намагається знайти оптимальні кубіти для використання, що призводить до тієї ж схеми, яка була спочатку знайдена з тими самими фізичними кубітами.

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