跳转至

扩大实验前,先检查资源规划

运行一个六站点 Digital–Analog–Digital 程序,比较请求的设置和实际生效的设置。请先完成物理噪声,使用安装好的环境。本课保持较小的本地 CPU 模拟规模,便于检查内存估算,避免直接尝试大数组分配。

算完状态大小,还要计算工作内存

六个二能级站点的完整 Hilbert 空间维数为 2⁶ = 64。一个 complex64 振幅占八字节,因此单个状态向量占 64 × 8 = 512 bytes。完整密度矩阵有 64² 个元素,同精度下占 32768 bytes。

这些都不是实验运行所需的峰值内存。算符、求解器工作区、采样和结果缓冲区还要占用空间,并发任务或轨迹也可能需要额外副本。规划器在分配大的状态数组前估算这些部分;估算值不等于整个进程的实测内存。

"""检查 Hybrid workload 的资源规划和实际执行配置。

Planner 会在分配大型状态数组前比较候选 method。最终 plan 会给出状态表示、Hilbert
维数、内存估算、worker 数、tolerance 和拒绝原因,结果中另有实际采用的配置。
"""

from __future__ import annotations

import json

from cascaqit import (
    AHSProgram,
    AtomRegister,
    Circuit,
    HybridProgram,
    LocalBackend,
    Waveform,
)
from cascaqit.simulators import SimulationOptions


def main() -> None:
    """运行六 site D-A-D workload,并对照规划值与实际应用值。"""
    sites = 6
    analog = AHSProgram(
        AtomRegister.line(count=sites, spacing=7.0),
        program_id="lesson.hybrid.resource.analog",
    ).drive(
        rabi=Waveform.linear(0.1, 0.6, duration=0.1),
        detuning=Waveform.constant(-0.1, duration=0.1),
        phase=0.0,
    )
    program = (
        HybridProgram("lesson.hybrid.resource")
        .digital("prepare", Circuit(sites).h(0).cx(0, 1))
        .analog("evolve", analog)
        .digital("correct", Circuit(sites).rz(0.2, sites - 1))
        .measure_all()
    )
    result = (
        LocalBackend(analog_time_steps=4)
        .run(
            program,
            shots=16,
            seed=105,
            options=SimulationOptions(
                integrator="fixed_step_krylov",
                dtype="complex64",
                max_steps=4,
                workers=2,
            ),
        )
        .result()
    )
    plan = result.metadata["simulation_plan"]
    execution = result.metadata["simulation_execution_config"]

    payload = {
        "track": "hybrid_researcher",
        "level": "expert",
        "lesson": "resource_planning",
        "facts": {
            "logical_sites": plan["logical_sites"],
            "method_selected": plan["method_selected"],
            "candidate_statuses": {
                item["method"]: item["status"] for item in plan["candidates"]
            },
            "hilbert_dimension": plan["hilbert_dimension"],
            "state_bytes": plan["estimate"]["state_bytes"],
            "estimated_peak_bytes": plan["estimate"]["estimated_peak_bytes"],
            "workers_requested": plan["metadata"]["workers_requested"],
            "workers_applied": execution["workers"],
            "estimated_peak_positive": plan["estimate"]["estimated_peak_bytes"] > 0,
            "execution_dtype": execution["dtype"],
            "tolerance_applied": execution["tolerance_applied"],
            "state_bytes_returned": result.metadata["state_bytes_returned"],
        },
        "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/05_expert_resource_planning_zh.py

Digital 制备先纠缠前两个站点;Analog 时段使用全局驱动和失谐;末尾 Digital RZ 作用于最后一个站点。程序没有声明二体相互作用,不能仅凭有六个站点就将它解释为相互作用 Rydberg 阵列。

区分请求、选定和实际生效的设置

{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "candidate_statuses": {
      "density_matrix": "rejected",
      "state_vector": "selected",
      "subspace": "rejected",
      "trajectory": "rejected"
    },
    "estimated_peak_bytes": 20992,
    "estimated_peak_positive": true,
    "execution_dtype": "complex64",
    "hilbert_dimension": 64,
    "logical_sites": 6,
    "method_selected": "state_vector",
    "state_bytes": 512,
    "state_bytes_returned": false,
    "tolerance_applied": false,
    "workers_applied": 1,
    "workers_requested": 2
  },
  "lesson": "resource_planning",
  "level": "expert",
  "track": "hybrid_researcher"
}
输出字段 如何理解
method_selected 这个无噪声程序选用了 state_vector。
candidate_statuses 其他方法也经过评估;本次被拒绝,不等于 SDK 一般不支持它们。
state_bytes、estimated_peak_bytes 前者是单个状态数组大小,后者包含规划器估计的其他分配。
workers_requested、workers_applied 请求了两个工作线程,当前选定的状态向量路径实际使用一个内核工作线程。
execution_dtype 执行时使用的是 complex64。
tolerance_applied 明确选择固定步长积分后,此处为 false。
state_bytes_returned false 表示没有返回振幅,不表示演化时未分配状态。

需要了解拒绝原因时,查看 plan["candidates"] 中各项的 reason_codes。本例没有提供子空间基,因此子空间方法不可选;密度矩阵和轨迹候选要求噪声模型。规划器不会为凑出一个可用方法而自动补上噪声模型或阻塞近似。

本例明确请求 fixed_step_krylov,使用四个时间片。容差字段会被记录,但不参与自适应步长选择。增加采样次数只改变采样统计。评估演化误差时,应逐步增加时间分辨率并比较结果,或在适用时选择支持的自适应方法。数据类型也不能单独保证计算精度。

每次只改变一项资源设置

  1. 将 complex64 改为 complex128,预测并核对状态数组字节数。
  2. 将站点数从六增加到七,计算 complex64 下状态向量和完整密度矩阵的大小。
  3. 在 SimulationOptions 中加入 max_memory_bytes=1024,读取资源错误。状态向量只占 512 字节,为什么 1024 字节仍不够?
核对思路

六站点的 complex128 向量占 64 × 16 = 1024 bytes。七站点的 complex64 向量占 128 × 8 = 1024 bytes,密度矩阵占 128² × 8 = 131072 bytes。限制后的预算无法容纳工作区和缓冲区,规划器会拒绝执行。减少返回内容也不能免去演化所需的状态。

保存结果时,一起保存接受的资源计划、实际执行设置和程序。不同机器的可用内存预算可能不同,不应把一次输出的主机预算当作通用最低配置。模拟资源规划说明了规划器规则,实验设计介绍了复现记录需要包含哪些内容。

English version

SDK 1.0.8a · `6eff6362`