Skip to content

Bind values before running a program

Declare parameters when you want to reuse a circuit or pulse structure while changing angles or amplitudes. Declare them through the Circuit or AHSProgram that uses them so types, units, bounds and usage locations stay together.

Task Entry point
Make a parameterized digital circuit executable bound = circuit.bind(values)
Bind an analog waveform or phase bound = program.bind(values)
Execute one declared program LocalBackend.run(program, params=values).result()
Share a parameter between Hybrid blocks Declare identical definitions in the blocks and let HybridProgram collect them
Execute several parameter points Use a parameter scan instead of mutating the original program in a loop

values maps parameter names to numbers. Check spelling, units and bounds. Unit labels do not convert MHz to rad/us. Shared declarations must agree on type, unit, bounds, default, expression and compilation impact; matching names alone are insufficient.

A complete binding example

This example binds an RY angle to 0.5 rad. bind() returns a new circuit while the original declaration remains symbolic.

"""Declare and bind a typed Digital rotation parameter.

Parameters remain symbolic while a circuit is reusable. ``bind`` creates a
new executable circuit, checks missing or unknown values, and preserves the
original declaration for another experiment.
"""

from __future__ import annotations

import json

from cascaqit import Circuit


def main() -> None:
    """Bind one angle and compare declaration with executable circuit."""
    declaration = Circuit(1, program_id="lesson.digital.parameter")
    theta = declaration.parameter("theta", lower_bound=-3.2, upper_bound=3.2)
    declaration.ry(theta, 0).measure_all()

    # Binding returns a separate circuit; the declaration stays symbolic.
    bound = declaration.bind({"theta": 0.5})
    result = bound.run(shots=0, seed=202, return_probabilities=True)

    payload = {
        "track": "digital_developer",
        "level": "foundation",
        "lesson": "parameter_binding",
        "facts": {
            "declaration_is_bound": declaration.is_bound,
            "bound_is_bound": bound.is_bound,
            "parameter_names": [item.name for item in bound.parameters],
            "bound_angle": bound.operations[0].arguments["theta"],
            "probability_sum": round(sum((result.probabilities or {}).values()), 12),
        },
        "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/digital_developer/02_foundation_parameter_binding_en.py
{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "bound_angle": 0.5,
    "bound_is_bound": true,
    "declaration_is_bound": false,
    "parameter_names": [
      "theta"
    ],
    "probability_sum": 1.0
  },
  "lesson": "parameter_binding",
  "level": "foundation",
  "track": "digital_developer"
}

Expect declaration_is_bound to be false, bound_is_bound true, and bound_angle 0.5. This run requests zero measurement shots and returns state probabilities, so empty counts do not indicate failure. probability_sum should equal one within numerical precision.

When binding fails

Check for missing required parameters, unknown names and values outside inclusive bounds. Derived parameters are computed from expressions; they are not independent inputs. Boolean parameters and numeric parameters are not interchangeable.

For a Hybrid conflict, correct the declarations in the source blocks. Repeating an unchanged request does not fix validation. See the shared-parameter lesson, Parameter and ParameterManager.

中文版

SDK 1.0.8a · `8b227bff`