Required prerequisites
Describe the bug
An if condition: return guard inside a @cudaq.kernel compiles without
warning but has no effect: the operations after it execute regardless of
the condition. This produces silently wrong circuits rather than an
error.
It is easy to miss in testing: guards whose guarded code consists of loops
over zero-trip ranges appear to work (the loops do nothing for exactly the
inputs the guard was for), so a kernel can carry dead guards through an
entire test suite. We found it porting a C++ device kernel whose
if steps == 0: return was masked by for _ in range(steps), while its
unsupported-order guard executed a wrong product formula instead of the
documented no-op.
(Related but distinct: #1657 is about return None with a declared return
type; this issue is bare return control flow in void kernels being
dropped.)
Steps to reproduce the bug
import cudaq
cudaq.set_target("qpp-cpu")
@cudaq.kernel
def guarded(skip: int):
q = cudaq.qvector(1)
if skip == 1:
return
x(q[0])
print(cudaq.sample(guarded, 0)) # { 1:1000 } (expected)
print(cudaq.sample(guarded, 1)) # { 1:1000 } (expected { 0:1000 })
Also reproduces with multi-clause conditions
(if a != 1 and a != 2: return) and with multiple sequential guards.
Expected behavior
Either honor return control flow in void kernels, or — if early return
is intentionally unsupported — reject it with a compile error. Silent
acceptance is the worst of both: the common C++ device-kernel idiom
"invalid runtime inputs are no-ops via early return" ports over as a
silently wrong circuit.
Is this a regression? If it is, put the last known working version (or commit) here.
Not a regression
Environment
- CUDA-Q built from source at commit
0be565550f4c23affdcbed9e4eaec38d2d0915e6
- Python 3.11.x, target
qpp-cpu (library mode)
- AlmaLinux 8.10, x86_64
All reproducers below were executed and verified against this build.
Suggestions
Workaround we use: restructure kernel bodies as a single positively-guarded
if-block (valid = ... then if valid: <entire body>).
Required prerequisites
Describe the bug
An
if condition: returnguard inside a@cudaq.kernelcompiles withoutwarning but has no effect: the operations after it execute regardless of
the condition. This produces silently wrong circuits rather than an
error.
It is easy to miss in testing: guards whose guarded code consists of loops
over zero-trip ranges appear to work (the loops do nothing for exactly the
inputs the guard was for), so a kernel can carry dead guards through an
entire test suite. We found it porting a C++ device kernel whose
if steps == 0: returnwas masked byfor _ in range(steps), while itsunsupported-order guard executed a wrong product formula instead of the
documented no-op.
(Related but distinct: #1657 is about
return Nonewith a declared returntype; this issue is bare
returncontrol flow in void kernels beingdropped.)
Steps to reproduce the bug
Also reproduces with multi-clause conditions
(
if a != 1 and a != 2: return) and with multiple sequential guards.Expected behavior
Either honor
returncontrol flow in void kernels, or — if early returnis intentionally unsupported — reject it with a compile error. Silent
acceptance is the worst of both: the common C++ device-kernel idiom
"invalid runtime inputs are no-ops via early return" ports over as a
silently wrong circuit.
Is this a regression? If it is, put the last known working version (or commit) here.
Not a regression
Environment
0be565550f4c23affdcbed9e4eaec38d2d0915e6qpp-cpu(library mode)All reproducers below were executed and verified against this build.
Suggestions
Workaround we use: restructure kernel bodies as a single positively-guarded
if-block (
valid = ...thenif valid: <entire body>).