2. 量子编译器基础与验证对象
量子编译器验证的第一步,不是急着写测试用例,而是把“到底要验证什么”说清楚。一个量子编译器的输入是量子程序,输出可能是另一种量子电路、脉冲波形,甚至是校准后的控制指令。如果验证对象没有界定清楚,测试就会在错误的抽象层上比较,导致“看起来通过、实际错误”的假阴性。本节围绕五个核心概念展开:量子电路IR、脉冲级表示、编译pass分类、验证对象界定、正确性属性定义。
量子电路IR:编译器的中间语言
量子电路IR(Intermediate Representation)是编译器内部表示量子程序的数据结构。它通常包含量子寄存器、经典寄存器、门指令、测量指令、屏障和条件分支。以OpenQASM 2.0为例,一段简单的Bell态电路可以表示为:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q -> c;
在编译器内部,这段代码会被解析成IR节点。IR的关键属性包括:门集合是否支持参数化、是否保留经典控制流、是否记录量子比特的物理映射。验证时,IR层比较通常关注门序列的等价性,而不是文本是否相同。例如,h q[0]; cx q[0],q[1];与cx q[0],q[1]; h q[0];在文本上不同,但作用在|00⟩上结果不同,因此IR比较必须基于语义而非语法。
脉冲级表示:从门到物理控制
当编译器面向超导量子处理器时,逻辑门最终要展开为微波脉冲或磁通脉冲。脉冲级表示描述的是:在哪个物理量子比特上、施加什么形状的包络、持续多长时间、相位和幅度是多少。例如,一个X门可能对应一个DRAG脉冲,参数包括幅度amp、持续时间dur、相位phase和DRAG系数beta。验证脉冲级表示时,不能简单比较波形数组,因为不同脉冲可能实现同一酉矩阵。更合理的做法是:将脉冲作用于量子态,通过仿真或层析得到等效酉矩阵,再与目标门比较。
编译pass分类:验证的切入口
量子编译器的pass通常分为以下几类:
- 解析与规范化pass:将输入QASM解析为IR,展开自定义门,统一门集合。
- 逻辑优化pass:消去相邻逆门、合并旋转门、简化受控门。
- 映射与路由pass:将逻辑量子比特映射到物理量子比特,插入SWAP门满足连通性约束。
- 调度pass:安排门执行顺序,处理冲突和时序约束。
- 脉冲生成pass:将物理门转换为脉冲波形。
每一类pass都有不同的正确性属性。逻辑优化pass应保持电路酉等价;映射pass应保持逻辑语义不变,但允许物理量子比特重排;调度pass不应改变门之间的依赖关系;脉冲生成pass应保证脉冲等效于目标门。
验证对象界定:三个层次
验证对象可以按抽象层次划分为三层:IR层、门层和脉冲层。IR层验证关注电路结构变换是否正确;门层验证关注映射后电路是否与原始电路在逻辑上等价;脉冲层验证关注物理控制是否实现目标门。界定验证对象时,需要明确:输入是什么、输出是什么、允许的差异是什么。例如,映射pass允许量子比特编号改变,但不允许门之间的逻辑关系改变。如果验证时直接比较量子比特编号,就会误报失败。
正确性属性定义:从“等价”到“可观测”
正确性属性是验证的判据。常见的属性包括:
- 酉等价:两个电路在忽略全局相位后实现相同酉矩阵。
- 状态等价:对一组测试态,两个电路输出相同量子态。
- 测量等价:对一组测试态和测量基,两个电路输出相同概率分布。
- 保真度阈值:在含噪声条件下,输出态与理想态的保真度不低于给定阈值。
定义正确性属性时,必须说明参照系和相位约定。例如,酉等价通常忽略全局相位,但保留相对相位;测量等价则只关心概率分布,不关心相位。如果验证目标是比较两个编译器版本,建议先定义一组基准电路和测试态,再选择合适属性。
实际验证流程示例
假设我们要验证一个映射pass是否正确。输入是一个3量子比特GHZ态电路,逻辑量子比特q0、q1、q2,物理量子比特拓扑为线性连接0-1-2。映射pass将q0映射到物理比特2,q1映射到物理比特1,q2映射到物理比特0。验证步骤如下:
- 将原始电路和映射后电路分别转换为酉矩阵(忽略全局相位)。
- 检查两个酉矩阵是否在容差范围内相等。若相等,说明映射pass保持了逻辑语义。
- 若不等,检查是否因为SWAP门插入导致量子比特顺序变化。此时需要将映射后电路的输出量子比特按映射关系重排,再比较。
- 如果仍然不等,则定位到具体门,检查映射pass是否错误地改变了门的作用对象。
这个流程的关键是:先定义正确性属性(酉等价),再定义允许的差异(量子比特重排),最后选择比较方法。如果跳过第二步,直接比较矩阵,就会把正确的映射误判为错误。
验证对象界定检查表
在实际项目中,可以用以下检查表快速界定验证对象:
| 检查项 | 说明 | 示例 |
|---|---|---|
| 抽象层次 | IR层、门层还是脉冲层? | 映射pass验证在门层 |
| 输入输出 | 输入电路和输出电路分别是什么? | 输入逻辑电路,输出物理电路 |
| 允许差异 | 哪些变化是合法的? | 量子比特编号可变,门序不可变 |
| 正确性属性 | 用酉等价、状态等价还是测量等价? | 映射pass用酉等价 |
| 容差 | 数值比较的误差范围是多少? | 矩阵元素误差小于1e-6 |
正确性属性定义不是一次性的,而是随着编译器版本迭代不断细化的。建议在项目初期就建立属性清单,并在每次回归测试中复用。这样,当编译器新增一个pass时,可以快速判断它属于哪一类验证对象,应该使用哪种正确性属性,从而避免验证盲区。