扫描参数,并确认每个点都执行成功¶
对单个 RY(θ) 门扫描 θ = -0.5、0、0.5 rad。这里使用只含 Digital 门的 Hybrid 程序,便于手算,同时练习与 Digital-Analog 实验相同的扫描接口。请先完成共享参数,并使用安装好的环境。
从 |0⟩ 出发,P(1) = sin²(θ/2)。三个点的预测值依次约为 0.061209、0、0.061209。正负角度在这个测量基下给出相同概率,并不表示它们制备了相同量子态。
提交一组明确的参数点¶
"""通过统一 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()
python3 examples/user/tracks/hybrid_researcher/03_applied_parameter_sweep_zh.py
ParameterScan.explicit() 保留输入点的顺序。shots=16 是每个点的采样次数,整个扫描共请求 48 次。扫描根据根随机种子和点的索引派生各点种子。工作线程完成的先后不会改变这种对应关系,但调整点的排列顺序可能会改变它。
程序不含 Analog 演化,因此无需时间积分。执行扫描时不必额外塞入一个 Analog 程序块,也不必设置时间步数。
{
"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"
}
使用数据前,先查看总任务的 job_state,再检查所有 item_states。本例要求全部成功,否则直接报错。读取每个结果时,同时读取 item.bind_set.values;工作线程完成顺序不能用来标识参数点。selected_workers 受可用 CPU 和内存限制,三个点不一定能同时执行。
概率数组应符合开头的预测,各点计数之和应为 [16, 16, 16]。两个非零角度测得的 1 次数可以不同。尤其要区分“缺失结果”和“测得零次激发”:失败点没有结果,不能当作概率为零的数据参与分析。
输入无效与运行失败发生在不同阶段¶
扫描会在启动子任务前检查全部参数绑定。越界值、未知参数等无效输入会以 LOCAL_HYBRID_SCAN_INVALID 拒绝提交,continue_on_error 不会绕过这些检查。
这个策略处理的是子任务执行过程中的失败。结果会保留成功和失败的各点状态;部分成功、部分失败时,总状态为 partially_completed;全部失败则为 failed。使用 fail_fast 时,按索引顺序执行,遇到失败后,后续尚未启动的点标为 not_run。重跑前应先检查失败点的诊断。
检查顺序与采样次数¶
- 将三个输入点倒序,预测返回的参数顺序和概率。
- 将最后一个值改为
1.5,超过声明上界。continue_on_error会留下前两个点的结果吗? - 将每点采样次数从 16 提高到 4096。哪类输出的波动会变小?总采样次数是多少?
核对思路
顺序变为 [0.5, 0.0, -0.5]。概率函数是偶函数,因此概率数组的数值不变。随机种子随索引分配,不应要求移动后的点保持原来的计数。无效值 1.5 会使整个扫描在子任务启动前被拒绝,这次提交不会产生前两个点的结果。每点 4096 次时,总计 12288 次;采样频率更接近相同的状态概率,增加采样次数不会提高状态演化的数值精度。
Hybrid 参数指南还介绍了网格扫描和绑定细节。下一课加入物理噪声,区分状态变化与有限次采样造成的波动。