扫描一组参数,并保留失败点¶
参数扫描适合比较同一程序在多个输入下的结果。当前统一扫描入口接收 HybridProgram;纯数字实验也可以包装成只含 Digital 块的 HybridProgram,不必加入无关的 Analog 块。
- 保留参数化程序,用
ParameterScan.explicit()列出有序参数点;需要笛卡尔积时使用ParameterScan.cartesian()。 - 将扫描传给
LocalBackend.run(program, sweep=scan, shots=...)。不要同时传params。 - 调用扫描 Job 的
result(),读取总状态以及每个点的状态、绑定值、结果或错误。 - 按保存的参数点和索引整理数据。失败点保留为失败,不能填成概率零。
最小可核对扫描¶
三个角度为 −0.5、0 和 0.5 rad。对单个 RY 门,P(1) = sin²(theta/2),因此两端概率相同,中间为零。
"""通过统一 Hybrid Backend 执行可复现的参数扫描。
``ParameterScan`` 按声明顺序展开参数点。每个 child 会保存自己的绑定值、seed、
结果和状态;aggregate result 则汇总 worker 数和资源规划信息。
"""
from __future__ import annotations
import json
from cascaqit import Circuit, HybridProgram, LocalBackend
from cascaqit.parameters import ParameterScan
def main() -> None:
"""运行三个旋转角度,并按 scan 顺序检查 child result。"""
circuit = Circuit(1, program_id="lesson.hybrid.sweep.digital")
theta = circuit.parameter("theta", lower_bound=-1.0, upper_bound=1.0)
circuit.ry(theta, 0)
program = (
HybridProgram("lesson.hybrid.sweep").digital("rotate", circuit).measure_all()
)
scan = ParameterScan.explicit(
scan_id="lesson.hybrid.sweep.points",
points=tuple({"theta": value} for value in (-0.5, 0.0, 0.5)),
)
job = LocalBackend(seed=103).run(
program, sweep=scan, shots=16, failure_policy="continue_on_error"
)
result = job.result()
if job.status().state != "completed" or any(
item.state != "completed" or item.result is None for item in result.items
):
raise RuntimeError("The parameter sweep did not complete every point.")
payload = {
"track": "hybrid_researcher",
"level": "applied",
"lesson": "parameter_sweep",
"facts": {
"job_state": job.status().state,
"item_states": [item.state for item in result.items],
"theta_values": [item.bind_set.values["theta"] for item in result.items],
"counts_totals": [
sum((item.result.counts if item.result else {}).values())
for item in result.items
],
"probabilities": [
item.result.probabilities for item in result.items if item.result
],
"selected_workers": result.metadata["scan_resource_plan"][
"selected_workers"
],
},
"boundaries": {
"hardware_execution": False,
"cloud_execution": False,
"network_accessed": False,
"credentials_loaded": False,
},
}
print(json.dumps(payload, sort_keys=True))
if __name__ == "__main__":
main()
python examples/user/tracks/hybrid_researcher/03_applied_parameter_sweep_zh.py
{
"boundaries": {
"cloud_execution": false,
"credentials_loaded": false,
"hardware_execution": false,
"network_accessed": false
},
"facts": {
"counts_totals": [
16,
16,
16
],
"item_states": [
"completed",
"completed",
"completed"
],
"job_state": "completed",
"probabilities": [
{
"0": 0.9387912809451864,
"1": 0.061208719054813655
},
{
"0": 1.0,
"1": 0.0
},
{
"0": 0.9387912809451864,
"1": 0.061208719054813655
}
],
"selected_workers": 3,
"theta_values": [
-0.5,
0.0,
0.5
]
},
"lesson": "parameter_sweep",
"level": "applied",
"track": "hybrid_researcher"
}
本例每点 16 次采样,总计 48 次。item_states 应全部成功,计数总数为 [16, 16, 16]。并发完成顺序不决定参数顺序;随机种子按根种子和点索引派生,所以重新排列点可能改变对应计数。
拒绝输入与执行失败¶
绑定检查发生在子任务启动前。漏参、未知参数或越界会使整个扫描被拒绝;continue_on_error 无法跳过这些检查。
对子任务运行中的失败,continue_on_error 保留各点结果和错误;有成功也有失败时总状态为 partially_completed,全部失败为 failed。fail_fast 按索引顺序运行,失败后尚未启动的点为 not_run。
准备长扫描时,先用少量点确认物理范围和资源预算,再开启本地保存与恢复。更多字段见 ParameterScan 与扫描结果课程。