Feature Description
A general keep-alive mechanism for "always-on" sticky elements so they stay asserted for the whole program without a per-component manual call that will be usable by gate level users.
Problem Statement
This is a more featureful extension of a bugfix for #123.
The merged keep-alive primitive BaseQuam.twpa_keepalive() (#135) requires the user to call it once per loop iteration in a hand-written QUA program. That's fine for pulse-level users but breaks down for gate-level / circuit-compilation use cases.
For those more abstract level users who don't write bare QUA, there's no point in their code to call it. Users also shouldn't have to know a TWPA is a sticky element that decays. Finally, the bugfix manual solution adds increasing complexity to the stack. Each new always-on component adds another "remember to keep this alive" rule, with nothing enforcing it, and the list grows with the library and user base.
Proposed Solution
A registry behind one keep_sticky_alive() base method. Components opt in by declaring the elements they need re-asserted; BaseQuam collects them by walking the QUAM tree and re-asserts all of them in a single align().
# a component opts in by declaring its sticky element(s), scoped to the qubits in use:
component.keepalive_elements(qubits) -> [element names]
# BaseQuam gains one method:
keep_sticky_alive(qubits = active_qubits):
elements = collect keepalive_elements(qubits)
from every always-on component in the QUAM tree
if elements:
align(elements + channels of qubits)
# twpa_keepalive() becomes a thin alias of keep_sticky_alive()
Auto-injection per shot. Whatever generates the shot loop inserts the call once per iteration.
# near-term: a loop helper owns the for_ and injects the call
shot_loop(n_shots, qubits):
with for_(... n_shots ...):
keep_sticky_alive(qubits)
yield # user's per-shot body runs here
# long-term: the circuit->QUA compiler emits it when it builds the shot loop
with for_(shot in n_shots):
keep_sticky_alive(active_qubits)
<compiled circuit>
Alternatives Considered
Explicit manual calls as twpa_keepalive but as noted above, this is not a workable solution for gate level users.
Example Usage
Today, manual:
with for_(n, 0, n < n_avg, n + 1):
machine.twpa_keepalive([q1])
# gates / measure ...
With this feature, handwritten qua automatic:
for n in machine.shot_loop(n_avg, qubits=[q1]):
# gates / measure ... keep-alive handled automatically
With this feature, gate-level (compiler owns the loop; user writes no QUA):
results = machine.run(circuit, n_shots=1000) # keep_sticky_alive injected per shot internally
Priority
Important
Additional Context
Confirmed one call per shot is sufficient via simulation on hardware: the sticky hold carries the element through the rest of the iteration, and it holds across nested loops and conditionals, so auto-injection is a single line where the loop is emitted, with no interleaving among gates. Align must include always on elements + active qubits channels.
Checklist
Feature Description
A general keep-alive mechanism for "always-on" sticky elements so they stay asserted for the whole program without a per-component manual call that will be usable by gate level users.
Problem Statement
This is a more featureful extension of a bugfix for #123.
The merged keep-alive primitive BaseQuam.twpa_keepalive() (#135) requires the user to call it once per loop iteration in a hand-written QUA program. That's fine for pulse-level users but breaks down for gate-level / circuit-compilation use cases.
For those more abstract level users who don't write bare QUA, there's no point in their code to call it. Users also shouldn't have to know a TWPA is a sticky element that decays. Finally, the bugfix manual solution adds increasing complexity to the stack. Each new always-on component adds another "remember to keep this alive" rule, with nothing enforcing it, and the list grows with the library and user base.
Proposed Solution
A registry behind one keep_sticky_alive() base method. Components opt in by declaring the elements they need re-asserted; BaseQuam collects them by walking the QUAM tree and re-asserts all of them in a single align().
Auto-injection per shot. Whatever generates the shot loop inserts the call once per iteration.
Alternatives Considered
Explicit manual calls as twpa_keepalive but as noted above, this is not a workable solution for gate level users.
Example Usage
Today, manual:
With this feature, handwritten qua automatic:
With this feature, gate-level (compiler owns the loop; user writes no QUA):
Priority
Important
Additional Context
Confirmed one call per shot is sufficient via simulation on hardware: the sticky hold carries the element through the rest of the iteration, and it holds across nested loops and conditionals, so auto-injection is a single line where the loop is emitted, with no interleaving among gates. Align must include always on elements + active qubits channels.
Checklist