RFC 016: Квантовая нативная поддержка и интеграция с множественными бэкендами
Причина отклонения: Недостаточно предварительных зависимостей. Механизм Primitive::Extension ещё не реализован, компилятор языка не завершён, нет реальных пользовательских запросов. Квантовая поддержка должна быть переоценена после созревания языка как потребитель механизма Extension.
Зависимости:
Аннотация
В данном документе определяется квантовая нативная поддержка и интеграция с множественными бэкендами для языка YaoXiang. Основная идея: существующий дизайн YaoXiang (по умолчанию Move, возврат владения, непрозрачные типы, DAG-планировщик, обобщённые константные параметры) естественным образом формирует полную основу для квантового языка программирования без необходимости введения какого-либо нового квантового специализированного синтаксиса. Мы добавляем небольшое количество встроенных типов (Qubit, Complex, Topology) и встроенных функций (квантовые вентили, измерения, топологические ограничения), используя существующие механизмы языка для реализации квантовой нативной семантики, автоматического параллелизма для максимального использования квантовых возможностей, гибридного классического программирования и поддержки множественных бэкендов.
Мотивация
Зачем нужна квантовая нативная поддержка?
Текущая экосистема квантового программирования имеет серьёзные разрывы:
- Низкоуровневые языки (QCIS, OpenQASM): напрямую управляют физическими квантовыми вентилями, но не имеют системы типов и механизмов абстракции, что затрудняет написание сложных алгоритмов.
- Высокоуровневые фреймворки (Qiskit, Cirq, Q#): построены на расширении классических языков (Python, C#), квантовая семантика реализуется через библиотеки, что приводит к:
- Правило о невозможности клонирования квантового состояния требует ручного соблюдения пользователем (или зависит от линейной системы типов, добавленной позже).
- Синтаксис операций квантовых вентилей отделён от классического кода, высокая стоимость обучения.
- Гибридные вычисления: квантовая и классическая части требуют явного разделения, отсутствует унифицированная модель потока данных.
Текущие проблемы
Существующий дизайн YaoXiang恰好提供ёт полную основу для решения этих проблем:
| Потребности квантовых вычислений | Существующий дизайн YaoXiang | Описание |
|---|---|---|
| Невозможность клонирования квантового состояния | Семантика Move по умолчанию | Присваивание передаёт владение, без неявного копирования, естественно соответствует теореме о неклонировании |
| Квантовые вентили как унитарные преобразования | Возврат владения | q = H(q) потребляет исходный qubit, возвращает новый qubit, точно соответствует семантике вентиля |
| Состояния запутывания | Непрозрачные типы | BellPair можно оперировать только целиком, компилятор отслеживает время жизни, предотвращает неправильное разложение |
| Ограничения физической топологии | Обобщённые константные параметры | Qubit(Topology, N) — проверка смежности на этапе компиляции |
| Коллапс при измерении | Повторное использование пустого состояния | После измерения qubit становится пустым, можно переинициализировать, имитируя квантовый коллапс |
| Автоматический параллелизм квантовых схем | DAG-планировщик | Операторы внутри функции автоматически распараллеливаются по зависимостям данных, вентили без зависимостей естественно параллельны |
| Гибридный классическо-квантовый поток управления | Унифицированный синтаксис | Квантовые и классические операции используют одинаковую форму name: type = value |
YaoXiang — это не "добавление квантовой поддержки", а обнаружение того, что его дизайн уже является квантовым нативным.
Пояснение семантики: В данном документе используется семантика владения YaoXiang для выражения квантовых операций. На уровне компилятора гарантируется неклонирование (безопасность владения). На уровне языка "потребление-создание" является синтаксическим выражением передачи владения — потребление = получение владения, возврат = передача владения. Базовая реализация может использовать реальные обратимые квантовые вентили (изменение квантового состояния на месте), а не реальное "создание нового квантового состояния".
Цели проектирования
- Ноль нового синтаксиса: не вводить ключевые слова вроде
quantum,circuit, все квантовые возможности выражаются через существующие механизмы языка. - Безопасность типов: компилятор гарантирует, что квантовые состояния не копируются и не используются неправомерно.
- Проверка топологических ограничений на этапе компиляции: через обобщённые константные параметры
Qubit(T, N)проверяется соответствие двухкубитных вентилей физической топологии на этапе компиляции. - Прозрачная поддержка множественных бэкендов: один и тот же квантовый код может компилироваться в QIR (универсальная экосистема) или QCIS (отечественный квантовый набор команд), переключение через параметры командной строки.
- Бесшовное гибридное классическое: квантовые вычисления могут свободно вызывать классические функции, классический код также может оперировать квантовыми данными (через общий доступ
ref, но с ограничениями владения).
Предложение
Базовый дизайн
1. Маппинг квантовой системы типов
Базовые типы:
Qubit: Type0 = primitive_qubit
Complex: Type0 = { re: Float, im: Float }Qubit— тип первого класса, следует правилам владения (Move, RAII).Complexиспользуется для представления амплитуды, компилятор может выполнить встраивание и оптимизацию.
Квантовые вентили как функции:
# Сигнатуры встроенных функций
H: (Qubit) -> Qubit = builtin_hadamard
X: (Qubit) -> Qubit = builtin_pauli_x
Y: (Qubit) -> Qubit = builtin_pauli_y
Z: (Qubit) -> Qubit = builtin_pauli_z
CNOT: (control: Qubit, target: Qubit) -> { Qubit, Qubit } = builtin_cnot- Все вентили потребляют входной qubit, возвращают новый qubit (или пару запутывания). Синтаксис возврата владения
q = H(q)напрямую соответствует математической семантике. - Многокубитные вентили возвращают структуры, результат получается через сопоставление с образцом или доступ к полям.
Измерение:
measure: (Qubit) -> Int = builtin_measure # Потребляет qubit, возвращает классический бит
measure_all: (List(Qubit)) -> List(Int) = builtin_measure_all- После измерения qubit потребляется (становится пустым), пользователь может переинициализировать через повторное использование пустого состояния.
Инициализация:
qubit: (Int) -> Qubit = builtin_qubit # Инициализация базового состояния 0 или 12. Запутывание и инкапсуляция непрозрачных типов
Пара запутывания инкапсулируется как непрозрачный тип, предоставляются только операции объединения, разложение запрещено:
# Встроенные непрозрачные типы
BellPair: Type0 = primitive_bell_pair
# Встроенные функции — только целостные операции
CNOT: (Qubit, Qubit) -> BellPair
measure_bell: (BellPair) -> { Int, Int }
split_bell: (BellPair) -> { Qubit, Qubit } # Разложение пары запутывания (требует осторожного использования)
apply_cnot_to_bell: (BellPair, Qubit) -> BellPairКлючевой дизайн:
- Доступ к полям не предоставляется, разрешены только целостные операции через встроенные функции
measure_bell(bp)потребляет всю пару запутывания за один раз, возвращает классические биты- Компилятор может отслеживать полный жизненный цикл пары запутывания
Сравнение с Python/Qiskit:
Python (Qiskit): Построение схемы во время выполнения, ошибки могут быть обнаружены только после отправки
YaoXiang: Большинство логических ошибок перехватываются на этапе компиляцииОставшиеся 10% (такие как физическая декогеренция, погрешности вентилей) — это проблемы оборудования, которые язык не может решить.
3. Ограничения физической топологии
Квантовый чип — это топологический граф с ограничениями, не любые два кубита могут выполнять двухкубитный вентиль, они должны быть смежными. YaoXiang использует обобщённые константные параметры для гарантии топологических ограничений на этапе компиляции.
Определение типа топологии:
# Топология как тип, содержит матрицу смежности
Topology: Type0 = primitive_topology
# Встроенные топологические константы
Linear8: Topology = topology(8) # Линейная 8-битная: 0-1-2-3-4-5-6-7
Grid3x3: Topology = topology(3, 3) # Сетка 3x3
Ring16: Topology = topology(16, ring) # Кольцевая 16-битнаяQubit привязан к топологии и позиции:
# Qubit(T, N) — T это тип топологии, N — константный позиционный параметр
q0: Qubit(Grid3x3, 0) # Grid3x3 топология, позиция (0,0)
q1: Qubit(Grid3x3, 1) # Grid3x3 топология, позиция (0,1)
q2: Qubit(Grid3x3, 2) # Grid3x3 топология, позиция (0,2)
q3: Qubit(Grid3x3, 3) # Grid3x3 топология, позиция (1,0)Автоматические ограничения для операций вентилей:
# Сигнатура типа CNOT с топологическим ограничением
CNOT: (T: Topology, I: Int, J: Int) -> (
(Qubit(T, I), Qubit(T, J)) -> { Qubit(T, I), Qubit(T, J) }
) when adjacent(T, I, J)
# Проверка на этапе компиляции
CNOT(q0, q1) # ✅ В Grid3x3 (0,0) и (0,1) смежны
CNOT(q0, q2) # ❌ Ошибка компиляции: (0,0) и (0,2) не смежныadjacent — ограничение на этапе компиляции:
adjacent— это функция этапа компиляции, использующая матрицу смежности топологии для статической проверки- При константных индексах — 100% проверка на этапе компиляции
- При динамических индексах — генерация кода проверки во время выполнения
Отображение виртуальных на физические кубиты:
# Конкретная физическая позиция неизвестна на этапе компиляции? Используйте вывод типов
q = qubit(Grid3x3) # Автоматическое распределение позиции 0, дальнейший вывод4. Владение и линейный поток квантовых состояний
Все квантовые операции следуют семантике Move, гарантируя, что qubit не копируется:
q = qubit(0)
q2 = q # ❌ Ошибка компиляции: q уже перемещён, нельзя использовать повторно
q = H(q) # ✅ Потребляет q, возвращает новый q
measure(q) # ✅ Потребляет q, после чего q становится пустым
q = qubit(0) # ✅ Повторное использование пустого состояния4. Автоматический параллелизм и DAG-планировщик
В Standard или Full Runtime DAG-планировщик автоматически анализирует квантовую программу:
apply_two_qubit_gates: () -> {Qubit, Qubit} = () => {
q1 = H(qubit(0))
q2 = H(qubit(0))
# Вышеуказанные две строки не имеют зависимости по данным, DAG автоматически параллелизует
CNOT(q1, q2) # Зависит от q1 и q2, автоматическое ожидание
}- Планировщик использует конфигурацию
num_workers(количество физических квантовых процессоров) для реального параллелизма. - Пользователю не нужно вручную упорядочивать вентили, достаточно описать поток данных.
5. Гибридные классические вычисления
Классический и квантовый код полностью слиты:
grover_search: (target: Int) -> Int = () => {
n = 4
qubits = List(Qubit)()
for i in 0..n {
qubits.append(H(qubit(0)))
}
# Классический цикл смешан с квантовыми операциями
oracle(qubits, target) # oracle — это последовательность квантовых вентилей
qubits = diffusion(qubits)
results = measure_all(qubits)
return decode_result(results) # Классическая постобработка
}- В одной функции можно произвольно смешивать квантовые вентили и классический поток управления.
- Система владения гарантирует, что квантовые переменные не будут ошибочно скопированы в классических ветвлениях.
6. Архитектура поддержки множественных бэкендов
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ YaoXiang源 │ │ Проверка │ │ DAG промеж. │
│ (унифициров. │ │ типов │ │ представление │
│ синтаксис) │────▶│ + анализ влад. │────▶│ (граф данных)│
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Бэкенды кодогенерации (вставляемые) │
├─────────────────┬───────────────────────────┤
│ QIR бэкенд │ QCIS бэкенд │
│ (универс. экос.)│ (отечеств. квант. инстр.)│
├─────────────────┼───────────────────────────┤
│ - Вывод .ll │ - Вывод .qcis текста │
│ файла │ - Адаптация CAS/Гуандунь│
└─────────────────┴───────────────────────────┘- Процесс компиляции: унифицированный фронтенд → построение DAG → выбор бэкенда → генерация целевого кода.
- QIR бэкенд: маппит узлы DAG на квантовые вентили intrinsic QIR, генерирует LLVM bitcode, может использовать оптимизацию LLVM.
- QCIS бэкенд: сериализует DAG в команды QCIS (например,
H q0), поддерживает прямую отправку на консоль квантового чипа.
Примеры
Приготовление и измерение состояния Белла
bell_measure: () -> {Int, Int} = () => {
q1 = H(qubit(0))
q2 = H(qubit(0))
bell = CNOT(q1, q2) # Возвращает непрозрачный тип BellPair
result = measure_bell(bell) # Одновременное измерение двух битов
return result
}Квантовая телепортация (упрощённая)
teleport: (msg: Qubit, bell: BellPair) -> Qubit = (msg, bell) => {
# Разложение пары запутывания для получения двух независимых кубитов
(alice_qubit, bob_qubit) = split_bell(bell)
# Операции Алисы
(msg, alice_qubit) = CNOT(msg, alice_qubit)
msg = H(msg)
a1 = measure(msg)
a2 = measure(alice_qubit)
# Передача классической информации (автоматическая обработка зависимостей планировщиком)
# Операции Боба
if a2 == 1 { bob_qubit = X(bob_qubit) }
if a1 == 1 { bob_qubit = Z(bob_qubit) }
return bob_qubit
}Детальной дизайн
Определения встроенных типов и функций
В модуле compiler/builtins добавить:
builtins.insert("Qubit", Ty::Primitive(Primitive::Qubit));
builtins.insert("Complex", Ty::Record(vec![
("re", Ty::Primitive(Primitive::Float)),
("im", Ty::Primitive(Primitive::Float)),
]));
// Квантовые вентили
for (name, sig) in GATES {
builtins.insert(name, Ty::Function(vec![Ty::Qubit], Ty::Qubit));
}
builtins.insert("CNOT", Ty::Function(
vec![Ty::Qubit, Ty::Qubit],
Ty::Record(vec![
("q0", Ty::Qubit),
("q1", Ty::Qubit)
])
));
builtins.insert("measure", Ty::Function(vec![Ty::Qubit], Ty::Primitive(Primitive::Int)));
builtins.insert("qubit", Ty::Function(vec![Ty::Primitive(Primitive::Int)], Ty::Qubit));Специальная обработка Qubit в проверке владения
Qubitпомечен как!Copy(по умолчанию Move), неявное копирование запрещено.- Параметр функции измерения
measureимеет типQubit(передача по значению), потребляет владение. - В записях типов, возвращаемых многокубитными вентилями, все поля имеют тип
Qubit, необходимо соблюдать правила владения.
Оптимизация DAG-планировщиком квантовых вентилей
- Узлы квантовых вентилей рассматриваются как чистые функции (без побочных эффектов), планировщик может произвольно переупорядочивать вентили без зависимостей.
- При выводе "последовательности квантовых команд" планировщик сохраняет зависимости данных и группирует параллельные вентили (применимо для многокубитных процессоров).
- Поддержка настройки
--target-num-qubitsи--target-topologyдля последующей раскладки и маршрутизации (будущее расширение).
Детальный маппинг QIR бэкенда
| Операция YaoXiang | Команда QIR |
|---|---|
H(q) | call void @__quantum__qis__h__body(%Qubit* %q) |
CNOT(q1, q2) | call void @__quantum__qis__cnot__body(%Qubit* %q1, %Qubit* %q2) |
measure(q) | %result = call i1 @__quantum__qis__mz__body(%Qubit* %q) |
qubit(0) | %q = call %Qubit* @__quantum__rt__qubit_allocate() |
QIR бэкенд использует LLVM -O2 для дальнейшей оптимизации и выводит bitcode, совместимый с QIR Alliance.
Детальный маппинг QCIS бэкенда
| Операция YaoXiang | Команда QCIS |
|---|---|
H(q) (q соответствует физическому биту 2) | H 2 |
CNOT(q1,q2) (q1→бит 0, q2→бит 1) | CNOT 0 1 |
measure(q) (бит 0) | M 0 |
qubit(0) инициализация | Неявна в первой команде использования, не требует дополнительной команды |
- Необходимо вести таблицу отображения виртуальных кубитов (переменных YaoXiang) на физические биты.
- Поддержка проверки топологических ограничений (будущая реализация).
Генерация гибридного классического кода
- Классическая часть (такая как циклы, условия, целочисленные операции) генерирует нативный код (x86/ARM), взаимодействие с квантовым бэкендом через FFI или встроенные вызовы.
- В QIR бэкенде классическая часть может быть понижена до LLVM IR, смешанная компиляция с QIR.
Влияние на систему типов
- Добавлены примитивные типы
QubitиComplex. Qubitавтоматически имеет семантику Move, копирование запрещено.- Сигнатуры функций квантовых вентилей необходимо зарегистрировать в системе типов.
Обратная совместимость
- ✅ Полная обратная совместимость
- Добавление встроенных типов и функций не влияет на существующий код
- Квантовые возможности опциональны, без дополнительных затрат при отключении
Компромиссы
Преимущества
- Нет нового синтаксиса: разработчикам нужно выучить лишь несколько встроенных функций для написания квантовых программ.
- Безопасность типов: система владения автоматически предотвращает копирование кубитов, избегая распространённых ошибок квантового программирования.
- Автоматический параллелизм: DAG-планировщик бесплатно предоставляет параллелизм на уровне вентилей без дополнительной оптимизации компилятора.
- Совместимость с экосистемой: QIR бэкенд позволяет YaoXiang работать на нескольких квантовых облачных платформах; QCIS бэкенд обеспечивает независимость и контроль.
- Гибридные возможности: естественное слияние классического и квантового кода, подходит для написания сложных квантовых алгоритмов (классическое управление в Shor, Grover).
Недостатки
- Статическое количество кубитов: текущий дизайн предполагает, что количество кубитов известно на этапе компиляции, динамическое распределение через
List(Qubit), но кучевое выделениеListможет добавить дополнительные накладные расходы (можно смягчить оптимизацией). - Повторное использование после измерения: повторное использование пустого состояния позволяет переинициализировать кубит, но физические квантовые биты могут иметь время релаксации, требуется обработка в системе выполнения (в настоящее время ответственность пользователя).
- Динамическое топологическое отображение: когда физическая топология становится известной только во время выполнения, проверка на этапе компиляции неприменима, требуется генерация кода проверки во время выполнения (текущая версия поддерживает только статическую проверку).
Альтернативные варианты
| Вариант | Почему не выбран |
|---|---|
Введение ключевого слова quantum и типа circuit | Добавление нового синтаксиса, высокая стоимость обучения, противоречит принципу простоты дизайна YaoXiang |
| Реализация квантовой поддержки только как библиотеки | Невозможность использования гарантий компилятора для безопасности квантовых состояний, невозможность глубокой интеграции с DAG-планировщиком |
| Ожидание созревания квантового оборудования перед поддержкой | Упущение критического окна возможностей для дизайна языка квантового программирования |
| Повторное использование существующих квантовых фреймворков (например, Qiskit) | Квантовая семантика реализуется через библиотеку, невозможно получить гарантии безопасности системы типов и владения |
| Разработка отдельного квантового подъязыка | Увеличение сложности языка, высокие затраты на поддержку |
Стратегия реализации
Разделение на этапы
| Этап | Время | Содержание |
|---|---|---|
| Phase 1 | 1 месяц | Базовые квантовые типы и встроенные функции: добавление типов Qubit, Complex в компилятор, реализация проверки типов встроенных функций, расширение проверки владения |
| Phase 2 | 1 месяц | DAG-планировщик распознаёт квантовые вентили: модификация логики построения DAG, пометка квантовых вентилей как чистых функций, реализация группового вывода параллельных вентилей |
| Phase 3 | 2 месяца | Прототип QIR бэкенда: реализация генератора кода из DAG в QIR, интеграция LLVM, подключение QIR симулятора для верификации |
| Phase 4 | 2 месяца | Прототип QCIS бэкенда: реализация транслятора из DAG в команды QCIS, проектирование маппинга виртуальных-физических битов, подключение отечественной квантовой платформы для верификации |
| Phase 5 | 2 месяца | Усиление гибридного классического: обеспечение корректной кодогенерации при пересечении классического потока управления и квантовых вентилей, поддержка List(Qubit), добавление примеров программ |
| Phase 6 | 2 месяца | Оптимизация и документация: реализация базовой раскладки и маршрутизации, написание руководства пользователя и учебника по квантовому программированию, выпуск предварительной версии |
Риски
Доступность квантового оборудования: зависимость от доступности внешних квантовых симуляторов и реальных QPU.
- Смягчение: приоритет подключения к открытым симуляторам (QIR runner, Qiskit Aer), реальные QPU как долгосрочная цель.
Сложность реализации бэкендов: спецификации QIR и QCIS могут измениться.
- Смягчение: абстракция интерфейса кодогенерации, изоляция различий бэкендов, удобство последующей адаптации.
Неопределённость производительности: характеристики производительности квантовых программ отличаются от классических.
- Смягчение: предоставление инструментов профилирования, чтобы пользователи понимали эффект параллелизма на уровне вентилей.
Открытые вопросы
- [x] Топологические ограничения: реализовано через обобщённые константные параметры
Qubit(Topology, N)с проверкой на этапе компиляции. - [ ] Динамический квантовый регистр: как
List(Qubit)отображается в QCIS бэкенде? Можно генерировать физические биты соответствующего количества, но требуется механизм распределения во время выполнения. - [ ] Смягчение ошибок: предоставлять ли встроенные конструкции смягчения ошибок (например, динамическая декoupling)? Можно сначала реализовать как библиотеку.
- [ ] Взаимодействие с существующими квантовыми SDK: можно ли импортировать модули QASM или QIR? В будущем можно рассмотреть FFI.
- [ ] Автоматическая раскладка и маршрутизация: когда количество виртуальных кубитов превышает количество физических кубитов, как автоматически отобразить?
Ссылки
- QIR Specification
- QCIS: A Quantum Control Instruction Set (USTC/Гуандунь)
- Rust Quantum Computing Examples
- Qunity: A Unified Language for Quantum and Classical Computing (2025)
Жизненный цикл и судьба
┌─────────────┐
│ Черновик │ ← Автор создаёт
└──────┬──────┘
│
▼
┌─────────────┐
│ На проверке│ ← Обсуждение сообщества
└──────┬──────┘
│
├──────────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Принято │ │ Отклонено │
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ accepted/ │ │ rfc/ │
│ (официальный│ │ (сохранение │
│ дизайн) │ │ на месте) │
└─────────────┘ └─────────────┘Пояснение статуса
| Статус | Расположение | Описание |
|---|---|---|
| Черновик | docs/design/rfc/draft/ | Черновик автора, ожидает подачи на проверку |
| На проверке | docs/design/rfc/ | Открытое обсуждение и обратная связь сообщества |
| Принято | docs/design/accepted/ | Становится официальным документом дизайна, переходит в фазу реализации |
| Отклонено | docs/design/rfc/ | Сохраняется в каталоге RFC, статус обновлён |
