Skip to content

[C++] Add more tests for control vs. broadcast#4657

Open
arnavnagzirkar wants to merge 5 commits into
NVIDIA:mainfrom
arnavnagzirkar:fix-913
Open

[C++] Add more tests for control vs. broadcast#4657
arnavnagzirkar wants to merge 5 commits into
NVIDIA:mainfrom
arnavnagzirkar:fix-913

Conversation

@arnavnagzirkar

Copy link
Copy Markdown

Summary

Root Cause

There were no dedicated tests documenting how cudaq-quake handles the full
range of broadcast vs. control semantics for quantum gates. The existing
ctrl_vector.cpp test covered the h(veq, qubit) / x(veq, qubit) implicit-
control pattern but did not cover:

  • Broadcasting x over individually-indexed qubits (x(q[0], q[1], q[2]))
  • Broadcasting x over an entire register (x(q))
  • The surprising case where x<cudaq::ctrl>(q) with a single register still
    broadcasts (the compiler ignores the ctrl modifier for a single VeqType
    operand — see buildOp in ConvertExpr.cpp lines 283-299)
  • Multiple individual-qubit controls (x<cudaq::ctrl>(q[0], q[1], q[2]))
  • Simple swap, controlled swap with individual qubits, and controlled swap
    with a register of controls

Change Made

New file: cudaq/test/AST-Quake/ctrl_broadcast.cpp

Eight FileCheck tests covering the full broadcast/control matrix:

Kernel expression Behavior MLIR output
x(q[0], q[1], q[2]) Broadcast 3 separate quake.x ops
x(q) Broadcast loop cc.loop + quake.x
x<cudaq::ctrl>(q) Still broadcasts (ctrl ignored for single veq) cc.loop + quake.x
x<cudaq::ctrl>(q[0],q[1],q[2]) Controlled quake.x [ctrl0,ctrl1] tgt
x(veq, qubit) Implicit ctrl (default overload modifier) quake.x [veq] qubit
swap(q[0], q[1]) Simple swap quake.swap ref0, ref1
swap<cudaq::ctrl>(q[0],q[1],q[2]) Controlled swap quake.swap [ctrl] tgt0, tgt1
swap(ctrl_reg, src, tgt) Controlled swap via dedicated overload quake.swap [veq] src, tgt

Key behavioral insight documented: the two-arg swap(QuantumRegister, qubit, qubit)
overload has no mod template parameter, so it cannot take <cudaq::ctrl>
passing a register as the first argument implicitly makes it the control.

Issue

Fixes #913

Issue URL: #913

Changes

cudaq/test/AST-Quake/ctrl_broadcast.cpp | 142 ++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

Testing

  • Agent ran relevant tests during development

  • Linting checks passed

  • Changes are minimal and focused on the issue

AI Assistance Disclosure

This pull request was prepared with the assistance of AI coding tools (GitHub Copilot). The change has been read, understood, and is owned by the human contributor submitting it, who will respond to review feedback.

Fixes NVIDIA#913

Signed-off-by: Arnav Nagzirkar <113314200+arnavnagzirkar@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented Jun 3, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Comment thread cudaq/test/AST-Quake/ctrl_broadcast.cpp Outdated
Comment on lines +45 to +46
// CHECK: cc.loop while
// CHECK: quake.x %{{.*}} : (!quake.ref) -> ()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These CHECK lines need to be expanded. They are too heavily pruned.

Comment thread cudaq/test/AST-Quake/ctrl_broadcast.cpp Outdated
Comment on lines +59 to +61
// CHECK: cc.loop while
// CHECK: quake.x %{{.*}} : (!quake.ref) -> ()
// CHECK-NOT: quake.x [%

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment thread cudaq/test/AST-Quake/ctrl_broadcast.cpp Outdated
Comment on lines +74 to +75
// CHECK: quake.x [%{{.*}}, %{{.*}}] %{{.*}} : (!quake.ref, !quake.ref, !quake.ref) -> ()
// CHECK: return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And so on ... if we're going through the trouble to write tests for these cases, we should make sure that the tests themselves are robust enough to catch regressions. Dropping 90% of the operations and regex matching any possible string can cause false positives, rendering the test useless.

@schweitzpgi schweitzpgi changed the title fix: Add more tests for control vs. broadcast [C++] Add more tests for control vs. broadcast Jun 3, 2026
@schweitzpgi schweitzpgi added the testing Relates to testing label Jun 3, 2026
schweitzpgi and others added 3 commits June 3, 2026 16:04
Address review feedback: bind SSA values and capture the full broadcast loop body (veq_size, cc.loop while/do/step, extract_ref, gate, invariant) and the individual control operands so the tests catch regressions instead of matching any string.

Signed-off-by: Arnav Nagzirkar <113314200+arnavnagzirkar@users.noreply.github.com>
@arnavnagzirkar

Copy link
Copy Markdown
Author

Thanks for the review. I have expanded the three pruned check blocks so they assert the full structure instead of matching arbitrary strings.

For the two broadcast loops (broadcast_register and ctrl_broadcast_register) the checks now bind the alloca and walk the whole invariant loop: quake.veq_size on the register, the cc.loop while header with its induction variable, the arith.cmpi slt bound test, cc.condition, the do block, quake.extract_ref with the concrete (!quake.veq<4>, i64) types, the quake.x on the extracted !quake.ref, cc.continue, the step block with arith.addi, and the {invariant} attribute. The ctrl_broadcast_register case keeps the CHECK-NOT to prove no controlled form is ever emitted.

For ctrl_individual the controls and target are now bound to the specific extracted refs (q[0] and q[1] as controls, q[2] as target) rather than wildcard operands, so a regression that swapped operands or changed the control set would fail.

These mirror the structure already used by the other cases in this file and by grover.cpp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Relates to testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add more tests for control vs. broadcast

2 participants