Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Используйте qodec и модуль qdk.ec из Microsoft Quantum Development Kit (QDK) для определения кода исправления квантовых ошибок (QEC) и превратите его в исполняемый протокол. В этой статье вы определите код ошибки, создадите базовую линию qodec, проверьте свои объявления, вычислите расстояние между гаджетами и сохраните протокол.
В примерах в этой статье используется код $[[4,2,2]]$ C4 , который хранит два логических кубита в четырех физических кубитах и обнаруживает любую одну физическую Pauli ошибку.
Prerequisites
Выполните следующие задачи перед началом работы:
- Установите QDK для исправления ошибок.
- Используйте среду с Python версией 3.11 или более поздней версии.
- Убедитесь, что qodecStim средство синтаксического анализа доступно. В Arm64Windows или LinuxArm64 установите Stim из исходного кода, а затем перезапустите Python или ядро Jupyter перед вызовом
build_qodec.
Определите код
qodec.Code Создайте объект со стабилизаторами кода и по одному логическому представителю X и по одному Z для каждого логического кубита.
import qodec
c4 = qodec.Code(
"C4",
stabilizers=["X_0 X_1 X_2 X_3", "Z_0 Z_1 Z_2 Z_3"],
x=["X_0 X_1", "X_0 X_2"],
z=["Z_0 Z_2", "Z_0 Z_1"],
)
Пакет qodec использует разреженную нотацию для Pauli строк. Каждый термин имеет Pauli букву и физическую метку кубита. Например, X_0 X_2 применяет X к физическим кубитам 0 и 2.
Определение кода является статическим математическим объектом. Он не включает схемы, которые подготавливают, сохраняют или измеряют закодированные состояния.
Анализ кода
Чтобы просмотреть моментальный снимок операторов Code, создайте CodeProfile.
from qdk import ec
profile = ec.CodeProfile(c4)
print("Physical support:", sorted(profile.support))
print("Physical qubits:", profile.length)
print("Logical qubits:", profile.logical_qubit_count)
print("Stabilizers:", profile.stabilizers)
print("Logical X operators:", profile.x)
print("Logical Z operators:", profile.z)
Профиль не изменяется, если вы позже измените исходный объект qodec.Code.
Вычислите расстояние кода
Чтобы найти минимальное количество разрешенных физических ошибок, которые вызывают нетривиальный логический эффект при нулевом синдроме, вызовите distance.
distance = profile.distance()
print("Code distance:", distance)
error = distance.witness.product
syndrome = profile.syndrome_of(error)
logical_effect = profile.logical_effect_of(error)
print("Witness:", error)
print("Syndrome:", sorted(syndrome))
print("Logical effect:", logical_effect)
assert distance.value == 2
assert profile.is_logical(error)
По умолчанию поиск назначает стоимость, равную единице, для каждой однокубитной ошибки X, Y или Z. Возвращенный Distance объект имеет сертифицированные границы и свидетельство для любой конечной верхней границы.
Когда полный точный поиск слишком затратен, используйте distance_bounds.
bounds = profile.distance_bounds(upper_bound=4)
print("Distance bounds:", bounds)
print("Lower bound:", bounds.lower_bound)
print("Upper bound:", bounds.upper_bound)
Решатель по умолчанию — HiGHS. Чтобы использовать другой решатель, задайте solver="enumeration", или установите MWPF и задайте solver="mwpf".
Создайте базовый план qodec
qodec описывает, как запускать закодированные инструкции. Он содержит наборы инструкций, коды, слои, гаджеты, схемы, проверки и уравнения чтения.
Используйте build_qodec для создания двухуровневого протокола из кода C4.
protocol = ec.build_qodec(
c4,
strategy="bare-css/v1",
strict=False,
)
В этом примере bare-css/v1 используется для проверки простого протокола без кубитов флагов.
Caution
Стратегия bare-css/v1 не обещает отказоустойчивые схемы. Вычислите дистанцию каждого гаджета перед использованием протокола для шумных экспериментов.
Построитель пытается создать следующие логические инструкции:
prepare_z_allprepare_x_allsyndromemeasure_z_allmeasure_x_allh_allcx_all
Суффикс _all означает, что инструкция действует на каждом логическом кубите в блоке. Например, cx_all применяет CNOT между соответствующими логическими кубитами в двух блоках.
Не каждый код поддерживает каждую инструкцию-кандидат. Если используется strict=True по умолчанию, построитель вызывает ошибку, когда он не может построить и проверить кандидата. С strict=False построитель сохраняет поддерживаемые инструкции и записи об упущениях в protocol.metadata["qdk.ec"]["build"]["omitted"].
Проверьте логический слой и его гаджеты.
logical_layer = protocol.layers[0]
print("Instructions:")
for mnemonic in logical_layer.instruction_set.instructions:
print(" -", mnemonic)
print("Gadgets:")
for mnemonic in logical_layer.gadgets:
print(" -", mnemonic)
Второй уровень содержит физическую систему команд Stim, используемую созданными схемами.
Проверить гаджет
Логическая инструкция объявляет контракт. Его гаджет дает схему, реализующую контракт.
prepare_z_all Проверьте гаджет.
gadget = logical_layer.gadgets["prepare_z_all"]
gadget_profile = ec.GadgetProfile(gadget)
print("Declared objective:")
print(gadget_profile.objective)
print("Computed action:")
print(gadget_profile.action)
Сравните результат, вычисленный по схеме, с объявленной целью инструкции.
objective = gadget_profile.objective
assert objective is not None
if gadget_profile.action.is_equivalent_to(objective):
print("The gadget implements its declared instruction.")
else:
print(objective.why_not_equivalent_to(gadget_profile.action))
GadgetProfile создает моментальный снимок входных данных, поэтому он не отражает последующие изменения. После изменения гаджета создайте новый профиль.
Проверьте протокол
Используйте audit для проверки всего qodec.
report = ec.audit(protocol)
print(report)
Если аудит не находит ошибок или предупреждений, он выводит:
audit: ok
Аудит проверяет следующие области:
- Алгебра кода
- Инструкция и структура слоя
- Вызовы схем и привязки параметров
- Действия гаджета
- Проверки и уравнения вывода
- Уравнения с флагами
- Отношения входных и выходных фреймов
- Границы ссылок и полнота протокола
Чтобы реагировать на определенные уровни серьезности, используйте коллекции отчетов.
if report.errors:
for diagnostic in report.errors:
print(diagnostic)
raise ValueError("The qodec has audit errors.")
if report.warnings:
for diagnostic in report.warnings:
print(diagnostic)
Значение report.ok означает, что отчет не имеет ошибок. Предупреждения этого не меняют.
Вывести недостающие уравнения
Используйте filled, когда черновик виджета или qodec не содержит проверок или логических уравнений считывания, которые можно получить с помощью точного моделирования.
В следующем примере создается неполная копия протокола.
draft = qodec.Qodec.loads(protocol.dumps())
draft_gadgets = draft.layers[0].gadgets
draft_gadgets["measure_x_all"].readouts = []
draft_gadgets["cx_all"].checks = []
print(ec.audit(draft))
Заполните поддерживаемые уравнения, а затем проверьте результат.
completed = ec.filled(draft)
print(ec.audit(completed))
Функция filled возвращает новый гаджет или qodec и не изменяет входные данные. Он выводит проверки, уравнения наблюдаемых выходов и соотношения систем отсчета. Он сохраняет привязки флагов, так как безошибочное моделирование не может определить, какие ошибки должен обнаруживать флаг.
Если исходный протокол уже содержит проверенные прямые уравнения, filled сохраняет их, когда это возможно.
Проанализируйте неисправности гаджета
Аудит без ошибок подтверждает бесшумную согласованность. Это не является доказательством отказоустойчивости.
Вызов GadgetProfile.distance, чтобы найти минимальное количество разрешенных неисправностей схемы, при котором происходит логический сбой, а все объявленные проверки и флаги остаются нулевыми. Объединенная неисправность также должна обеспечивать, чтобы каждый выход оставался в пределах своего кодового пространства.
protocol = completed
for mnemonic, gadget in sorted(protocol.layers[0].gadgets.items()):
result = ec.GadgetProfile(gadget).distance()
witness = result.witness if result.upper_bound is not None else "none"
print(f"{mnemonic}: distance={result}, witness={witness}")
Модель сбоя по умолчанию включает эти события после каждого вызова прерывателя цепи:
- Ошибка Pauli в кубитах, затронутых вызовом
- Инверсия бита считывания, которую производит вызов
- Коррелированная комбинация этих ошибок
Каждое событие за один вызов стоит один, даже если оно имеет коррелированную многоквибитную ошибку.
Код может иметь расстояние два, а один из его gadget'ов имеет расстояние один. Например, сбой в одной цепи может распространяться через анциллу и создавать незамеченную логическую ошибку. Добавьте проверки или флаги контуров, а затем создайте новый GadgetProfile и вычислите расстояние еще раз.
Проверить определенный сбой
Используйте FaultEvent.after для определения сбоя после индекса вызова цепи с нумерацией с нуля.
gadget = protocol.layers[0].gadgets["syndrome"]
profile = ec.GadgetProfile(gadget)
fault = ec.FaultEvent.after(0, ec.Pauli("X_0"))
(effect,) = profile.effects_of([fault])
print("Fault:", fault)
print("Changed quantities:", effect)
FaultEffect может включать измененные проверки, логические считывания и знаки выходного кадра. Используйте явные наборы ошибок, если модель уровня схемы по умолчанию не соответствует предположениям оборудования.
result = profile.distance(faults=[fault])
print(result)
Точный поиск гаджетов может занять много времени, так как набор ошибок по умолчанию увеличивается экспоненциально с поддержкой каждого вызова. Используйте distance_bounds, явный набор отказов или upper_bound, если необходимо ограничить поиск.
Сохранить протокол
Проверьте окончательный qodec перед тем как сохранить его.
report = ec.audit(protocol)
if report.errors or report.warnings:
raise ValueError(str(report))
Сохраните протокол в виде одного YAML bundle и снова загрузите его, чтобы убедиться, что он соответствует исходному.
from pathlib import Path
output_directory = Path("qodec-output")
output_directory.mkdir(exist_ok=True)
saved_path = protocol.save(str(output_directory), single_file=True)
loaded = qodec.Qodec.load(saved_path)
assert loaded == protocol
print("Saved qodec:", saved_path)
Пакет с одним файлом хранит манифест, определения кода, наборы инструкций, гаджеты и исходные коды схем в одном YAML файле, что упрощает совместное использование и перезагрузку.
Запустите протокол
После того как qodec пройдет аудит и будет соответствовать вашим требованиям к расстоянию, скомпилируйте логическую программу в Quantum Intermediate Representation (QIR) и выполните ее через протокол. См. "Запуск и декодирование логических программ".
Полный пример, который добавляет схемы флагов и сравнивает логические частоты ошибок, см. в пошаговом руководстве по протоколу QEC в QDK репозитории GitHub.