QCloud Fidelity Layout 完整工作流
本教程展示 pyqpanda3 0.4.0 的完整硬件感知路径:
- 获取 QCloud 实时芯片元数据。
- 将芯片元数据转换为
ChipBackend。 - 使用同一个
ChipBackend完成保真度感知布局和转译。 - 根据芯片元数据中的时序导出带时间戳的指令流。
- 在本地预览时序图。
- 使用
run_instruction()提交同一份指令流。
不要在源码或文档中硬编码 API key。下面示例统一从环境变量 QPANDA_QCLOUD_API_KEY 读取。
为什么必须从 chip_info() 开始
run_instruction() 接收 instruction JSON,所以手写一段短指令看起来很方便。手写指令适合排查格式问题,但不是推荐的真实硬件流程。
面向 QCloud 后端时,应从 chip_info() 构建指令流:
chip_info().get_chip_backend()提供物理拓扑和原生门集。single_gate_fidelity、readout_fidelity、double_gate_fidelity参与fidelity_layout()的布局评分。single_gate_timing、double_gate_timing、echo_gate_timing用于生成带时间戳的指令调度。- CZ 补偿角也保存在同一个后端对象中。
核心原则很简单:用于布局的后端对象,也应该继续用于指令导出和时序绘图。
一步完成保真度布局、调度和提交
这条路径通过 layout_method="fidelity" 让 Transpiler 在内部调用 fidelity layout。
import os
from pyqpanda3.core import CZ, H, QProg, measure
from pyqpanda3.qcloud import QCloudOptions, QCloudService
from pyqpanda3.transpilation import Transpiler, decompose
from pyqpanda3.visualization import draw_time_scheduling
def build_program():
prog = QProg()
prog << H(0)
prog << H(1)
prog << CZ(0, 1)
prog << CZ(1, 2)
prog << measure(0, 0)
prog << measure(1, 1)
prog << measure(2, 2)
return prog
service = QCloudService(os.environ["QPANDA_QCLOUD_API_KEY"])
qcloud_backend = service.backend(os.environ.get("QPANDA_QCLOUD_BACKEND", "WK_C180"))
chip_info = qcloud_backend.chip_info()
chip_backend = chip_info.get_chip_backend()
print("backend:", qcloud_backend.name())
print("timing:", chip_backend.single_gate_timing, chip_backend.double_gate_timing)
prog = build_program()
decomposed = decompose(prog, ["U3", "CZ"])
transpiled = Transpiler().transpile(decomposed, chip_backend, {}, 2, "fidelity")
# is_scheduling=True 会让 to_instruction 使用 chip_backend 中的单双门时序,
# 而不是依赖文档里手写的时间戳。
instruction = transpiled.to_instruction(
chip_backend,
offset=1,
is_scheduling=True,
compensate_pulse=False,
)
figures = draw_time_scheduling(instruction, backend=chip_backend, output="plotly")
print("schedule figure:", type(figures).__name__)
options = QCloudOptions()
options.set_mapping(False)
options.set_optimization(False)
options.set_amend(False)
job = qcloud_backend.run_instruction([instruction], 1000, options)
result = job.result()
print(result.get_counts_list())示例输出形态:
backend: WK_C180
timing: 40 80
schedule figure: Figure
[{'000': 263, '001': 229, '010': 241, '011': 227, '100': 6, '101': 4, '110': 15, '111': 15}]时序和计数会随后端与标定快照变化。这里真正重要的是:指令时间戳来自 QCloud 返回的 ChipBackend,不是文档里的固定常量。
提交前检查初始布局
当你希望观察、保存或调整初始映射时,可以手动调用 fidelity_layout()。但后续 transpile()、to_instruction() 和 draw_time_scheduling() 仍应继续使用同一个 chip_backend。
from pyqpanda3.transpilation import Transpiler, decompose, fidelity_layout
decomposed = decompose(prog, ["U3", "CZ"])
init_mapping = fidelity_layout(
decomposed,
chip_backend.chip_topology_edges,
chip_backend.single_gate_fidelity,
chip_backend.readout_fidelity,
chip_backend.double_gate_fidelity,
)
print("initial mapping:", init_mapping)
transpiled = Transpiler().transpile(
decomposed,
chip_backend,
init_mapping,
2,
)
instruction = transpiled.to_instruction(
chip_backend,
offset=1,
is_scheduling=True,
compensate_pulse=False,
)
figures = draw_time_scheduling(instruction, backend=chip_backend, output="plotly")
job = qcloud_backend.run_instruction([instruction], 1000, options)
print(type(figures).__name__)
print(job.result().get_counts_list())示例输出形态:
initial mapping: {1: 106, 0: 96, 2: 115}
Figure
[{'000': 229, '001': 203, '010': 210, '011': 189, '100': 39, '101': 50, '110': 45, '111': 35}]init_mapping 是 Python 字典,键是线路中的逻辑比特,值是芯片上的物理比特。
Fidelity Layout 的实现思路
构建虚拟交互图
布局过程会扫描分解后的程序。单比特门增加对应逻辑比特的重要性;测量让读出保真度参与评分;双比特门形成带权虚拟交互边,交互次数越多,权重越高。
搜索连通物理块
芯片拓扑来自 chip_backend.chip_topology_edges。算法不会在整张芯片上盲目枚举所有排列,而是先根据线路使用的逻辑比特数量,在物理拓扑中寻找连通候选块。
为候选映射打分
每个候选映射会根据以下因素计算综合错误代价:
- 单比特门错误率:逻辑比特上的单比特操作越多,对应物理比特的单门保真度越重要。
- 读出错误率:被测量的逻辑比特优先使用读出效果更好的物理比特。
- 双比特门错误率:频繁交互的逻辑边优先放到高保真的物理 CZ 边上。
- 拓扑距离惩罚:如果频繁交互的逻辑比特没有映射到相邻物理比特,会按距离增加惩罚。
cost =
one_qubit_count * single_gate_error(physical_qubit)
+ measure_count * readout_error(physical_qubit)
+ two_qubit_count * pair_cost(logical_edge, physical_qubits)其中 pair_cost 取决于两个逻辑比特映射到的物理比特是否相邻:
- 如果两个物理比特相邻,使用对应物理边的双门错误率。
- 如果两个物理比特不相邻,则额外叠加非局域交互惩罚、距离惩罚和平均双门错误率。
缺失的保真度数据会使用同类已提供数据的平均错误率;如果该类数据完全为空,平均错误率为 0.0。
把初始映射交给 Routing
Fidelity layout 只决定初始映射,并不替代完整 routing。若初始映射已经把主要双比特交互放在相邻且高保真的物理边上,routing 阶段通常需要更少 SWAP;如果线路交互图和芯片拓扑差异较大,仍然可能需要 SWAP。
参数调优
init_mapping = fidelity_layout(
decomposed,
chip_backend.chip_topology_edges,
chip_backend.single_gate_fidelity,
chip_backend.readout_fidelity,
chip_backend.double_gate_fidelity,
max_candidate_blocks=32,
max_mappings_per_block=256,
distance_penalty_weight=1.0,
)| 参数 | 说明 |
|---|---|
max_candidate_blocks | 候选物理块数量。增大后搜索更充分,但耗时更高。 |
max_mappings_per_block | 每个候选块中尝试的映射数量。增大后可能找到更好映射,但组合复杂度更高。 |
distance_penalty_weight | 拓扑距离惩罚权重。较大时更偏向减少 SWAP,较小时更偏向保真度。 |
运行完整示例
源码包中包含可运行示例:
$env:QPANDA_QCLOUD_API_KEY="your_api_key"
$env:QPANDA_QCLOUD_BACKEND="WK_C180"
python samples/python/fidelity_layout_qcloud.py如果不设置 QPANDA_QCLOUD_BACKEND,示例默认使用 WK_C180。
进阶:0.4.1 的保真度驱动近似与指标
本教程聚焦 0.4.0 的 fidelity_layout() 位置参数工作流。0.4.1 在此基础上进一步让保真度数据驱动转译决策:
- 用
TranspilationOptions把布局/路由/优化策略集中到一个对象,并通过TranspilationResult.metrics回收双比特门数量、深度、对数期望保真度等指标。 optimization_level >= 1时由approximation_degree决定 ORACLE KAK 是精确还是近似合成(1.0精确,None使用目标双比特门错误率)。ChipBackend.gate_fidelity(逐指令保真度)可由云端元数据自动填充,transpilation_metrics()会优先匹配它。RoutingMethod.LIGHT_SABRE启用分层前瞻路由,通常能减少双比特门插入。
详见 转译教程 §4.5 和 转译选项与指标 API。