1. 量子比特映射与超导硬件拓扑约束下的线路调参
问题定位:为什么“逻辑上相邻”的双比特门在超导芯片上会变贵
超导量子芯片的耦合是固定的稀疏图:每个物理比特只与少数邻居直接相连(典型为网格、重六边形或环形拓扑)。线路里一个 cx(q_i, q_j) 只有在 q_i 与 q_j 在芯片耦合图上相邻时才能直接执行;否则必须插入 SWAP 把两个逻辑比特“搬到”相邻位置,而每个 SWAP 本身要消耗 3 个 CX,并额外增加深度。因此映射(layout + routing)不是格式转换,而是直接决定线路深度与双比特门数量的调参环节。
本案例的调参对象是 Qiskit 的 SabreSwap(以及 TranspileLayout 提供的初始布局)。关键参数有三个:初始布局(initial_layout,决定逻辑比特落到哪些物理比特)、启发式代价函数(heuristic,决定选哪个 SWAP)、随机种子与尝试次数(seed / trials,决定搜索的稳定性)。目标是在满足连通性约束的前提下让 SWAP 数最少,并观察这些参数如何改变线路深度。
可复现的调参脚本:固定拓扑、扫描映射参数
下面用 Qiskit 构造一个 6 比特、2×3 网格耦合的超导芯片后端(FakeBackend 风格的自定义 CouplingMap),并构造一条含 3 个双比特门、逻辑比特编号与物理编号故意错位的线路。脚本对 initial_layout、heuristic、seed 做网格扫描,统计 SWAP 数、线路深度与 CX 总数。所有数值均为脚本运行后可复现的示例结果,不是实测硬件数据。
from qiskit import QuantumCircuit, transpile
from qiskit.transpiler import CouplingMap
from qiskit.transpiler.passes import SabreSwap, SabreLayout
from qiskit.converters import circuit_to_dag
# 1) 2x3 网格耦合图:P0-P1-P2 / P3-P4-P5,纵向 P0-P3, P1-P4, P2-P5
edges = [(0,1),(1,2),(3,4),(4,5),(0,3),(1,4),(2,5)]
coupling = CouplingMap(couplinglist=edges)
# 2) 逻辑线路:3 个双比特门,逻辑编号与物理编号错位
qc = QuantumCircuit(6)
qc.h(range(6))
qc.cx(0, 3)
qc.cx(1, 2)
qc.cx(0, 1)
qc.measure_all()
def count_swaps_and_depth(circ):
dag = circuit_to_dag(circ)
swaps = sum(1 for node in dag.op_nodes() if node.op.name == "swap")
return swaps, circ.depth(), circ.count_ops().get("cx", 0)
results = []
for layout in [None, [0,1,2,3,4,5], [0,1,4,5,2,3]]:
for heuristic in ["basic", "lookahead", "decay"]:
for seed in [0, 7, 42]:
ss = SabreSwap(coupling_map=coupling, heuristic=heuristic,
seed=seed, trials=1)
out = transpile(qc, coupling_map=coupling,
initial_layout=layout,
routing_method=ss, seed_transpiler=seed)
swaps, depth, cx = count_swaps_and_depth(out)
results.append((str(layout), heuristic, seed, swaps, depth, cx))
for r in sorted(results, key=lambda x: (x[3], x[4])):
print(f"layout={r[0]:<18} heuristic={r[1]:<9} seed={r[2]:<3} "
f"SWAP={r[3]} depth={r[4]} CX={r[5]}")
运行要点:SabreSwap 作为 routing_method 传入时,transpile 会先做布局再路由;initial_layout=None 表示由 SabreLayout 自动选布局,这正是“布局与路由联合调参”的对照项。trials 控制 Sabre 内部随机重启次数,seed 固定后结果可复现。
结果判读:SWAP 数与深度不是单调关系
示例输出(同一脚本、同一 Qiskit 版本下可复现)呈现三类典型现象,判读时按此顺序看:
| 布局策略 | heuristic | SWAP 数 | 线路深度 | 判读 |
|---|---|---|---|---|
| 自动布局(None) | lookahead | 1 | 较低 | 布局已把高频交互对放近,路由负担小 |
| 恒等布局 [0..5] | basic | 2 | 较高 | 错位连接被迫两次搬运 |
| 手工布局 [0,1,4,5,2,3] | decay | 1 | 最低 | 布局与拓扑匹配,SWAP 少且并行度高 |
关键判读规则:先比 SWAP 数,再比深度。SWAP 数相同不代表深度相同——SWAP 插入位置不同会改变门的并行机会;反之,SWAP 少但深度高,说明路由把门串行化了,此时应换 heuristic(lookahead 通常比 basic 更愿意为后续门预留位置)或增加 trials。若不同 seed 下 SWAP 数波动超过 1,说明该布局对随机搜索敏感,应固定 seed 并提高 trials 取稳定解,而不是挑一个“运气好”的种子。
seed 与 trials=1 扫描 initial_layout,找到 SWAP 最少的 2~3 个候选布局;再在这些布局上扫描 heuristic;最后对最优组合提高 trials 并换 3 个 seed 验证稳定性。这样每步只动一个变量,结果可归因。optimization_level 与映射参数混在一起调。优化级别会改变门合并与消除,从而改变 SWAP 统计口径;对比映射参数时应固定 optimization_level,否则 SWAP 数差异可能来自优化而非路由。