引言
量子算法写出来是一张「电路」,但真实量子机只认识自家门集(如单比特旋转 + CNOT)——把抽象电路翻译成硬件可执行电路并优化,就是量子电路编译。本文讲透编译原理与实战:先给电路的核心指标(深度/宽度/保真度),再讲门集分解(任意旋转门 → Clifford+T 容错门集)、编译优化 pass(门的对易合并、重排、消除冗余),接着用 Qiskit transpile 走完整编译管线,最后谈容错电路的线路层设计(layout/routing 与 SWAP 代价)。
前置:/quantum-qubit-gates-basics/(量子门)、/quantum-algorithms-advanced/(QFT/QPE 电路)、/quantum-qiskit-programming/(Qiskit 基础)。
目录
- 1. 为什么需要电路编译:抽象电路到硬件电路
- 2. 电路的核心指标:深度、宽度与保真度
- 3. 门集分解:任意旋转到 Clifford+T
- 4. 编译优化 pass:对易合并、重排与消冗
- 5. Qiskit transpile:一键编译管线
- 6. 线路层:Layout 与 Routing(SWAP 代价)
- 7. 动态电路:测量与反馈(经典控制)
- 8. 编译代价:量子门的错误累积
- 9. 实战:把 QFT 电路编译到真实后端的噪声与深度对比
- 10. 速查表
- 延伸阅读
1. 为什么需要电路编译:抽象电路到硬件电路
算法电路 vs 硬件电路:
算法层:H 门、CNOT、旋转门 Rz(θ)…(通用、易读)
硬件层:每家芯片只支持自家门集(如单比特 + CNOT,且连接有约束)
编译 = 把算法电路翻译成硬件能执行、尽量高效的电路
编译做什么:
1. 门集映射:Rz(θ) → 硬件门(如 Rz + Sqrt(X))
2. 逻辑到物理:算法比特 → 芯片实际比特(Layout)
3. 路由:两比特门必须在物理相连的比特上(Routing)
4. 优化:合并门、消除冗余、减小深度
心智:电路编译 ≈ 经典编译器的「指令选择 + 寄存器分配」——同一个量子程序,编译好坏直接决定能否在噪声机器上跑通。
2. 电路的核心指标:深度、宽度与保真度
三个指标决定电路「贵不贵」:
| 指标 | 含义 | 为什么重要 |
|---|---|---|
| 深度(depth) | 最长串行门序列长度 | 决定运行时间 |
| 宽度(width) | 同时使用的比特数 | 决定量子比特需求 |
| 门数(count) | 总门数量 | 决定错误累积 |
| 保真度(fidelity) | 输出与理想输出的接近度 | 决定结果可信度 |
关键关系:
保真度 ≈ (1 - 单门错误率)^门数
例子:1000 个门,单门错误率 1% → 保真度 ≈ (0.99)^1000 ≈ 4e-5(几乎全错)
→ 深度/门数每减半,保真度指数级提升
# Qiskit 查看电路指标
print(circ.depth()) # 深度
print(circ.width()) # 宽度(比特数)
print(circ.count_ops()) # 各门计数
记忆:电路贵不贵看深度和门数——门数决定错误累积,深度决定运行时间,编译优化的目标就是同时压低两者。
3. 门集分解:任意旋转到 Clifford+T
容错量子计算的门集是 Clifford + T:
Clifford 门:H、S、CNOT(可容错实现、易纠错)
T 门:T = Rz(π/4)(非 Clifford,实现更贵)
任意单比特旋转 → 用 Clifford + T 近似(Solovay-Kitaev 定理)
为什么需要 T 门:
只有 Clifford 门 → 电路可用经典高效模拟(Gottesman-Knill 定理)
T 门引入「非经典」→ 才有量子优势
代价:T 门需要 magic state 蒸馏 → 非常贵
分解示意:
Rz(θ) → 用 H、S、T 序列近似(误差 ε → 门数 ~ log²(1/ε))
# Qiskit 自动分解:transpile 到 basis gates
from qiskit.transpiler.passes import BasisTranslator
from qiskit.circuit.library import TGate, HGate, SGate, CXGate
# basis_gates 指定目标门集,transpile 自动分解
optimized = transpile(circ, basis_gates=['u', 'cx'])
| 门集 | 特点 | 应用 |
|---|---|---|
| 任意旋转 + CNOT | 灵活、短 | NISQ 噪声机 |
| Clifford + T | 可容错 | 容错量子计算 |
| 芯片原生门 | 最快 | 真机执行 |
记忆:容错必用 Clifford+T、NISQ 用任意旋转门——T 门贵但有量子优势,分解用 Qiskit 自动完成。
4. 编译优化 pass:对易合并、重排与消冗
编译优化 = 一系列 pass 对电路做等价变换:
常见 pass:
1. 对易合并:两个可交换门合并(Rz(a)·Rz(b) = Rz(a+b))
2. 门消除:X·X = I 对消
3. 重排:调整门序以利于合并
4. 简化:把旋转门合成一个
对易合并示例:
from qiskit import QuantumCircuit
# 两个连续 Rz 可以合并
qc = QuantumCircuit(1)
qc.rz(0.3, 0)
qc.rz(0.5, 0) # = rz(0.8)
优化流水线(Qiskit):
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import (
Optimize1qGatesDecomposition,
CommutativeCancellation,
RemoveDiagonalGatesBeforeMeasure,
)
pm = PassManager([
Optimize1qGatesDecomposition(), # 合并单比特门
CommutativeCancellation(), # 对易消除
RemoveDiagonalGatesBeforeMeasure(), # 测量前消对角门
])
optimized = pm.run(circ)
记忆:优化 pass 靠「门的代数性质」省门——合并 Rz、对消 X²、删测量前对角门,全是等价变换。
5. Qiskit transpile:一键编译管线
transpile 一键完成「门集映射 + 布局 + 路由 + 优化」:
from qiskit import QuantumCircuit, transpile
from qiskit_ibm_runtime import QiskitRuntimeService
qc = QuantumCircuit(3) # 你的算法电路
qc.h(0); qc.cx(0, 1); qc.cx(1, 2)
qc.measure_all()
# 编译到某个后端
service = QiskitRuntimeService()
backend = service.backend("ibm_sherbrooke")
compiled = transpile(qc, backend, optimization_level=3)
# optimization_level: 0 快 / 1 / 2 / 3 最优化
print(compiled.depth()) # 编译后深度
print(compiled.count_ops()) # 编译后门集(已是硬件门)
optimization_level 权衡:
| 级别 | 优化强度 | 编译耗时 | 适用 |
|---|---|---|---|
| 0 | 最弱 | 快 | 调试 |
| 1 | 基础 | 中 | 默认 |
| 2 | 较强 | 中 | 常规 |
| 3 | 最强 | 慢 | 保真度关键 |
记忆:transpile 是编译总开关——
optimization_level=3压深度、basis_gates定门集、传 backend 自动做 layout/routing。
6. 线路层:Layout 与 Routing(SWAP 代价)
真实芯片比特是「网格连接」的——不是任意两比特都能 CNOT:
Layout:把算法比特映射到芯片比特(哪个逻辑比特放哪个物理比特)
Routing:物理不相连的两比特要做 CNOT → 插入 SWAP 搬数据
SWAP 的代价:
SWAP = 3 个 CNOT → 很贵!
Routing 好坏 = 插入的 SWAP 数量
好的 Layout 能大幅减少 SWAP
# Qiskit 里查看耦合图与路由结果
print(backend.coupling_map) # 芯片连接图
compiled = transpile(qc, backend, routing_method='sabre')
# routing_method: sabre / basic / lookahead / stochastic
| 路由方法 | 特点 |
|---|---|
| basic | 简单、质量一般 |
| lookahead | 较优、慢 |
| sabre | 综合最优(默认推荐) |
| stochastic | 随机搜索 |
记忆:Layout 定「放哪」、Routing 定「怎么连」——SWAP 一个顶 3 个 CNOT,路由方法好坏差好几倍深度。
7. 动态电路:测量与反馈(经典控制)
动态电路 = 中间测量 + 经典反馈——让量子程序「见机行事」:
经典流程:测量 → 结果决定后续门 → 继续跑
例子:重复纠错测量、变分算法的参数更新
Qiskit 动态电路:
from qiskit import QuantumCircuit, ClassicalRegister
qc = QuantumCircuit(2, 1)
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0) # 中间测量
# 经典反馈:根据测量结果控制后续门
qc.x(1).c_if(0, 1) # 若比特0=1,则对比特1施加X
记忆:动态电路把「测量结果」变回「控制信号」——
.c_if实现经典反馈,是纠错与自适应算法的基石。
8. 编译代价:量子门的错误累积
编译优化为什么是「保命」——门数直接决定错误率:
总错误率 ≈ 1 - (1-ε)^N ≈ N·ε(小 ε 时)
N = 门数,ε = 单门错误率
同样 1000 个门 vs 500 个门 → 错误率差 2 倍
编译对保真度的影响:
from qiskit import transpile
# 对比不同优化级别的门数与深度
for level in range(4):
c = transpile(qc, backend, optimization_level=level)
print(f"level {level}: depth={c.depth()}, gates={c.count_ops()}")
降低编译代价的思路:
1. 用 hardware-efficient 电路(直接贴芯片门集)
2. 减少 T 门(T 门最贵)
3. 好的 Layout/Routing(少 SWAP)
4. 动态解耦(抵消噪声)
记忆:每省一个门 = 省一份错误——编译优化就是在「等价变换」里把门数压到最少,深度就是保真度。
9. 实战:把 QFT 电路编译到真实后端
完整实战:量子傅里叶变换(QFT)编译对比:
from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import QFT
from qiskit_ibm_runtime import QiskitRuntimeService
# 1. 构造 5 比特 QFT
qc = QFT(5).decompose()
qc.measure_all()
print("原始深度:", qc.depth())
# 2. 获取真实后端
service = QiskitRuntimeService()
backend = service.backend("ibm_sherbrooke")
# 3. 三种编译策略对比
results = {}
for level in [0, 2, 3]:
c = transpile(qc, backend, optimization_level=level)
results[level] = (c.depth(), c.count_ops())
print(f"level {level}: depth={c.depth()}, ops={c.count_ops()}")
# 4. 跑真机(受噪声预算限制)
# sampler = SamplerV2(mode=backend)
# job = sampler.run([compiled], shots=4096)
# print(job.result())
预期结论:
level 0 → depth 上百
level 3 → depth 明显更小、门更少
→ 保真度可能差几倍(门数减半=错误减半)
记忆:编译实战三步——构造电路、transpile 对比、上机跑——先看 depth/门数再决定花多少 shots。
10. 速查表
| 需求 | 做法 |
|---|---|
| 编译到硬件 | transpile(circ, backend, optimization_level=3) |
| 指定门集 | basis_gates=['u', 'cx'] |
| 深度/门数 | circ.depth() / circ.count_ops() |
| 优化 pass | PassManager + CommutativeCancellation |
| 路由 | routing_method='sabre' |
| 动态电路 | measure + .c_if |
| 看耦合图 | backend.coupling_map |
| T 门优化 | 减少 T 门(最贵) |
| 保真度 | 门数每减半、错误减半 |
一句话记忆:量子电路编译 = 把算法电路翻译成芯片门集并优化——深度与门数决定保真度(错误 ~ 门数);门集分解走 Clifford+T(T 门最贵)、优化 pass 靠对易合并消冗、Layout 定放哪、Routing 管连线(SWAP 顶 3 个 CNOT);Qiskit transpile 一键完成、optimization_level 3 最狠——编译好坏就是量子程序的生死。
延伸阅读
- /quantum-qubit-gates-basics/ — 量子门基础
- /quantum-algorithms-advanced/ — QFT/QPE 电路
- /quantum-qiskit-programming/ — Qiskit 编程实战
- /quantum-error-mitigation/ — 编译后仍有的噪声如何缓解
- /quantum-error-correction/ — 容错与 T 门
- [[cs-fundamentals]] — 编译原理类比
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。