feat: add automatic RF switching as a qblox backend compiler pass

(asked AI to generate a feature description, and can confirm that what it wrote is correct)

Auto RF Switch Dressing — Feature Description

What it does

When auto_rf_switch: True is set in QbloxCompilerOptions, the compilation pass auto_rf_switch_dressing automatically inserts RFSwitchToggle operations around microwave pulses. This gates the RF switch open only when needed, rather than leaving it always on.

RF Switch window placement

  • Each MW pulse gets an RF switch window that starts ramp_buffer before the pulse and ends ramp_buffer after it (default ramp_buffer = 20 ns).
  • If the pulse starts at t=0 (no room before), the window starts at t=0 and only the post-buffer is added.
  • The t0 offset on a pulse is accounted for when calculating the window boundaries.
  • ramp_buffer is configurable via auto_rf_switch_ramp_buffer in compiler options.

Window merging

  • Adjacent RF switch windows are merged into a single RFSwitchToggle when the gap between consecutive pulses is ≤ 2 * ramp_buffer.
  • If the gap is > 2 * ramp_buffer, two separate RFSwitchToggle operations are created.
  • The merge boundary is inclusive (gap == 2 * ramp_buffer → merged; gap == 2 * ramp_buffer + ε → separate).

Supported pulse types on MW ports

  • Regular MW pulses (e.g. SquarePulse on a :mw port): detected and windowed directly.
  • Stitched pulses via VoltageOffset: a non-zero VoltageOffset followed by a zero VoltageOffset on a :mw port is treated as a pulse window from the first event to the second. These windows participate in the same merging logic as regular pulses.

Sub-schedule support

  • MW pulses inside nested sub-schedules are discovered recursively, with their absolute times computed relative to the global (root) schedule timeline.
  • All RFSwitchToggle operations are inserted on the root schedule only — never inside a sub-schedule. This prevents the sub-schedule's duration from being extended, which would cause timing problems.
  • Cross-sub-schedule merging works: if a pulse at the end of one sub-schedule and a pulse at the start of the next sub-schedule are within 2 * ramp_buffer of each other globally, their windows are merged into a single RF switch.

What is NOT supported / explicitly excluded

  • Non-MW ports (e.g. flux ports like q0:fl): SquarePulse or VoltageOffset on flux/baseband ports are completely ignored — no RF switch is inserted.
  • Unclosed VoltageOffset windows: a non-zero VoltageOffset with no subsequent zero VoltageOffset on the same port is silently ignored (no RF switch generated).
  • VoltageOffset-only zero events: a zero-valued VoltageOffset with no preceding non-zero event produces no RF switch.
  • RFSwitchToggle operations themselves: already-existing RF switch toggles are not re-processed or double-counted when collecting pulses.
  • Disabled by default: the pass is a no-op unless auto_rf_switch: True is explicitly set. If compiler_options is absent from the hardware config, the pass is also skipped entirely.

Merge checklist

See also merge request guidelines

  • Merge request has been reviewed (in-depth by a knowledgeable contributor), and is approved by a project maintainer.
  • New code is covered by unit tests (or N/A).
  • New code is documented and docstrings use numpydoc format (or N/A).
  • New functionality: considered making private instead of extending public API (or N/A).
  • Public API changed: added @deprecated and entry in deprecated code suggestions (or N/A).
  • Newly added/adjusted documentation and docstrings render properly (or N/A).
  • Pipeline fix or dependency update: post in #software-for-developers channel to merge main back in or update local packages (or N/A).
  • Tested on hardware (or N/A).
  • CHANGELOG.md for breaking changes and AUTHORS.md have been updated (or N/A).
  • Update Hardware backends documentation if backend interface change or N/A
  • Check whether performance is significantly affected by looking at the Performance metrics results.
  • Windows tests in CI pipeline pass (manually triggered by maintainers before merging).
    • Maintainers do not hit Auto-merge, we need to actively check as manual tests do not block pipeline

For reference, the issues workflow is described in the contribution guidelines.

Edited by Robert Sokolewicz

Merge request reports

Loading