最佳实践

11 个发布前可重跑的完整场景:从配置/缓存、构造电路、编译、API/CLI 提交、变分线路、 Torch 集成,到 calibration + QEM、XEB workflow。每一个都对应 examples/3_best_practices/<n>_*.py,并由 scripts/build_docs.py 在文档构建时 按 [doc-require:] 门控自动重跑。

覆盖矩阵

案例

配置

后端缓存

裸 Circuit

Named

虚拟/本地后端

API 提交

CLI 提交

可视化

变分

Torch

Calibration/QEM

00 配置与后端缓存

01 裸线路模拟

02 Named Circuit

03 编译与虚拟后端

04 API 提交

05 CLI 提交

06 云后端模板

07 变分线路

08 Torch 集成

09 Calibration + QEM

10 XEB workflow

案例

00 — 配置 Key 与后端缓存

Source: examples/3_best_practices/00_config_and_backend_cache.py
Status: pass

最早的用户路径:创建配置、写入平台 token(脱敏)、校验配置结构,并用本地构造的 BackendInfo 演示后端缓存的写入、读取和审查。真实 token 不会写入文档输出。

Source code

"""00 — 配置 Key 与后端缓存

[doc-require: ]
[doc-output-include: stdout, source]

最早的用户路径:创建配置、写入平台 token(脱敏)、校验配置结构,并用本地构造的
``BackendInfo`` 演示后端缓存的写入、读取和审查。真实 token 不会写入文档输出。
"""

from __future__ import annotations

import tempfile
from pathlib import Path

from uniqc import BackendInfo, Platform, QubitTopology, audit_backends
from uniqc.backend_adapter.backend_cache import (
    cache_info,
    get_cached_backends,
    update_cache,
)
from uniqc.backend_adapter.config import load_config, save_config, validate_config


def main() -> None:
    workdir = Path(tempfile.mkdtemp(prefix="uniqc-bp-config-"))
    config_path = workdir / "config.yaml"

    config = {
        "active_profile": "release-check",
        "release-check": {
            "originq": {"token": "originq-token-redacted"},
            "quafu": {"token": "quafu-token-redacted"},
            "ibm": {"token": "ibm-token-redacted", "proxy": {"http": "", "https": ""}},
        },
    }
    save_config(config, config_path=config_path)

    loaded = load_config(config_path=config_path)
    errors = validate_config(config_path=config_path)
    print("profile:", loaded["active_profile"])
    print("validation errors:", errors)

    backend = BackendInfo(
        platform=Platform.DUMMY,
        name="virtual-line-3",
        description="release-check virtual backend",
        num_qubits=3,
        topology=(QubitTopology(0, 1), QubitTopology(1, 2)),
        status="available",
        is_simulator=True,
    )
    update_cache(Platform.DUMMY, [backend], cache_dir=workdir)
    cached = get_cached_backends(Platform.DUMMY, cache_dir=workdir)
    print("cached backend ids:", [b.full_id() for b in cached])
    print("cache platforms:", sorted(cache_info(cache_dir=workdir)))
    print("audit issues:", audit_backends(cached))


if __name__ == "__main__":
    main()

Stdout

profile: release-check
validation errors: []
cached backend ids: ['dummy:virtual-line-3']
cache platforms: ['dummy']
audit issues: []

01 — 裸 Circuit、本地模拟与结果可视化

Source: examples/3_best_practices/01_bare_circuit_simulation.py
Status: pass

从空 Circuit 构造 Bell 态,导出 OriginIR / OpenQASM 2.0,使用本地模拟器得到 概率分布并画图。

Source code

"""01 — 裸 Circuit、本地模拟与结果可视化

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

从空 ``Circuit`` 构造 Bell 态,导出 OriginIR / OpenQASM 2.0,使用本地模拟器得到
概率分布并画图。
"""

from __future__ import annotations

import math

import matplotlib.pyplot as plt

from uniqc import Circuit
from uniqc.simulator import Simulator


def probability_dict(values):
    if isinstance(values, dict):
        total = sum(values.values()) or 1
        return {
            format(int(k), "b") if isinstance(k, int) else str(k): v / total
            for k, v in values.items()
        }
    n = int(math.log2(len(values))) if values else 0
    return {
        format(i, f"0{n}b"): float(p)
        for i, p in enumerate(values)
        if abs(float(p)) > 1e-12
    }


def plot_probs(probs, title):
    labels = list(probs)
    values = [probs[k] for k in labels]
    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.bar(labels, values, color="#3267a8")
    ax.set_ylim(0, max(1.0, max(values, default=0) * 1.2))
    ax.set_xlabel("bitstring")
    ax.set_ylabel("probability")
    ax.set_title(title)
    ax.grid(axis="y", alpha=0.25)
    fig.tight_layout()


def main() -> None:
    circuit = Circuit()
    circuit.h(0)
    circuit.cnot(0, 1)
    circuit.measure(0, 1)

    print("OriginIR:")
    print(circuit.originir)
    print("QASM header:")
    print("\n".join(circuit.qasm.splitlines()[:6]))

    sim = Simulator()
    probs = probability_dict(sim.simulate_pmeasure(circuit.originir))
    print("probabilities:", probs)
    plot_probs(probs, "Bell state probabilities")


if __name__ == "__main__":
    main()

Stdout

OriginIR:
QINIT 2
CREG 2
H q[0]
CNOT q[0], q[1]
MEASURE q[0], c[0]
MEASURE q[1], c[1]

QASM header:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0], q[1];
probabilities: {'00': 0.4999999999999999, '11': 0.4999999999999999}

Figures

01 — 裸 Circuit、本地模拟与结果可视化 — figure-01.svg

02 — Named Circuit 与可复用线路

Source: examples/3_best_practices/02_named_circuit_and_reuse.py
Status: pass

用命名寄存器和 @circuit_def 组织可复用子线路,再组合成一个 4-qubit GHZ-like 电路。

Source code

"""02 — Named Circuit 与可复用线路

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

用命名寄存器和 ``@circuit_def`` 组织可复用子线路,再组合成一个 4-qubit GHZ-like 电路。
"""

from __future__ import annotations

import math

import matplotlib.pyplot as plt

from uniqc import Circuit, circuit_def
from uniqc.simulator import Simulator


def probability_dict(values):
    n = int(round(math.log2(len(values)))) if values else 0
    return {
        format(i, f"0{n}b"): float(p)
        for i, p in enumerate(values)
        if abs(float(p)) > 1e-12
    }


def plot_probs(probs, title):
    labels = list(probs)
    values = [probs[k] for k in labels]
    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.bar(labels, values, color="#3267a8")
    ax.set_ylim(0, max(1.0, max(values, default=0) * 1.2))
    ax.set_xlabel("bitstring")
    ax.set_ylabel("probability")
    ax.set_title(title)
    ax.grid(axis="y", alpha=0.25)
    fig.tight_layout()


@circuit_def(name="bell_pair", qregs={"q": 2})
def bell_pair(circ, q):
    circ.h(q[0])
    circ.cnot(q[0], q[1])
    return circ


@circuit_def(name="rz_layer", qregs={"q": 4}, params=["angle"])
def rz_layer(circ, q, angle):
    for i in range(4):
        circ.rz(q[i], angle)
    return circ


def main() -> None:
    circuit = Circuit(qregs={"data": 4})
    data = circuit.get_qreg("data")

    bell_pair(circuit, qreg_mapping={"q": [data[0], data[1]]})
    bell_pair(circuit, qreg_mapping={"q": [data[2], data[3]]})
    circuit.cnot(data[1], data[2])
    rz_layer(
        circuit,
        qreg_mapping={"q": [data[0], data[1], data[2], data[3]]},
        param_values={"angle": 0.25},
    )
    circuit.measure(0, 1, 2, 3)

    print("DEF export:")
    print(bell_pair.to_originir_def())
    print("operations:", len(circuit.opcode_list))

    probs = probability_dict(Simulator().simulate_pmeasure(circuit.originir))
    print("non-zero states:", probs)
    plot_probs(probs, "Named circuit result")


if __name__ == "__main__":
    main()

Stdout

DEF export:
DEF bell_pair(q[0], q[1])
H q[0]
CNOT q[0], q[1]
ENDDEF
operations: 9
non-zero states: {'0000': 0.24999999999999978, '0111': 0.2499999999999998, '1011': 0.24999999999999986, '1100': 0.24999999999999983}

Figures

02 — Named Circuit 与可复用线路 — figure-01.svg

03 — 编译、拓扑与虚拟后端

Source: examples/3_best_practices/03_compile_region_dummy_backend.py
Status: pass

构造一个虚拟线性拓扑后端,把不满足相邻拓扑的线路编译到目标基门集合,并检查编译产物。

Source code

"""03 — 编译、拓扑与虚拟后端

[doc-require: ]
[doc-output-include: stdout, source]

构造一个虚拟线性拓扑后端,把不满足相邻拓扑的线路编译到目标基门集合,并检查编译产物。
"""

from __future__ import annotations

from uniqc import BackendInfo, Circuit, Platform, QubitTopology, compile


def main() -> None:
    circuit = Circuit()
    circuit.h(0)
    circuit.cnot(0, 2)

    backend = BackendInfo(
        platform=Platform.DUMMY,
        name="virtual-line-3",
        num_qubits=3,
        topology=(QubitTopology(0, 1), QubitTopology(1, 2)),
        status="available",
        is_simulator=True,
    )

    compiled_originir = compile(circuit, backend_info=backend, output_format="originir")
    compiled_qasm = compile(circuit, backend_info=backend, output_format="qasm")

    print("backend:", backend.full_id())
    print("compiled OriginIR:")
    print(compiled_originir)
    print("compiled QASM first lines:")
    print("\n".join(compiled_qasm.splitlines()[:8]))


if __name__ == "__main__":
    main()

Stdout

backend: dummy:virtual-line-3
compiled OriginIR:
QINIT 3
CREG 0
RZ q[0], (1.5707963267948966)
SX q[0]
RZ q[0], (1.5707963267948966)
RZ q[1], (1.5707963267948966)
SX q[1]
RZ q[1], (3.141592653589793)
CZ q[0], q[1]
SX q[1]
RZ q[1], (1.5707963267948966)

compiled QASM first lines:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[0];
rz(pi/2) q[0];
sx q[0];
rz(pi/2) q[0];
rz(pi/2) q[1];

04 — Python API 提交、取回与可视化

Source: examples/3_best_practices/04_api_submit_dummy_result.py
Status: pass

使用 submit_task(backend="dummy:local:simulator") 验证远端任务接口的本地替代 路径:提交、等待、查询缓存、画图。

  • backend="dummy:local:simulator" 表示无约束、无噪声;

  • 需要虚拟拓扑时使用 dummy:local:virtual-line-N / dummy:local:virtual-grid-RxC

  • 需要真实芯片噪声时使用 dummy:<platform>:<backend>

Source code

"""04 — Python API 提交、取回与可视化

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

使用 ``submit_task(backend="dummy:local:simulator")`` 验证远端任务接口的本地替代
路径:提交、等待、查询缓存、画图。

* ``backend="dummy:local:simulator"`` 表示无约束、无噪声;
* 需要虚拟拓扑时使用 ``dummy:local:virtual-line-N`` / ``dummy:local:virtual-grid-RxC``;
* 需要真实芯片噪声时使用 ``dummy:<platform>:<backend>``。
"""

from __future__ import annotations

import matplotlib.pyplot as plt

from uniqc import Circuit, get_task, submit_task, wait_for_result


def plot_probs(probs, title):
    labels = list(probs)
    values = [probs[k] for k in labels]
    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.bar(labels, values, color="#3267a8")
    ax.set_ylim(0, max(1.0, max(values, default=0) * 1.2))
    ax.set_xlabel("bitstring")
    ax.set_ylabel("probability")
    ax.set_title(title)
    ax.grid(axis="y", alpha=0.25)
    fig.tight_layout()


def main() -> None:
    circuit = Circuit()
    circuit.h(0)
    circuit.cnot(0, 1)
    circuit.measure(0, 1)

    task_id = submit_task(
        circuit,
        backend="dummy:local:simulator",
        shots=128,
        metadata={"example": "best-practices-api"},
    )
    counts = wait_for_result(task_id)
    task = get_task(task_id)

    print("task_id:", task_id)
    print("status:", task.status)
    print("counts:", counts)

    probs = {k: v / sum(counts.values()) for k, v in counts.items()}
    plot_probs(probs, "API dummy submission result")


if __name__ == "__main__":
    main()

Stdout

task_id: uqt_eae7e360b52a40f28686206ebb385441
status: success
counts: UnifiedResult(counts={'00': 64, '11': 64}, probabilities={'00': 0.5, '11': 0.5}, shots=128, platform='dummy', task_id='uqt_eae7e360b52a40f28686206ebb385441', backend_name='dummy:local:simulator', execution_time=None, error_message=None)

Figures

04 — Python API 提交、取回与可视化 — figure-01.svg

05 — CLI 提交完整链路

Source: examples/3_best_practices/05_cli_workflow_dummy.py
Status: pass

通过 subprocess.run 执行 CLI:写出 OriginIR 文件,uniqc submit --backend dummy --wait, 并展示返回结果。

  • --backend dummy(默认)对应无约束、无噪声的 dummy:local:simulator

  • 可通过 --backend dummy:local:virtual-line-3 指定虚拟拓扑;

  • 也可通过 --backend dummy:originq:WK_C180 走真实 backend compile/transpile + 本地含噪执行。

Source code

"""05 — CLI 提交完整链路

[doc-require: ]
[doc-output-include: stdout, source]

通过 ``subprocess.run`` 执行 CLI:写出 OriginIR 文件,``uniqc submit --backend dummy --wait``,
并展示返回结果。

* ``--backend dummy``(默认)对应无约束、无噪声的 ``dummy:local:simulator``;
* 可通过 ``--backend dummy:local:virtual-line-3`` 指定虚拟拓扑;
* 也可通过 ``--backend dummy:originq:WK_C180`` 走真实 backend compile/transpile + 本地含噪执行。
"""

from __future__ import annotations

import pathlib
import subprocess
import sys
import tempfile

PROJECT_ROOT = pathlib.Path(__file__).resolve().parents[2]


def main() -> None:
    workdir = pathlib.Path(tempfile.mkdtemp(prefix="uniqc-bp-cli-"))
    circuit_file = workdir / "bell.originir"
    circuit_file.write_text(
        "QINIT 2\nCREG 2\nH q[0]\nCNOT q[0], q[1]\n"
        "MEASURE q[0], c[0]\nMEASURE q[1], c[1]\n",
        encoding="utf-8",
    )

    cmd = [
        sys.executable,
        "-m",
        "uniqc.cli",
        "submit",
        str(circuit_file),
        "--backend",
        "dummy",
        "-s",
        "64",
        "--wait",
        "--format",
        "json",
    ]
    completed = subprocess.run(
        cmd,
        cwd=PROJECT_ROOT,
        text=True,
        capture_output=True,
        check=True,
    )
    print("command:", " ".join(cmd))
    print(completed.stdout)


if __name__ == "__main__":
    main()

Stdout

command: /home/agony/projects/uniqc-dev/UnifiedQuantum/.venv/bin/python3 -m uniqc.cli submit /tmp/uniqc-bp-cli-_x2r5t8y/bell.originir --backend dummy -s 64 --wait --format json
{
  "task_id": "uqt_ed3f17897c5f44c88fd8696722ae7d50",
  "backend": "dummy:local:simulator",
  "shots": 64
}
{
  "counts": {
    "00": 32,
    "11": 32
  },
  "probabilities": {
    "00": 0.5,
    "11": 0.5
  },
  "shots": 64,
  "platform": "dummy",
  "task_id": "uqt_ed3f17897c5f44c88fd8696722ae7d50",
  "backend_name": "dummy:local:simulator",
  "execution_time": null,
  "error_message": null
}

06 — 云后端提交模板与 dry-run

Source: examples/3_best_practices/06_cloud_backend_template.py
Status: pass

展示真实后端路径的安全模板:先 dry_run_task,再提交。该例子默认仅执行 dummy dry-run;真实 OriginQ / Quafu / IBM 提交单元应在维护者确认 token、账号额度和后端

Source code

"""06 — 云后端提交模板与 dry-run

[doc-require: ]
[doc-output-include: stdout, source]

展示真实后端路径的安全模板:先 ``dry_run_task``,再提交。该例子默认仅执行 dummy
dry-run;真实 OriginQ / Quafu / IBM 提交单元应在维护者确认 token、账号额度和后端
可用后再打开(参考 ``[doc-require: originq]`` 等门控)。
"""

from __future__ import annotations

from uniqc import Circuit, dry_run_task


def main() -> None:
    circuit = Circuit()
    circuit.h(0)
    circuit.measure(0)

    result = dry_run_task(circuit, backend="dummy:local:simulator", shots=100)
    print("dummy dry-run success:", result.success)
    print("details:", result.details)

    cloud_templates = {
        "originq API": "submit_task(circuit, backend='originq:PQPUMESH8', shots=1000)",
        "quafu API": "submit_task(circuit, backend='quafu:ScQ-P18', shots=1000)",
        "ibm API": "submit_task(circuit, backend='ibm:ibm_fez', shots=1000)",
        "CLI dry-run": "uniqc submit bell.originir --backend quafu:ScQ-P18 --dry-run",
    }
    for name, snippet in cloud_templates.items():
        print(f"{name}: {snippet}")


if __name__ == "__main__":
    main()

Stdout

dummy dry-run success: True
details: Dry-run passed for dummy simulator: OriginIR is valid. Qubits=1, shots=100
originq API: submit_task(circuit, backend='originq:PQPUMESH8', shots=1000)
quafu API: submit_task(circuit, backend='quafu:ScQ-P18', shots=1000)
ibm API: submit_task(circuit, backend='ibm:ibm_fez', shots=1000)
CLI dry-run: uniqc submit bell.originir --backend quafu:ScQ-P18 --dry-run

07 — 简单变分量子线路

Source: examples/3_best_practices/07_variational_circuit.py
Status: pass

用一个单参数 ansatz 最小化 <Z>。该例子故意不用外部优化库,便于确认线路、模拟和 可视化路径。

Source code

"""07 — 简单变分量子线路

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

用一个单参数 ansatz 最小化 ``<Z>``。该例子故意不用外部优化库,便于确认线路、模拟和
可视化路径。
"""

from __future__ import annotations

import math

import matplotlib.pyplot as plt

from uniqc import Circuit
from uniqc.simulator import Simulator


def build_ansatz(theta):
    c = Circuit()
    c.ry(0, float(theta))
    c.measure(0)
    return c


def z_expectation(theta):
    counts = Simulator().simulate_shots(build_ansatz(theta).originir, shots=400)
    total = sum(counts.values()) or 1
    p0 = counts.get(0, 0) / total
    p1 = counts.get(1, 0) / total
    return p0 - p1


def main() -> None:
    theta = 0.2
    history = []
    for step in range(18):
        value = z_expectation(theta)
        plus = z_expectation(theta + math.pi / 2)
        minus = z_expectation(theta - math.pi / 2)
        grad = 0.5 * (plus - minus)
        history.append((step, theta, value, grad))
        theta -= 0.25 * grad

    for row in history[::4]:
        print("step=%02d theta=%.3f <Z>=%.3f grad=%.3f" % row)
    print("final theta:", round(theta, 4))

    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.plot([r[0] for r in history], [r[2] for r in history], marker="o")
    ax.set_xlabel("step")
    ax.set_ylabel("<Z>")
    ax.set_title("Variational circuit optimization")
    ax.grid(alpha=0.25)
    fig.tight_layout()


if __name__ == "__main__":
    main()

Stdout

step=00 theta=0.200 <Z>=0.990 grad=-0.240
step=04 theta=0.496 <Z>=0.850 grad=-0.495
step=08 theta=1.130 <Z>=0.385 grad=-0.912
step=12 theta=2.098 <Z>=-0.505 grad=-0.872
step=16 theta=2.748 <Z>=-0.925 grad=-0.463
final theta: 2.9356

Figures

07 — 简单变分量子线路 — figure-01.svg

08 — Torch 集成后的量子线路

Source: examples/3_best_practices/08_torch_quantum_training.py
Status: pass

用 PyTorch 管理参数和优化器,量子期望值由 UnifiedQuantum 线路和模拟器计算,梯度 使用 parameter-shift 写回。

Source code

"""08 — Torch 集成后的量子线路

[doc-require: pytorch, matplotlib]
[doc-output-include: stdout, figures, source]

用 PyTorch 管理参数和优化器,量子期望值由 UnifiedQuantum 线路和模拟器计算,梯度
使用 parameter-shift 写回。
"""

from __future__ import annotations

import math

import matplotlib.pyplot as plt
import torch

from uniqc import Circuit
from uniqc.simulator import Simulator


def circuit_for(theta):
    c = Circuit()
    c.ry(0, float(theta))
    c.measure(0)
    return c


def z_expectation(theta):
    counts = Simulator().simulate_shots(circuit_for(theta).originir, shots=400)
    total = sum(counts.values()) or 1
    return (counts.get(0, 0) - counts.get(1, 0)) / total


def main() -> None:
    torch.manual_seed(7)

    theta = torch.nn.Parameter(torch.tensor(0.1))
    optimizer = torch.optim.SGD([theta], lr=0.3)
    history = []

    for step in range(16):
        optimizer.zero_grad()
        value = z_expectation(theta.item())
        grad = 0.5 * (
            z_expectation(theta.item() + math.pi / 2)
            - z_expectation(theta.item() - math.pi / 2)
        )
        theta.grad = torch.tensor(grad)
        optimizer.step()
        history.append((step, theta.item(), value, grad))

    print("torch parameter:", theta)
    print("last rows:", history[-3:])

    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.plot([r[0] for r in history], [r[2] for r in history], marker="o", label="<Z>")
    ax.plot([r[0] for r in history], [r[1] for r in history], marker="s", label="theta")
    ax.set_xlabel("step")
    ax.set_title("Torch optimizer with quantum expectation")
    ax.grid(alpha=0.25)
    ax.legend()
    fig.tight_layout()


if __name__ == "__main__":
    main()

Stdout

torch parameter: Parameter containing:
tensor(2.7580, requires_grad=True)
last rows: [(13, 2.3747503757476807, -0.56, -0.8125), (14, 2.575000286102295, -0.715, -0.6675), (15, 2.758000373840332, -0.885, -0.61)]

Figures

08 — Torch 集成后的量子线路 — figure-01.svg

09 — Calibration + QEM

Source: examples/3_best_practices/09_calibration_qem_dummy.py
Status: pass

在带显式读出噪声的 dummy adapter 上运行读出校准,将校准结果写入临时缓存,再用 ReadoutEM 对同一个 noisy backend 产生的观测 counts 做修正。

Source code

"""09 — Calibration + QEM

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

在带显式读出噪声的 dummy adapter 上运行读出校准,将校准结果写入临时缓存,再用
``ReadoutEM`` 对同一个 noisy backend 产生的观测 counts 做修正。
"""

from __future__ import annotations

import tempfile

import matplotlib.pyplot as plt

from uniqc import Circuit
from uniqc.backend_adapter.task.adapters import DummyAdapter
from uniqc.calibration.readout import ReadoutCalibrator
from uniqc.qem import ReadoutEM


def main() -> None:
    cache_dir = tempfile.mkdtemp(prefix="uniqc-bp-calibration-")
    adapter = DummyAdapter(noise_model={"readout": [0.08, 0.12]})
    calibrator = ReadoutCalibrator(adapter=adapter, shots=200, cache_dir=cache_dir)
    calibration = calibrator.calibrate_1q(0)

    observed_circuit = Circuit(1)
    observed_circuit.x(0)
    observed_circuit.measure(0)
    task_id = adapter.submit(observed_circuit.originir, shots=200)
    raw_counts = adapter.query(task_id)["result"]
    observed = {int(k, 2): v for k, v in raw_counts.items()}
    mitigator = ReadoutEM(adapter=adapter, shots=200, cache_dir=cache_dir)
    corrected = mitigator.mitigate_counts(observed, measured_qubits=[0])

    print("assignment fidelity:", round(calibration["assignment_fidelity"], 4))
    print("confusion matrix:", calibration["confusion_matrix"])
    print("observed:", observed)
    print("corrected:", {k: round(v, 2) for k, v in corrected.items()})

    labels = ["0", "1"]
    fig, ax = plt.subplots(figsize=(6, 3.4))
    x = range(len(labels))
    ax.bar([i - 0.18 for i in x], [observed[i] for i in x], width=0.36, label="observed")
    ax.bar([i + 0.18 for i in x], [corrected[i] for i in x], width=0.36, label="mitigated")
    ax.set_xticks(list(x))
    ax.set_xticklabels(labels)
    ax.set_ylabel("counts")
    ax.set_title("Readout error mitigation")
    ax.legend()
    ax.grid(axis="y", alpha=0.25)
    fig.tight_layout()


if __name__ == "__main__":
    main()

Stdout

assignment fidelity: 0.9
confusion matrix: ((0.92, 0.12), (0.08, 0.88))
observed: {0: 24, 1: 176}
corrected: {0: 0.0, 1: 200.0}

Figures

09 — Calibration + QEM — figure-01.svg

10 — XEB workflow

Source: examples/3_best_practices/10_xeb_workflow_dummy.py
Status: pass

使用很小的参数运行 1q XEB,覆盖校准、ReadoutEM、随机线路生成、fidelity 拟合和结果 图示。本例子使用 backend="dummy:local:simulator" 搭配显式 noise_model 做本地 含噪发布检查;如果要检查真实芯片标定噪声路径,应改用 backend="dummy:originq:WK_C180" 这类规则型 backend id,它会先按真实 backend compile/transpile,再本地含噪执行。

Source code

"""10 — XEB workflow

[doc-require: matplotlib]
[doc-output-include: stdout, figures, source]

使用很小的参数运行 1q XEB,覆盖校准、ReadoutEM、随机线路生成、fidelity 拟合和结果
图示。本例子使用 ``backend="dummy:local:simulator"`` 搭配显式 ``noise_model`` 做本地
含噪发布检查;如果要检查真实芯片标定噪声路径,应改用 ``backend="dummy:originq:WK_C180"``
这类规则型 backend id,它会先按真实 backend compile/transpile,再本地含噪执行。
"""

from __future__ import annotations

import tempfile

import matplotlib.pyplot as plt

from uniqc import xeb_workflow


def main() -> None:
    cache_dir = tempfile.mkdtemp(prefix="uniqc-bp-xeb-")
    results = xeb_workflow.run_1q_xeb_workflow(
        backend="dummy:local:simulator",
        qubits=[0],
        depths=[1, 2, 3],
        n_circuits=3,
        shots=128,
        use_readout_em=True,
        noise_model={"depol": 0.01, "readout": 0.04},
        seed=11,
        cache_dir=cache_dir,
    )

    result = results[0]
    print("fidelity_per_layer:", round(result.fidelity_per_layer, 6))
    print(
        "fit parameters:",
        {
            "A": round(result.fit_a, 6),
            "B": round(result.fit_b, 6),
            "r": round(result.fit_r, 6),
        },
    )
    print("depths:", result.depths)

    fitted = [
        result.fit_a * (result.fit_r ** depth) + result.fit_b for depth in result.depths
    ]
    fig, ax = plt.subplots(figsize=(6, 3.4))
    ax.plot(result.depths, fitted, marker="o")
    ax.set_xlabel("depth")
    ax.set_ylabel("fitted fidelity")
    ax.set_title("1q XEB fitted release-check result")
    ax.grid(alpha=0.25)
    fig.tight_layout()


if __name__ == "__main__":
    main()

Stdout

fidelity_per_layer: 0.983341
fit parameters: {'A': 1.01276, 'B': 0.0, 'r': 0.983341}
depths: (1, 2, 3)

Figures

10 — XEB workflow — figure-01.svg

发布前重跑

维护者发布前应该用全开发环境重跑一次完整 docs 流水线(含 pre-doc-execution):

uv sync --all-extras --group dev --group docs --upgrade
cd docs
uv run make html

如果某个示例因为缺少依赖或凭据无法执行,scripts/build_docs.py跳过而不是 失败;请保证至少 dummy:local:* 路径全部 pass。如果某个示例真的产生了 warning / error 而它本应被忽略(比如来自某个第三方库的 deprecation),用 [doc-warning-ignore: <regex>] 在示例 docstring 里标注即可。