平台约定 {#guide-platform-conventions}¶
本文档详细说明各量子云平台的输入/输出约定、运行模式、门支持范围和配置方式。适用于完成基础使用教程后需要针对特定平台调优的场景。
1. 输入格式约定 {#platform-input-formats}¶
各平台接受的电路格式不同,submit_task() 内部会根据 backend 参数自动选择对应的 Circuit Adapter 进行转换,但用户也可以手动调用各平台的 adapter。
平台 |
输入类型 |
自动转换 |
手动转换 |
|---|---|---|---|
OriginQ |
|
|
|
IBM |
|
|
|
Dummy |
|
|
无需转换,直接送入本地模拟器 |
自动转换路径:Circuit → CircuitAdapter → Native Circuit → TaskAdapter → 云端
2. 输出格式约定 {#platform-output-formats}¶
所有平台的 query() 返回格式统一为 {"status": "...", "result": ...}。注意:各平台的 result 内层结构不同。
2.1 OriginQ¶
{
"status": "success",
"result": {"00": 512, "11": 488}
}
扁平 {bitstring: shots} 字典。
2.2 IBM / Qiskit¶
{
"status": "success",
"result": {"00": 512, "11": 488},
"time": "Fri 01 May 2026, 10:00AM",
"backend_name": "ibm_fez"
}
单电路提交返回扁平 {bitstring: shots} 字典。query_batch() 返回 {"result": [flat_dict, ...]}。
{
"status": "success",
"result": {"00": 512, "11": 488}
}
与 OriginQ 相同,扁平 {bitstring: shots} 字典。
2.5 统一结果格式¶
所有平台的 wait_for_result() / query_task() 均返回统一的扁平 counts 字典:
from uniqc import wait_for_result
# 所有平台统一返回 {"00": 512, "1111": 488}
result = wait_for_result(task_id)
# result == {"00": 512, "1111": 488} # 扁平 dict,无需后处理
result = wait_for_result(another_task_id)
# result == {"00": 512, "1111": 488} # 同样格式
wait_for_result() 的实际返回值是 result["result"],各 adapter 已统一将其规范化为 {bitstring: shots} 扁平字典。
2.6 Bit endianness 与测量比特映射 {#platform-bit-endianness}¶
uniqc 在所有平台都把测量结果归一化到同一个 cbit 框架。这条约定永久不变,
由 uniqc/test/test_endianness_convention.py 在所有 adapter(含 dummy / 真机
normalizer mock)上回归保护:
bitstring 的索引规则:返回字典的 key 是定长二进制字符串。其 最右侧字符(索引
-1)对应 classical bitc[0];索引-2对应c[1];依此类推。MSB 在最左、LSB 在最右——与bin(int)[2:].zfill(n)的视觉顺序一致。classical bit 的来源:
c[i]记录的是 第 i 次 调用circuit.measure(q)的结果,不一定 是q[i]。也就是说,cbit 索引由测量调用顺序决定,不是由 qubit 索引决定:c = Circuit() c.h(0); c.cnot(0, 1) c.measure(1) # -> c[0] (bitstring 的最右字符) c.measure(0) # -> c[1] (bitstring 的右数第二字符) # bitstring "10" 表示 c[1]=1, c[0]=0
跨平台一致性:OriginQ、IBM/Qiskit、Quark 在底层各有差异(IBM 的 BitArray 以
c[0]为整数最低位、Quark 取决于固件),但uniqc的 normalizer 已经统一 改写为上述 cbit 框架。任何依赖原始平台 顺序的下游代码请改用 normalizer 输出。永久自检脚本:在任何后端(云 / dummy / 本地仿真)跑下面这段电路,dominant outcome 都 必须 是
'01':from uniqc.circuit_builder import Circuit from uniqc.backend_adapter.task_manager import submit_batch, query_task c = Circuit(2) c.x(0) c.measure(0) # -> c[0] c.measure(1) # -> c[1] uid = submit_batch([c], backend='dummy:local:virtual-line-2', shots=1024) print(query_task(uid).result) # -> {'01': 1024}
x(0)把q[0]翻成|1⟩,第一次measure(0)写到c[0]=1;按右起 LSB 约定 bitstring 必为'01'。任何后端给出'10'即视为 endianness 退化 bug,应优先 修复 adapter / normalizer 而非业务代码。
如果你需要按 qubit 索引读取,请保证 circuit.measure(q[i]) 的调用顺序与你预期的 c[i] 一致。
2.7 提交前格式校验 {#platform-precheck}¶
从 0.0.12 起,submit_task() / submit_batch() 在提交到任何云端之前,会执行一次 离线校验(uniqc.compile.compatibility_report):
Submit language:根据后端确定提交语言 —
originq→ OriginIR;ibm、quark→ QASM 2.0。Basis gate set:根据后端确定基础门集合 —
originq、quark默认按cz + sx + rz校验;ibm按BackendInfo.extra["basis_gates"]校验。Topology:双比特门必须落在 backend 拓扑的边上。
CZ、ISWAP、SWAP、XX、YY、ZZ、XY视为无向;CNOT/CX、ECR视为有向。Qubit count:电路中用到的 qubit 索引必须
< backend.num_qubits。Topology TTL:后端拓扑使用
~/.uniqc/cache/backends.sqlite的缓存,TTL 24h;过期但仍可用的拓扑会以 warning 方式提示。
校验通过 时,submit_task() 会在 metadata 中附加:
{
"validation_passed": True,
"gate_depth": 13,
"used_gates": ["CZ", "RZ", "SX"],
"submit_language": "originir",
"validation_warnings": [...], # 仅在有 warning 时出现
}
校验失败且未启用自动编译时会抛出 UnsupportedGateError。可以这样跳过校验或自动编译:
from uniqc import submit_task, compile_for_backend, compatibility_report, is_compatible
# 直接获取报告(不会发请求)
report = compatibility_report(circuit, backend_info)
print(report)
# 简单 boolean
ok = is_compatible(circuit, backend_info)
# 让 uniqc 自动按 backend 政策编译后再提交
task_id = submit_task(circuit, backend="originq:WK_C180")
# 完全跳过校验(仅在你确信前端已经做过等价校验时使用)
task_id = submit_task(circuit, backend="originq:WK_C180", skip_validation=True)
或者编程式预先编译:
compiled = compile_for_backend(circuit, backend_info) # → cz/sx/rz
2.8 Gate depth 计算约定 {#platform-gate-depth}¶
uniqc.compute_gate_depth(circuit, *, virtual_z=True) 返回 并行感知 + virtual-Z 感知 的 depth:
每个 gate 占据其所有 qubit 的 earliest free layer;同一层中无冲突的 gate 被并行计入同一深度。这与“gate 数”不同——很多旧实验代码错误地把它们等同。
virtual_z=True(默认)时,Z、RZ、S、T、U1视为 frame change,深度为 0;它们仍占据该 qubit 的 cursor 以避免与非交换的相邻门折叠。BARRIER同步它涉及的所有 qubit cursor,但不增加 depth 数。MEASURE不计入 gate depth。CZ不是 virtual-Z(它是双比特门)。
from uniqc import Circuit, compute_gate_depth
c = Circuit()
c.h(0); c.h(1); c.cnot(0, 1); c.rz(0, 0.5); c.h(0)
compute_gate_depth(c) # → 3 (H 并行;CNOT;RZ 虚;H 与 CNOT 不并行 → 3)
compute_gate_depth(c, virtual_z=False) # → 4
3. 运行模式约定 {#platform-run-modes}¶
3.1 提交行为对比¶
平台 |
|
|
|
|---|---|---|---|
OriginQ |
立即返回(异步) |
立即返回(异步) |
✅ 支持 |
IBM / Qiskit |
同步(提交即阻塞) |
同步(批量在一个 Job 内执行) |
✅ 支持 |
Dummy |
同步(本地模拟器) |
同步 |
❌ 不需要 |
3.2 轮询等待模式¶
# OriginQ: 使用 query_sync() 轮询
results = adapter.query_sync(task_id, interval=2.0, timeout=60.0)
# IBM / Qiskit: submit() 本身就是同步的,不需要额外等待
4. 门支持约定 {#platform-gate-support}¶
4.1 OriginQ¶
使用 pyqpanda3 的 convert_originir_string_to_qprog(),支持完整的 OriginIR 规范:
H, X, Y, Z, S, SX, T, RX, RY, RZ, RPhi, RPhi90, RPhi180,
U1, U2, U3, U4, CNOT, CZ, SWAP, ISWAP, TOFFOLI, CSWAP,
XX, YY, ZZ, XY, PHASE2Q, UU15, I, BARRIER, MEASURE
以及 CONTROL/DAGGER 块。
OriginQ 模拟器后端¶
OriginQ 云平台提供三种模拟器后端,可通过 backend_name 参数使用:
|
说明 |
用途 |
|---|---|---|
|
全振幅模拟 |
多比特精确模拟 |
|
部分振幅 |
大规模线路的部分比特模拟 |
|
单振幅 |
特定基态振幅计算 |
from uniqc import submit_task
# 使用 OriginQ 模拟器后端
task_id = submit_task(circuit, backend="originq:full_amplitude", shots=1000)
result = wait_for_result(task_id)
注意:模拟器后端在
uniqc backend list --platform originq中以Type = sim标识,与 QPU 硬件后端(Type = hw)分开列出。模拟器后端使用QCloudSimulatorAPI 而非 QPU 的QCloudOptions。
4.2 IBM / Qiskit¶
QiskitAdapter.translate_circuit() 走 OriginIR → QASM → qiskit.QuantumCircuit 路线,借助 Qiskit 的转译器支持所有标准 OpenQASM 2.0 门。
5. 芯片/后端命名约定 {#platform-chip-names}¶
OriginQ¶
WK_C180 # 180 比特硬件
PQPUMESH8 # 8 比特硬件
full_amplitude # 全振幅模拟器
可用 OriginQAdapter().list_backends() 查询所有可用后端。
IBM¶
ibm_qasm_simulator # QASM 模拟器(推荐测试用)
ibm_brisbane # 真实硬件 Brisbane
ibm_sherbrooke # 真实硬件 Sherbrooke
真实硬件名称因设备代数而异,使用 QiskitAdapter()._provider.backends() 查询可用后端。
6. 配置约定 {#platform-configuration}¶
6.1 YAML 配置文件(~/.uniqc/config.yaml)¶
uniqc config set originq.token "your-originq-key"
uniqc config set ibm.token "your-ibm-token"
active_profile: default
default:
originq:
token: "your-originq-key"
ibm:
token: "your-ibm-token"
proxy:
http: "http://proxy:8080"
https: "https://proxy:8080"
适配器直接读取 active profile 下的平台配置,不再通过 API token 环境变量注入凭据。
6.2 IBM 代理配置¶
# 方式1:通过构造函数传入
adapter = QiskitAdapter(proxy={"https": "http://proxy:8080"})
# 方式2:通过环境变量
export HTTP_PROXY=http://proxy:8080
export HTTPS_PROXY=http://proxy:8080
6.4 Dummy 模式¶
通过 backend 名称前缀 dummy 激活本地模拟,无需环境变量:
task_id = submit_task(circuit, backend='dummy:local:simulator') # 默认模拟
task_id = submit_task(circuit, backend='dummy:local:virtual-line-3') # 线性 3q 拓扑
7. 快速参考表 {#platform-quick-reference}¶
维度 |
OriginQ |
IBM |
Dummy |
|---|---|---|---|
地区 |
中国 |
全球 |
本地 |
输入 |
OriginIR string |
qiskit.QuantumCircuit |
OriginIR string |
结果格式 |
|
|
|
提交模式 |
异步 |
同步 |
同步 |
|
✅ |
✅ |
❌ |
1Q 门保真度 |
✅ 可用 |
✅ 可用 |
❌ |
电路优化 |
|
|
N/A |
chip_characterization 支持 |
✅ |
✅ |
✅ 从标定数据自动推导噪声参数 |
免费额度 |
有限 |
✅ 有开放设备 |
无需联网 |
8. DummyBackend:编号规则、虚拟拓扑与本地噪声模拟 {#platform-dummy-backend}¶
DummyBackend 是本地模拟器后端,在不需要真实量子硬件的情况下执行电路。推荐通过 backend id 使用,而不是在业务代码里手动拼装 adapter。
backend id |
语义 |
|---|---|
|
无约束、无噪声虚拟机 |
|
|
|
|
|
复用真实 backend 的拓扑和标定数据,先 compile/transpile,再本地含噪执行 |
dummy:<platform>:<backend> 是规则型写法,不是需要提前注册的 backend;它不会作为独立后端出现在 uniqc backend list 或 Gateway WebUI 的 backend 卡片中。运行时会解析真实 backend 的 topology / chip characterization,并把编译后的线路写入 task metadata。
基本用法¶
from uniqc import submit_task, wait_for_result
# 无约束、无噪声
task_id = submit_task(circuit, backend="dummy:local:simulator", shots=1000)
result = wait_for_result(task_id)
# 有拓扑约束但无噪声
line_task = submit_task(circuit, backend="dummy:local:virtual-line-3", shots=1000)
# 针对真实 OriginQ backend 的本地含噪仿真
noisy_task = submit_task(circuit, backend="dummy:originq:WK_C180", shots=1000)
chip_characterization 如何转换为噪声参数¶
使用 dummy:<platform>:<backend> 时,UnifiedQuantum 会从缓存或对应云平台 adapter 取得 ChipCharacterization,再自动提取以下数据:
标定数据 |
转换方式 |
用法 |
|---|---|---|
|
|
注入单量子比特去极化噪声 |
|
|
注入双量子比特门去极化噪声 |
|
对称读出误差模型 |
注入读出误差 |
若某量子比特或量子比特对缺少标定数据,使用默认值(1Q 误差 0.01,2Q 误差 0.05)。
直接使用 DummyAdapter(chip_characterization=...) 仍可作为底层测试或自定义 adapter 路径,但文档、示例和新业务代码应优先使用 dummy:<platform>:<backend>,这样 compile/transpile、task metadata 和 Gateway 展示都能走统一链路。
DummyOptions(Python API)¶
from uniqc import DummyOptions
opts = DummyOptions(
noise_model=None, # 可选,传入噪声模型(dict)
available_qubits=16, # 默认 16
available_topology=None, # None=all-to-all,传入 [[u,v], ...] 指定拓扑
shots=1000,
)
CLI 中的 Dummy 后端¶
CLI 使用 --backend 指定后端标识符,默认为 dummy:local:simulator:
# 无约束、无噪声(简写)
uniqc submit circuit.ir --backend dummy --shots 1000 --wait
# 等价于不传 --backend(默认即 dummy:local:simulator)
uniqc submit circuit.ir --shots 1000 --wait
# 虚拟线性拓扑
uniqc submit circuit.ir --backend dummy:local:virtual-line-3 --shots 1000 --wait
# 真实 backend 的本地含噪仿真
uniqc submit circuit.ir --backend dummy:originq:WK_C180 --shots 1000 --wait
# 试运行验证
uniqc submit circuit.ir --backend dummy --dry-run
9. 统一后端工厂:get_backend() {#platform-get-backend}¶
get_backend() 是量子后端工厂函数(uniqc.backend_adapter.backend),用于获取平台后端实例。日常代码优先从 uniqc 直接导入。
from uniqc import get_backend
# 获取 DummyBackend(纯净模拟)
backend = get_backend("dummy")
task_id = backend.submit(circuit, shots=1000)
# 获取带虚拟拓扑的 DummyBackend
backend = get_backend("dummy:local:virtual-line-3")
# 获取真实 backend 规则对应的 DummyBackend(提交时仍会先 compile/transpile)
backend = get_backend("dummy:originq:WK_C180")
# 获取 OriginQ 后端
backend = get_backend("originq")
# 获取 IBM 后端
backend = get_backend("ibm")
get_backend() 返回 QuantumBackend 实例,支持 .submit()、.query() 等方法。详见 后端管理。