Skip to content

Set a resource budget before scaling up

Inspect a small program’s plan before increasing sites, trajectories or concurrent scan points. The state array is only part of memory use; solver workspace, buffers and worker copies also require space.

Setting What it controls
max_memory_bytes, memory_fraction Memory budgets for planning, not operating-system isolation
dtype Amplitude precision and element size: eight bytes for complex64, sixteen for complex128
workers Scan or trajectory concurrency planning, not kernel thread count
trajectories Trajectory-estimation samples, separate from measurement shots
Probability/state return options Returned and saved data, without eliminating the state needed during evolution

A full state vector has 2^N complex entries and a density matrix 4^N. Trajectories use batches of pure states under chunking and concurrency limits. Multiplying one state’s bytes by trajectory count does not replace the actual peak-memory plan.

Inspect a real six-site plan

"""Audit resource planning and execution evidence for a Hybrid workload.

The planner evaluates method candidates before large-array allocation. The
accepted plan records state representation, Hilbert dimension, memory estimate,
workers, tolerances, and rejection reasons; execution records what was applied.
"""

from __future__ import annotations

import json

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


def main() -> None:
    """Run a six-site D-A-D workload and compare planned versus applied settings."""
    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()

Download the full script

python examples/user/tracks/hybrid_researcher/05_expert_resource_planning_en.py
{
  "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"
}

A six-site complex64 state vector occupies 512 bytes; a full density matrix occupies 32768 bytes. Neither is process peak memory. Compare state_bytes with estimated_peak_bytes, and read workers_requested alongside workers_applied. Requesting two workers does not guarantee two kernel threads on the chosen path.

When planning rejects a request, inspect candidate reason codes and estimates. Reducing sites or concurrency usually relieves state-storage pressure more than reducing shots. Compare precision before lowering dtype, and confirm the physical assumptions before switching to a blockade subspace.

This fixed-step example reports tolerance_applied as false. Follow the method and precision guide to vary time resolution or applicable adaptive tolerances. Retain the accepted resource plan and actual execution settings. One machine’s available-memory estimate is not a universal laptop requirement.

中文版

SDK 1.0.8a · `8b227bff`