Project parameters into a plan and decide whether to reuse it¶
Bind one rotation parameter, project it into semantic block arguments, then repeat with a new value and a previous plan. Complete graphs and plans and shared parameters. Use the installed environment.
Predict two different decisions: the first projection has no previous plan to reuse, while a second compatible binding can reuse its structure. Neither decision implies that a numerical payload was bound or executed.
Inspect the projected arguments¶
"""Project one canonical bind set into a compiled Hybrid plan.
Parameter projection validates schema and target identity, applies values to a
new immutable program, and records whether recompilation is required. It does
not call a numerical kernel or Backend.
"""
from __future__ import annotations
import json
from cascaqit import Circuit, HybridProgram
from cascaqit.parameters.projection import project_parameter_bindings
def main() -> None:
"""Bind a rotation and inspect the 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_en.py
manager.bind(...) validates values against the schema and returns a binding record. project_parameter_bindings(...) checks schema and target identity, then creates new semantic block arguments and a corresponding local plan. The example binds theta=0.4 first and theta=0.6 second, passing the first projection as 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"
}
Read first_argument_value and second_argument_value, not only the input binding record. They confirm that the new values reached the projected program and plan. The original program hash remains unchanged.
The first decision is recompile because a reusable base plan is missing. This is plan construction, not a hardware compilation request. The second decision is reuse: the schema, base program and parameter targets match, and the binding does not require recompilation. Reuse still updates the argument values; it does not mean returning a plan with stale parameters.
Both plans are non-executable. payload_bound and backend_called remain false. Projection operates on semantic arguments and planning metadata; it is not a substitute for HybridProgram.bind(...) when you need numeric Circuit and Analog payloads for execution. The two interfaces serve different stages.
Check the reasons before caching a plan¶
| Change | Effect on reuse |
|---|---|
| Only a compatible bind-only value changes | The prior structure can be reused with updated argument values. |
| No prior usable plan exists | A plan must be compiled. |
| Schema, base program or target mapping changes | The previous plan cannot simply be reused. |
| The binding is marked as requiring recompilation | A new compile decision is required. |
| Binding schema or targets are invalid | Projection is blocked and reports diagnostics. |
A matching parameter name is insufficient. Units, types, ranges and target mappings are part of the parameter meaning. Inspect decision_reason and diagnostics before deciding that a cache hit is valid.
Exercise reuse and rejection¶
- Remove
previous=projectionfrom the second call. Predict its decision and argument value. - Bind
theta=1.2, outside the declared bounds. Checkbinding.bind_setand its diagnostics before calling projection. - In a local test, use
dataclasses.replaceto set the binding'sparameter_schema_hashto 64 zero characters, then project it against the original manager.
Without previous, the second decision becomes recompile, while the new argument remains 0.6. The out-of-range binding produces no valid bind set. The deliberately mismatched schema blocks projection with PARAMETER_PROJECTION_SCHEMA_MISMATCH and no plan. Do not repair a mismatch by overwriting hashes in real data; regenerate the binding from the correct schema.
See Hybrid parameters for the distinction between semantic projection and executable binding. Continue with validation and discretization to inspect how target grids change numeric controls.