Skip to content

Separate an ordered plan from its executable payloads

Build a typed Hybrid program, inspect its dependency graph and attach its payloads to a local execution bundle. Complete syntax and HIR and shared-state Hybrid experiments. Use the installed environment.

The declared order is Digital preparation, Analog evolution, then terminal measurement. Predict that the graph and plan preserve this order. Also predict that compiling an ordered plan alone does not run the experiment or produce counts.

Inspect the plan, then build a bundle

"""Compile a typed Hybrid program into a deterministic graph and local plan.

The graph owns dependency order; the plan owns local execution requirements.
Neither artifact executes by itself. This separation lets compiler tooling
inspect ordering, payload requirements, and diagnostics before a Backend runs.
"""

from __future__ import annotations

import json

from cascaqit import AHSProgram, AtomRegister, Circuit, HybridProgram, Waveform


def main() -> None:
    """Build a typed program and inspect its compilation artifacts."""
    digital = Circuit(1, program_id="lesson.compiler.graph.digital").h(0)
    analog = AHSProgram(
        AtomRegister.line(count=1, spacing=5.0),
        program_id="lesson.compiler.graph.analog",
    ).drive(
        rabi=Waveform.constant(0.3, duration=0.1),
        detuning=Waveform.constant(0.0, duration=0.1),
        phase=0.0,
    )
    program = (
        HybridProgram("lesson.compiler.graph")
        .digital("prepare", digital)
        .analog("evolve", analog)
        .measure_all()
    )
    compiled = program.compile()
    if compiled.graph is None or compiled.plan is None:
        raise RuntimeError([item.to_dict() for item in compiled.diagnostics])

    binding = program.execution_builder(shots=8, seed=7).build()
    if binding.bundle is None:
        raise RuntimeError([item.to_dict() for item in binding.diagnostics])

    payload = {
        "track": "compiler_engineer",
        "level": "foundation",
        "lesson": "hybrid_graph_plan",
        "facts": {
            "topological_order": list(compiled.graph.topological_order),
            "dependency_types": sorted(
                {edge.dependency_type for edge in compiled.graph.edges}
            ),
            "plan_steps": [step.kernel_kind for step in compiled.plan.steps],
            "bundle_ready": binding.bundle.execution_ready,
            "payload_kinds": [item.payload_kind for item in binding.bundle.payloads],
            "execution_ready": compiled.plan.execution_ready,
            "diagnostic_codes": [item.code for item in compiled.diagnostics],
        },
        "boundaries": {
            "hardware_execution": False,
            "cloud_execution": False,
            "network_accessed": False,
            "credentials_loaded": False,
        },
    }
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()

Download the full script

python3 examples/user/tracks/compiler_engineer/02_foundation_hybrid_graph_plan_en.py

program.compile() returns a graph and a local plan. Graph edges record requirements such as shared quantum state, resource use and timing. A topological order respects those dependencies. These edge categories do not establish a physical pulse schedule or prove that independent operations will run concurrently.

{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "bundle_ready": true,
    "dependency_types": [
      "quantum_state",
      "resource",
      "timing"
    ],
    "diagnostic_codes": [
      "HYBRID_PLAN_PAYLOAD_REQUIRED"
    ],
    "execution_ready": false,
    "payload_kinds": [
      "digital",
      "analog",
      "measurement"
    ],
    "plan_steps": [
      "digital",
      "analog",
      "measurement"
    ],
    "topological_order": [
      "block.0000.prepare",
      "block.0001.evolve",
      "block.0002.measure"
    ]
  },
  "lesson": "hybrid_graph_plan",
  "level": "foundation",
  "track": "compiler_engineer"
}

The plan's step kinds should be digital, analog, measurement. Its execution_ready remains false, with HYBRID_PLAN_PAYLOAD_REQUIRED among the diagnostics. This plan describes what local execution needs; it is not a self-contained numerical input.

The typed HybridProgram also owns the actual Circuit and AHSProgram payloads. program.execution_builder(shots=8, seed=7) attaches those payloads and the terminal measurement settings to the plan. build() returns a checked bundle, whose bundle_ready should be true and whose payload kinds match the three steps.

These two readiness values refer to different artifacts. A non-executable plan and an executable bundle can therefore coexist without contradiction. Building the bundle still performs no state evolution. Calling a runner or Backend is a separate action; this lesson stops before it.

Preserve the artifacts needed by the next stage

Artifact Use in the next stage
Dependency graph Inspect and validate ordering constraints.
Local plan Identify ordered steps, logical mappings and required payloads.
Bound bundle Supply typed numerical programs and terminal measurement settings.
Execution result Record measurements and state transitions after running.

Saving only the graph or plan does not save all the executable payloads. Conversely, attaching a payload does not make its physical parameters scientifically appropriate. Bundle readiness means its declared steps have valid payload bindings. A particular consumer can impose additional requirements, such as a terminal measurement before sampling.

Inspect a change before running

  1. Change the Analog amplitude from 0.3 to 0.6 rad/us. Compare graph order, payload content and program hash.
  2. Change the bundle's shot count from 8 to 32. Does building it create 32 measurements?
  3. Remove terminal measure_all() and inspect the plan and bundle. Then try submitting the program to LocalBackend for sampled results. Does bundle readiness guarantee that submission is valid?

The first change preserves this sequential ordering but changes the program and numerical payload. The shot count is a future execution setting; building a bundle does not create samples. Without measurement, this plan and bundle can still be built for their two evolution steps. The sampled LocalBackend path rejects them with SCALABLE_HYBRID_MEASUREMENT_BOUNDARY_INVALID. It requires one terminal measurement; bundle readiness alone does not establish that requirement. Do not silently add an assumed readout.

See local Hybrid simulation for execution interfaces. Continue with parameter projection to update plan arguments without confusing that operation with payload binding.

中文版

SDK 1.0.8a · `8b227bff`