跳转至

将参数投影到计划,并判断能否复用

绑定一个旋转参数,将它投影到语义程序块的参数中,再使用新值和已有计划进行第二次投影。请先完成依赖图与计划及共享参数,使用安装好的环境。

先预测两次不同的决定:第一次没有旧计划可复用;第二次绑定兼容时,可以复用结构。无论哪种决定,都不表示数值程序已经绑定或执行。

查看投影后的实际参数

"""把一组规范参数绑定投影到已编译的 Hybrid plan。

投影过程会核对参数 schema 和 target identity,把值写入新的不可变程序,并判断
能否复用现有编译结果。它只做编译期处理,不调用数值内核或 Backend。
"""

from __future__ import annotations

import json

from cascaqit import Circuit, HybridProgram
from cascaqit.parameters.projection import project_parameter_bindings


def main() -> None:
    """绑定一个 rotation,并检查 projection decision。"""
    circuit = Circuit(1, program_id="lesson.compiler.projection.digital")
    theta = circuit.parameter("theta", lower_bound=-1.0, upper_bound=1.0)
    circuit.rz(theta, 0)
    program = (
        HybridProgram("lesson.compiler.projection")
        .digital("rotate", circuit)
        .measure_all()
    )
    original_hash = program.stable_hash()
    manager = program.parameters
    binding = manager.bind({"theta": 0.4}, bind_id="bind.lesson.compiler")
    if binding.bind_set is None:
        raise RuntimeError([item.to_dict() for item in binding.diagnostics])
    projection = project_parameter_bindings(manager, program, binding.bind_set)
    if projection.program is None or projection.plan is None:
        raise RuntimeError([item.to_dict() for item in projection.diagnostics])

    next_binding = manager.bind({"theta": 0.6}, bind_id="bind.lesson.compiler.next")
    if next_binding.bind_set is None:
        raise RuntimeError([item.to_dict() for item in next_binding.diagnostics])
    reused = project_parameter_bindings(
        manager, program, next_binding.bind_set, previous=projection
    )
    if reused.program is None or reused.plan is None:
        raise RuntimeError([item.to_dict() for item in reused.diagnostics])

    payload = {
        "track": "compiler_engineer",
        "level": "applied",
        "lesson": "parameter_projection",
        "facts": {
            "decision": projection.decision,
            "first_argument_value": projection.program.blocks[0].arguments[0].value,
            "second_decision": reused.decision,
            "second_argument_value": reused.plan.steps[0].argument_bindings[0].value,
            "original_unchanged": original_hash == program.stable_hash(),
            "payload_bound": projection.metadata["payload_bound"],
            "bound_value": projection.bind_set.values["theta"],
            "schema_hash_matches": projection.schema_hash
            == manager.schema.stable_hash(),
            "execution_ready": projection.plan.execution_ready,
            "diagnostic_codes": [item.code for item in projection.diagnostics],
            "backend_called": projection.metadata["backend_called"],
        },
        "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/compiler_engineer/03_applied_parameter_projection_zh.py

manager.bind(...) 按参数结构检查输入,返回绑定记录。project_parameter_bindings(...) 核对结构与目标身份,再生成新的语义程序块参数和相应本地计划。示例先绑定 theta=0.4,再绑定 theta=0.6,并把第一次投影作为 previous 传入。

{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "backend_called": false,
    "bound_value": 0.4,
    "decision": "recompile",
    "diagnostic_codes": [],
    "execution_ready": false,
    "first_argument_value": 0.4,
    "original_unchanged": true,
    "payload_bound": false,
    "schema_hash_matches": true,
    "second_argument_value": 0.6,
    "second_decision": "reuse"
  },
  "lesson": "parameter_projection",
  "level": "applied",
  "track": "compiler_engineer"
}

需要查看 first_argument_value 和 second_argument_value,不能只读输入绑定记录。它们确认新值已写入投影后的程序和计划,原程序的哈希保持不变。

第一次 decision 为 recompile,因为没有可复用的基础计划。这里构造的是计划,不是在请求硬件编译。第二次为 reuse:参数结构、基础程序和目标映射一致,而且这次绑定没有要求重编译。复用时仍会更新参数值,不会沿用含旧数值的计划。

两个计划都不可直接执行,payload_bound 和 backend_called 为 false。投影处理的是语义参数和规划信息;需要可执行的数值 Circuit 或 Analog 程序时,不能拿它代替 HybridProgram.bind(...)。两个接口用于不同阶段。

缓存计划前,检查决定的依据

改动 对复用的影响
只改变兼容的、仅需绑定的参数值 可以复用结构,同时更新数值。
没有可用的旧计划 需要编译计划。
参数结构、基础程序或目标映射改变 不能直接复用原计划。
绑定声明需要重新编译 应重新作出编译决定。
绑定结构或目标无效 投影被阻止,并返回诊断。

参数同名还不够,单位、类型、范围和目标映射都是其含义的一部分。判断缓存能否使用时,应检查 decision_reason 和诊断。

练习复用与拒绝

  1. 从第二次调用中去掉 previous=projection,预测决定和参数值。
  2. 绑定越界值 theta=1.2,投影前先检查 binding.bind_set 及诊断。
  3. 在本地测试中,用 dataclasses.replace 把绑定记录的 parameter_schema_hash 改为 64 个零,再对原管理器发起投影。

不传旧计划时,第二次决定变为 recompile,参数仍是 0.6。越界绑定不会产生有效的绑定记录。故意不匹配的结构哈希会以 PARAMETER_PROJECTION_SCHEMA_MISMATCH 阻止投影,不返回计划。实际数据出现不匹配时,应从正确的结构重新绑定,不能靠覆盖哈希修补。

Hybrid 参数指南说明了语义投影与可执行绑定的区别。下一课通过校验与离散化观察目标网格如何改变数值控制。

English version

SDK 1.0.8a · `6eff6362`