Skip to content

RFC 016: 量子原生支持与多重后端集成

拒绝原因: 前置依赖不足。Primitive::Extension 机制尚未实现,语言编译器未完成,无实际用户需求。量子支持应作为 Extension 机制的消费者在语言成熟后重新评估。

依赖:

摘要

本文档定义 YaoXiang 语言的量子原生支持多重后端集成方案。核心思想:YaoXiang 的现有设计(默认 Move、所有权回流、不透明类型、DAG 调度器、泛型常量参数)天然构成量子编程语言的完整基础,无需引入任何新的量子专用语法。我们通过添加少量内置类型(QubitComplexTopology)和内置函数(量子门、测量、拓扑约束),并利用现有语言机制,实现量子原生语义、自动并行最大化量子利用率、混合经典编程,以及多重后端支持。

动机

为什么需要量子原生支持?

当前量子编程生态存在严重割裂:

  • 低级语言(QCIS、OpenQASM):直接操作物理量子门,但缺乏类型系统、抽象机制,难以编写复杂算法。
  • 高级框架(Qiskit、Cirq、Q#):基于经典语言(Python、C#)扩展,量子语义通过库实现,导致:
    • 量子态不可克隆规则需用户手动遵守(或依赖线性类型系统后补)。
    • 量子门操作与经典代码语法割裂,学习成本高。
  • 混合计算:量子与经典部分需显式分离,缺乏统一数据流模型。

当前问题

YaoXiang 的已有设计恰好为解决这些问题提供了完备基础:

量子计算需求YaoXiang 已有设计说明
量子态不可克隆默认 Move 语义赋值即移动所有权,无隐式复制,天然符合 no-cloning 定理
量子门作为酉变换所有权回流q = H(q) 消费原 qubit,返回新 qubit,精确对应门语义
纠缠态不透明类型BellPair 只能整体操作,编译器追踪生命周期,防止误拆解
物理拓扑约束泛型常量参数Qubit(Topology, N) 编译期检查相邻性
测量坍缩空状态重用测量后 qubit 变空,可重新初始化,模拟量子态坍缩
量子线路自动并行DAG 调度器函数内语句根据数据依赖自动并行,无依赖的门天然并发
混合经典-量子控制流统一语法量子操作与经典操作使用相同 name: type = value 形式

YaoXiang 不是"添加量子支持",而是发现自己的设计已经量子原生。

语义说明:本文档使用 YaoXiang 的所有权语义来表达量子操作。编译器层面保证 no-cloning(所有权安全)。语言层面的"消费-创建"是所有权转移的语法表达——消费 = 获取所有权,返回 = 移交所有权。底层实现可以是真正的可逆量子门(原地修改量子态),而非真正"创建新量子态"。

设计目标

  1. 零新语法:不引入 quantumcircuit 等关键字,所有量子特性通过现有语言机制表达。
  2. 类型安全:编译器保证量子态不被复制、不被不合法使用。
  3. 拓扑约束编译期检查:通过泛型常量参数 Qubit(T, N) 在编译期验证双比特门操作是否符合物理拓扑。
  4. 多重后端透明:同一份量子代码可编译到 QIR(通用生态)或 QCIS(国产量子指令集),通过命令行参数切换。
  5. 混合经典无缝:量子计算可自由调用经典函数,经典代码也可操作量子数据(通过 ref 共享,但受所有权约束)。

提案

核心设计

1. 量子类型系统映射

基础类型

yaoxiang
Qubit: Type0 = primitive_qubit
Complex: Type0 = { re: Float, im: Float }
  • Qubit 是一等公民类型,遵循所有权规则(Move、RAII)。
  • Complex 用于表示振幅,编译器可内联优化。

量子门作为函数

yaoxiang
# 内置函数签名
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) 直接对应数学语义。
  • 多 qubit 门返回结构体,通过模式匹配或字段访问获取结果。

测量

yaoxiang
measure: (Qubit) -> Int = builtin_measure   # 消费 qubit,返回经典比特
measure_all: (List(Qubit)) -> List(Int) = builtin_measure_all
  • 测量后 qubit 被消费(变空),用户可通过空状态重用重新初始化。

初始化

yaoxiang
qubit: (Int) -> Qubit = builtin_qubit   # 0 或 1 初始化基态

2. 纠缠与不透明类型封装

将纠缠对封装为不透明类型,只提供组合操作,禁止拆解:

yaoxiang
# 内置不透明类型
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. 物理拓扑约束

量子芯片是带约束的拓扑图,不是任意两个 qubit 都能做双比特门,必须相邻才行。YaoXiang 使用泛型常量参数在编译期保证拓扑约束。

拓扑类型定义

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 绑定拓扑和位置

yaoxiang
# 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)

门操作自动约束

yaoxiang
# 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% 编译期验证
  • 动态索引时生成运行时检查代码

虚拟到物理映射

yaoxiang
# 编译时不知道具体物理位置?使用类型推断
q = qubit(Grid3x3)  # 自动分配位置 0,后续推导

4. 所有权与量子态的线性流动

所有量子操作均遵循 Move 语义,确保 qubit 不被复制:

yaoxiang
q = qubit(0)
q2 = q          # ❌ 编译错误:q 已移动,不可再使用
q = H(q)        # ✅ 消费 q,返回新 q
measure(q)      # ✅ 消费 q,之后 q 变空
q = qubit(0)    # ✅ 空状态重用

4. 自动并行与 DAG 调度

在 Standard 或 Full Runtime 下,DAG 调度器自动分析量子程序:

yaoxiang
apply_two_qubit_gates: () -> {Qubit, Qubit} = () => {
    q1 = H(qubit(0))
    q2 = H(qubit(0))
    # 以上两行无数据依赖,DAG 自动并行执行
    CNOT(q1, q2)   # 依赖 q1 和 q2,自动等待
}
  • 调度器利用 num_workers 配置(物理量子处理器数量)实现真正并行。
  • 用户无需手动安排门顺序,只需描述数据流。

5. 混合经典计算

经典与量子代码完全融合:

yaoxiang
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 文本        │
                          │  - 适配多种 QPU  │  - 适配中科院/国盾硬件    │
                          └─────────────────┴───────────────────────────┘
  • 编译流程:前端统一 → DAG 构建 → 后端选择 → 目标代码生成。
  • QIR 后端:将 DAG 节点映射到 QIR 的量子门 intrinsic,生成 LLVM bitcode,可进一步利用 LLVM 优化。
  • QCIS 后端:将 DAG 序列化为 QCIS 指令(如 H q0),支持直接提交到量子芯片控制台。

示例

贝尔态制备与测量

yaoxiang
bell_measure: () -> {Int, Int} = () => {
    q1 = H(qubit(0))
    q2 = H(qubit(0))
    bell = CNOT(q1, q2)  # 返回 BellPair 不透明类型
    result = measure_bell(bell)  # 一次性测量两个比特
    return result
}

量子隐形传态(简化)

yaoxiang
teleport: (msg: Qubit, bell: BellPair) -> Qubit = (msg, bell) => {
    # 拆分纠缠对获取两个独立 qubit
    (alice_qubit, bob_qubit) = split_bell(bell)

    # Alice 操作
    (msg, alice_qubit) = CNOT(msg, alice_qubit)
    msg = H(msg)
    a1 = measure(msg)
    a2 = measure(alice_qubit)

    # 经典信息传递 (由调度器自动处理依赖)
    # Bob 操作
    if a2 == 1 { bob_qubit = X(bob_qubit) }
    if a1 == 1 { bob_qubit = Z(bob_qubit) }
    return bob_qubit
}

详细设计

内置类型与函数定义

compiler/builtins 模块中增加:

rust
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 门返回的记录类型中,字段均为 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 进一步优化,并输出与 QIR Alliance 兼容的 bitcode。

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) 初始化隐含在第一条使用指令中,无需额外指令
  • 需维护从虚拟 qubit(YaoXiang 变量)到物理比特的映射表。
  • 支持拓扑约束检查(未来实现)。

混合经典代码生成

  • 经典部分(如循环、条件、整数运算)照常生成本地代码(x86/ARM),通过 FFI 或嵌入式调用与量子后端交互。
  • 在 QIR 后端中,经典部分可降级为 LLVM IR,与 QIR 混合编译。

类型系统影响

  • 新增 QubitComplex 原始类型。
  • Qubit 自动具有 Move 语义,禁止复制。
  • 量子门函数签名需在类型系统中注册。

向后兼容性

  • ✅ 完全向后兼容
  • 新增内置类型和函数,不影响现有代码
  • 量子特性是可选的,不启用时无额外开销

权衡

优点

  • 无新语法:开发者只需学习少数内置函数,即可编写量子程序。
  • 类型安全:所有权系统自动防止 qubit 复制,避免常见量子编程错误。
  • 自动并行:DAG 调度器免费提供门级并行,无需额外编译器优化。
  • 生态兼容:QIR 后端使 YaoXiang 能运行在多家量子云平台上;QCIS 后端保障自主可控。
  • 混合能力:经典量子融合自然,适合编写复杂量子算法(如 Shor、Grover 中的经典控制)。

缺点

  • Qubit 数量静态:当前设计假定 qubit 数量在编译时已知,动态分配需通过 List(Qubit),但 List 的堆分配可能引入额外开销(可通过优化缓解)。
  • 测量后重用:空状态重用允许重新初始化 qubit,但物理量子比特可能存在弛豫时间,需运行时系统处理(目前由用户负责)。
  • 动态拓扑映射:运行时才知道物理拓扑时,编译期检查无法生效,需生成运行时检查代码(当前版本仅支持静态检查)。

替代方案

方案为什么不选择
引入 quantum 关键字和 circuit 类型增加新语法,学习成本高,违背 YaoXiang 简洁设计原则
仅作为库实现量子支持无法利用编译器保证量子态安全,无法与 DAG 调度器深度集成
等待量子硬件成熟再支持错过量子编程语言设计的关键窗口期
复用现有量子框架(如 Qiskit)量子语义通过库实现,无法获得类型系统和所有权系统的安全保障
单独设计量子子语言增加语言复杂度,维护成本高

实现策略

阶段划分

阶段时间内容
Phase 11个月基础量子类型与内置函数:在编译器中添加 QubitComplex 类型,实现内置函数的类型检查,扩展所有权检查器
Phase 21个月DAG 调度器识别量子门:修改 DAG 构建逻辑,标记量子门为纯函数,实现并行门分组输出
Phase 32个月QIR 后端原型:实现 DAG 到 QIR 代码生成器,集成 LLVM,连接 QIR 模拟器验证
Phase 42个月QCIS 后端原型:实现 DAG 到 QCIS 指令翻译,设计虚拟-物理比特映射,连接国产量子平台验证
Phase 52个月混合经典增强:确保经典控制流与量子门交叉正确生成代码,支持 List(Qubit),增加示例程序
Phase 62个月优化与文档:实现基本布局与路由,编写用户指南和量子编程教程,发布预览版

风险

  1. 量子硬件可用性:依赖外部量子模拟器和真实 QPU 的可用性。

    • 缓解:优先对接开源模拟器(QIR runner、Qiskit Aer),真实 QPU 作为长期目标。
  2. 后端实现的复杂性:QIR 和 QCIS 规范可能发生变化。

    • 缓解:抽象代码生成接口,隔离后端差异,便于后续适配。
  3. 性能不确定性:量子程序的性能特征与经典程序不同。

    • 缓解:提供性能剖析工具,让用户了解门级并行效果。

开放问题

  • [x] 拓扑约束:已通过 Qubit(Topology, N) 泛型常量参数实现编译期检查。
  • [ ] 动态量子寄存器List(Qubit) 在 QCIS 后端如何映射?可生成对应数量的物理比特,但需运行时分配机制。
  • [ ] 错误缓解:是否提供内置的错误缓解(如动态退耦)构造?可先作为库实现。
  • [ ] 与现有量子 SDK 互操作:能否导入 QASM 或 QIR 模块?未来可考虑 FFI。
  • [ ] 自动布局与路由:当虚拟 qubit 数超过物理 qubit 数时,如何自动映射?

参考文献


生命周期与归宿

┌─────────────┐
│   草案      │  ← 作者创建
└──────┬──────┘


┌─────────────┐
│  审核中     │  ← 社区讨论
└──────┬──────┘

       ├──────────────────┐
       ▼                  ▼
┌─────────────┐    ┌─────────────┐
│  已接受     │    │  已拒绝     │
└──────┬──────┘    └──────┬──────┘
       │                  │
       ▼                  ▼
┌─────────────┐    ┌─────────────┐
│   accepted/ │    │    rfc/     │
│ (正式设计)  │    │ (保留原位)  │
└─────────────┘    └─────────────┘

状态说明

状态位置说明
草案docs/design/rfc/draft/作者草稿,等待提交审核
审核中docs/design/rfc/开放社区讨论和反馈
已接受docs/design/accepted/成为正式设计文档,进入实现阶段
已拒绝docs/design/rfc/保留在 RFC 目录,更新状态