Skip to content

Fix passing a whole qvector to multi-qubit custom operations in C++ frontend - #4990

Open
arcusbuilds wants to merge 1 commit into
NVIDIA:mainfrom
arcusbuilds:fix/4961-custom-op-qvector-targets
Open

Fix passing a whole qvector to multi-qubit custom operations in C++ frontend#4990
arcusbuilds wants to merge 1 commit into
NVIDIA:mainfrom
arcusbuilds:fix/4961-custom-op-qvector-targets

Conversation

@arcusbuilds

@arcusbuilds arcusbuilds commented Jul 24, 2026

Copy link
Copy Markdown

Fixes #4961.

Passing a qvector to a multi-qubit custom operation crashed nvq++ deep in the verifier
with Invalid matrix size, required 2^N * 2^N for N-qubit operation. The lowering treated
a lone veq argument as a broadcast target no matter what arity the operation had.

Per the review discussion, broadcasting only makes sense for single-qubit custom
operations, so the broadcast path is now gated on arity 1. Any other argument shape
(a qvector where individual qubits are required, or the wrong number of qubits) is
rejected at compile time with custom operation requires N individual qubit argument(s).

Testing: a new AST-error test (custom_op_invalid_argument.cpp) covers too many and too
few qubits, a whole qvector (the reproducer from the issue), and a qubit followed by a
qvector. Existing custom-operation tests pass unchanged.

@copy-pr-bot

copy-pr-bot Bot commented Jul 24, 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.

@github-actions github-actions Bot added c++ bridge CUDA-Q in C++ bridge to MLIR compiler core compiler labels Jul 24, 2026

@schweitzpgi schweitzpgi left a comment

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.

Broadcasting is only supported for operations on a single qubit because it can be inferred from the types.

We do not allow calling ops with more than one qubit with qvectors that will get magically expanded in C++. If the op takes $n$ arguments (arity $n$) then the programmer has to correctly pass $n$ arguments that are well-typed qubits.

@schweitzpgi

schweitzpgi commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

The desired fix is to disallow qvectors to be passed as argument to custom ops unless the op's arity is 1. The user should get a compiler error on such input (instead of the broken behavior obviously). Any arity $> 1$ should be explicitly enumerated.

@arcusbuilds

Copy link
Copy Markdown
Author

@schweitzpgi, Thanks, that makes sense. A qvector can't really be type-checked anyway when its size is only known at runtime. I'll update the PR to keep the single-qubit broadcast, reject qvectors for anything with arity > 1 with a clear compile error, and fix up the tests to match.

@arcusbuilds
arcusbuilds requested a review from schweitzpgi July 24, 2026 21:55
Passing a whole qvector to a custom operation with more than one target
was accepted by the C++ frontend and only failed later, during
verification, with an opaque error.

Broadcasting is only defined for single-qubit operations, where the
target count can be inferred from the types. For an operation of arity
greater than one, require the caller to enumerate the target qubits
explicitly and emit a compile-time diagnostic otherwise. The check
covers controlled invocations as well, so a qvector target is rejected
whether or not a control modifier is present; control arguments
themselves may still be a qvector.

Signed-off-by: Srijan Keshri <srijankeshri007@gmail.com>
@arcusbuilds
arcusbuilds force-pushed the fix/4961-custom-op-qvector-targets branch from 953bb2e to 983a808 Compare July 30, 2026 16:33
@arcusbuilds

Copy link
Copy Markdown
Author

@schweitzpgi Following up on this one. Is anything still needed from me? I think the workflows need a maintainer to approve a run before CI can report, but happy to make changes if something else is expected.

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

Labels

c++ bridge CUDA-Q in C++ bridge to MLIR compiler core compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Passing a qvector to a multi-qubit custom operation fails

2 participants