[C++] Add more tests for control vs. broadcast#4657
Conversation
Fixes NVIDIA#913 Signed-off-by: Arnav Nagzirkar <113314200+arnavnagzirkar@users.noreply.github.com>
| // CHECK: cc.loop while | ||
| // CHECK: quake.x %{{.*}} : (!quake.ref) -> () |
There was a problem hiding this comment.
These CHECK lines need to be expanded. They are too heavily pruned.
| // CHECK: cc.loop while | ||
| // CHECK: quake.x %{{.*}} : (!quake.ref) -> () | ||
| // CHECK-NOT: quake.x [% |
| // CHECK: quake.x [%{{.*}}, %{{.*}}] %{{.*}} : (!quake.ref, !quake.ref, !quake.ref) -> () | ||
| // CHECK: return |
There was a problem hiding this comment.
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.
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>
|
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. |
Summary
Root Cause
There were no dedicated tests documenting how
cudaq-quakehandles the fullrange of broadcast vs. control semantics for quantum gates. The existing
ctrl_vector.cpptest covered theh(veq, qubit)/x(veq, qubit)implicit-control pattern but did not cover:
x(q[0], q[1], q[2]))x(q))x<cudaq::ctrl>(q)with a single register stillbroadcasts (the compiler ignores the ctrl modifier for a single VeqType
operand — see
buildOpinConvertExpr.cpplines 283-299)x<cudaq::ctrl>(q[0], q[1], q[2]))with a register of controls
Change Made
New file:
cudaq/test/AST-Quake/ctrl_broadcast.cppEight FileCheck tests covering the full broadcast/control matrix:
x(q[0], q[1], q[2])quake.xopsx(q)cc.loop+quake.xx<cudaq::ctrl>(q)cc.loop+quake.xx<cudaq::ctrl>(q[0],q[1],q[2])quake.x [ctrl0,ctrl1] tgtx(veq, qubit)quake.x [veq] qubitswap(q[0], q[1])quake.swap ref0, ref1swap<cudaq::ctrl>(q[0],q[1],q[2])quake.swap [ctrl] tgt0, tgt1swap(ctrl_reg, src, tgt)quake.swap [veq] src, tgtKey behavioral insight documented: the two-arg
swap(QuantumRegister, qubit, qubit)overload has no
modtemplate 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
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.