4. 量子实验控制与测试执行引擎

量子实验控制与测试执行引擎位于自动化测试平台的核心位置,它把实验意图翻译成对仪器、波形发生器、采集卡和量子比特控制通道的确定性操作序列,并在长时间运行中维持可观测、可中断、可恢复的执行状态。与普通软件任务不同,量子实验的“一次执行”往往由数千次单发(shot)组成,参数扫描会进一步把一次实验展开为多维任务网格,任何一次仪器超时、触发丢失或温度漂移都可能导致整批数据不可用。因此,执行引擎的设计重点不是“把任务跑起来”,而是让任务在受控、可追踪、可回退的语义下运行。

任务模型与调度语义

执行引擎首先需要把实验描述为可调度的任务对象。一个典型任务包含:实验标识、量子比特目标集合、脉冲/波形序列引用、参数扫描定义、采样次数、超时阈值、重试策略、数据落盘路径以及依赖关系。调度器不直接操作硬件,而是把任务拆成“准备—执行—采集—归档”四个阶段,每个阶段都有明确的完成条件和失败判据。例如准备阶段要求所有仪器处于远程控制模式且锁相环锁定;执行阶段要求触发计数达到设定 shot 数;采集阶段要求每个 shot 的数据长度与通道数一致;归档阶段要求元数据与原始数据同时写入。

调度策略上,建议采用“资源锁 + 优先级队列”的混合模型。每台仪器、每个量子比特控制通道、每条采集链路都是可加锁资源,任务在进入执行阶段前必须一次性申请其全部资源,避免运行中因资源竞争产生死锁。优先级由实验类型决定:校准类任务优先于表征类任务,表征类任务优先于批量扫描任务。对于同一量子比特上的冲突任务,调度器应串行化而非并行化,因为并行脉冲会相互干扰。

量子实验执行引擎:调度、扫描、批量与恢复 实验任务提交 实验ID / 比特 / 波形 资源锁 + 优先级调度 仪器锁 / 通道锁 / 采集锁 校准 > 表征 > 批量扫描 参数扫描展开 频率 / 幅度 / 延时 / 相位 笛卡尔积 → 任务网格 批量执行 逐点下发 / 采集 shot 级数据落盘 执行阶段: 准备(仪器锁定) 执行(脉冲下发) 采集(shot 计数) 归档(元数据+数据) 异常中断检测 • 仪器超时 / 触发丢失 • shot 数据长度不一致 • 锁相环失锁 / 温度越限 恢复机制 • 检查点:已完成 shot 索引 • 重试:同参数重发 N 次 • 回退:重置仪器到安全态 结果与判据 • 有效 shot 数 ≥ 设定值 • 数据完整率 ≥ 99% • 扫描点全部归档 恢复后从检查点续跑 关键设计原则 1. 资源锁一次性申请,避免运行中死锁;2. 参数扫描先展开为网格再调度,保证可复现; 3. 每个 shot 完成后立即落盘并记录索引,作为恢复检查点;4. 异常分类处理,可重试与不可重试分离。

参数扫描的展开与执行

参数扫描是量子实验中最常见的批量形态。假设要测量一个超导量子比特的 Ramsey 干涉条纹,扫描参数为等待时间 τ,范围 0 到 20 μs,步长 0.5 μs,共 41 个点;每个点采样 2000 次 shot。执行引擎不应把这 41×2000 次操作全部预先实例化为独立任务,而应先生成“扫描网格”,再按网格逐点执行。网格的每个节点记录参数组合、随机种子、预期 shot 数和输出文件偏移量。这样做的目的是让扫描过程可复现:给定同一网格定义和随机种子,任何一次重跑都应得到相同的数据组织方式。

对于多维扫描,例如同时扫描频率和幅度,网格规模会迅速膨胀。此时应引入“扫描策略”字段,支持笛卡尔积、随机采样和自适应采样三种模式。笛卡尔积适合小规模全因子实验;随机采样适合高维参数空间探索;自适应采样则根据前一批点的结果动态决定下一个采样位置,常用于快速寻找最优工作点。执行引擎需要把扫描策略与调度器解耦:调度器只关心“下一个待执行节点”,不关心该节点是如何生成的。

批量执行与数据落盘

批量执行的核心挑战是吞吐与一致性的平衡。每个 shot 的数据量可能只有几 KB,但总数可达百万级。建议采用“分块写入 + 索引文件”的方式:每完成一个扫描点,将该点的所有 shot 数据写入一个独立文件,同时在索引文件中追加该点的参数、文件路径、有效 shot 数和校验和。索引文件本身采用追加写,避免频繁重写整个文件。当某个扫描点执行失败时,索引中该点标记为“不完整”,恢复时只需重跑该点,而不必重跑整个扫描。

执行引擎还应提供“批量执行报告”,在扫描结束后汇总每个点的有效 shot 数、数据完整率和异常次数。例如,若某个点的有效 shot 数低于设定值的 95%,报告应将其标记为“可疑点”,提示实验人员检查该参数附近的仪器状态或量子比特退相干情况。

异常中断与恢复机制

异常中断的来源可分为三类:仪器层(超时、触发丢失、锁相环失锁)、数据层(shot 长度不一致、校验和错误)和系统层(进程崩溃、磁盘写满)。执行引擎应为每类异常定义明确的处理策略。仪器层异常通常可重试,但重试前必须将仪器重置到安全态,例如关闭射频输出、清空采集缓冲区、重新锁定锁相环。数据层异常应丢弃当前 shot 并记录,若连续异常超过阈值则中断该扫描点。系统层异常则需要依赖检查点恢复。

检查点的粒度建议为“扫描点级”而非“shot 级”。每完成一个扫描点,引擎将已完成点索引、当前仪器配置和随机数生成器状态写入检查点文件。恢复时,引擎读取检查点,跳过已完成点,从下一个未完成点继续执行。对于正在执行中崩溃的点,由于其数据不完整,恢复时应整点重跑。这种设计在保证数据一致性的同时,避免了 shot 级检查点带来的频繁 I/O 开销。

实践建议:在开发阶段,可以用一个“模拟仪器”替换真实硬件,模拟仪器按设定概率注入超时和触发丢失异常,用于验证恢复机制的正确性。模拟仪器的异常注入概率、恢复重试次数和检查点间隔都应作为可配置参数,便于在不同实验场景下调整。

一个可参考的执行配置示例

下面给出一个 Ramsey 扫描任务的执行配置片段,用于说明任务描述、扫描定义和恢复策略如何组织。该配置为教学示例,参数值可根据实际硬件调整。

experiment:
  id: "ramsey_q0_20250101"
  qubit: "Q0"
  waveform: "ramsey_pulse_v3"
  shots_per_point: 2000
  timeout_ms: 5000
  retry:
    max_attempts: 3
    backoff_ms: 200
  scan:
    strategy: "cartesian"
    axes:
      - name: "tau_us"
        start: 0.0
        stop: 20.0
        step: 0.5
  checkpoint:
    level: "point"
    path: "/data/ramsey_q0/checkpoint.json"
  output:
    dir: "/data/ramsey_q0/raw"
    index: "/data/ramsey_q0/index.jsonl"

执行该配置时,引擎首先申请 Q0 控制通道和采集卡资源,然后按 τ 从 0 到 20 μs 逐点执行。每个点完成后,将 2000 个 shot 写入独立文件,并在索引中追加记录。若某点连续 3 次重试仍失败,则标记该点为“失败”,继续下一个点,最终在报告中汇总失败点列表。若进程在 τ=7.5 μs 处崩溃,恢复时读取检查点,发现已完成 0 到 7.0 μs 共 15 个点,则从 τ=7.5 μs 重新开始,已完成的 15 个点不会重复执行。

从工程实现角度看,执行引擎的价值最终体现在“可观测”和“可恢复”两个维度。可观测意味着每个扫描点、每个 shot 的状态都能被追踪;可恢复意味着任何中断都不会导致已采集数据的丢失或重复。把这两点落实到任务模型、调度策略、扫描展开、数据落盘和检查点设计中,才能支撑量子实验从单次手动操作走向可重复、可批量、可自动化的测试流程。