Skip to content

Scan parameters and retain failed points

Use a scan to compare one program at several inputs. The unified scan entry point currently accepts HybridProgram. A purely digital experiment can use a HybridProgram containing only Digital blocks; no Analog block is required.

  1. Keep the program parameterized and list ordered points with ParameterScan.explicit(). Use ParameterScan.cartesian() for a Cartesian product.
  2. Pass the scan to LocalBackend.run(program, sweep=scan, shots=...). Do not also supply params.
  3. Read the scan Job’s result(), including aggregate status and each point’s status, bindings, result or error.
  4. Organize data by the recorded bindings and indices. Retain failures as failures instead of replacing them with zero probability.

A scan with an analytic check

The angles are −0.5, 0 and 0.5 rad. A single RY gate gives P(1) = sin²(theta/2), so the endpoints have equal probability and the middle point has probability zero.

"""Execute a deterministic parameter sweep through one Hybrid Backend path.

``ParameterScan`` expands explicit points in stable order. Every child keeps
its own bind set, seed, result, and status while the aggregate records worker
and resource planning facts.
"""

from __future__ import annotations

import json

from cascaqit import Circuit, HybridProgram, LocalBackend
from cascaqit.parameters import ParameterScan


def main() -> None:
    """Run three rotation values and inspect child results in scan order."""
    circuit = Circuit(1, program_id="lesson.hybrid.sweep.digital")
    theta = circuit.parameter("theta", lower_bound=-1.0, upper_bound=1.0)
    circuit.ry(theta, 0)
    program = (
        HybridProgram("lesson.hybrid.sweep").digital("rotate", circuit).measure_all()
    )
    scan = ParameterScan.explicit(
        scan_id="lesson.hybrid.sweep.points",
        points=tuple({"theta": value} for value in (-0.5, 0.0, 0.5)),
    )
    job = LocalBackend(seed=103).run(
        program, sweep=scan, shots=16, failure_policy="continue_on_error"
    )
    result = job.result()

    if job.status().state != "completed" or any(
        item.state != "completed" or item.result is None for item in result.items
    ):
        raise RuntimeError("The parameter sweep did not complete every point.")

    payload = {
        "track": "hybrid_researcher",
        "level": "applied",
        "lesson": "parameter_sweep",
        "facts": {
            "job_state": job.status().state,
            "item_states": [item.state for item in result.items],
            "theta_values": [item.bind_set.values["theta"] for item in result.items],
            "counts_totals": [
                sum((item.result.counts if item.result else {}).values())
                for item in result.items
            ],
            "probabilities": [
                item.result.probabilities for item in result.items if item.result
            ],
            "selected_workers": result.metadata["scan_resource_plan"][
                "selected_workers"
            ],
        },
        "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/03_applied_parameter_sweep_en.py
{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "counts_totals": [
      16,
      16,
      16
    ],
    "item_states": [
      "completed",
      "completed",
      "completed"
    ],
    "job_state": "completed",
    "probabilities": [
      {
        "0": 0.9387912809451864,
        "1": 0.061208719054813655
      },
      {
        "0": 1.0,
        "1": 0.0
      },
      {
        "0": 0.9387912809451864,
        "1": 0.061208719054813655
      }
    ],
    "selected_workers": 3,
    "theta_values": [
      -0.5,
      0.0,
      0.5
    ]
  },
  "lesson": "parameter_sweep",
  "level": "applied",
  "track": "hybrid_researcher"
}

This example uses 16 shots per point, or 48 in total. Every item_states entry should be successful and count totals should be [16, 16, 16]. Completion order does not determine parameter order. Seeds derive from the root seed and point index, so reordering points can change their samples.

Invalid input versus execution failure

Bindings are checked before child jobs start. Missing, unknown or out-of-range values reject the whole scan. continue_on_error does not bypass validation.

For failures during child execution, continue_on_error retains individual outcomes. Mixed success and failure gives partially_completed; all failures gives failed. fail_fast executes in index order and marks later unstarted points not_run after a failure.

Before a long scan, check a few points for physical range and resource use, then enable local persistence and recovery. See ParameterScan and the scan-results lesson.

中文版

SDK 1.0.8a · `8b227bff`