issue with if condition after mid circuit measurement
Closed this issue · 1 comments
marwafar commented
Required prerequisites
- Consult the security policy. If reporting a security vulnerability, do not report the bug using this form. Use the process described in the policy to report the issue.
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker to verify that this hasn't already been reported. +1 or comment there if it has.
- If possible, make a PR with a failing test to give us a starting point to work on!
Describe the bug
If I run example 1, it will work and print the register a
. However, if I run example 2, it will not print the register a
Steps to reproduce the bug
Example 1:
import cudaq
@cudaq.kernel
def kernel_break():
ancilla_a=cudaq.qubit()
ancilla_b=cudaq.qubit()
q=cudaq.qubit()
h(ancilla_a)
h(ancilla_b)
x(q)
aux_1=mz(ancilla_a)
aux_2=mz(ancilla_b)
if aux_1==0:
if aux_2==0:
x.ctrl(ancilla_a,q)
a=mz(q)
count=cudaq.sample(kernel_break,shots_count=1000)
print(count)
Example 2:
import cudaq
@cudaq.kernel
def kernel_break():
ancilla_a=cudaq.qubit()
ancilla_b=cudaq.qubit()
q=cudaq.qubit()
h(ancilla_a)
h(ancilla_b)
x(q)
aux_1=mz(ancilla_a)
aux_2=mz(ancilla_b)
if aux_1==0 and aux_2==0:
#if aux_2==0:
x.ctrl(ancilla_a,q)
a=mz(q)
count=cudaq.sample(kernel_break,shots_count=1000)
print(count)
Expected behavior
if aux_1==0:
if aux_2==0:
......
and
if aux_1==0 and axu_2==0:
....
I expect the two if statement should work.
Is this a regression? If it is, put the last known working version (or commit) here.
Not a regression
Environment
- CUDA Quantum version: latest
- Python version: 3.10
- C++ compiler:
- Operating system: linux
Suggestions
No response
schweitzpgi commented
Doing some triage, it looks like the and
operator is lowering to correct code initially. But something is going sideways after that.
func.func @__nvqpp__mlirgen__kernel_break() attributes {"cudaq-entrypoint"} {
%false = arith.constant false
%c0_i64 = arith.constant 0 : i64
%0 = quake.alloca !quake.ref
%1 = quake.alloca !quake.ref
%2 = quake.alloca !quake.ref
quake.h %0 : (!quake.ref) -> ()
quake.h %1 : (!quake.ref) -> ()
quake.x %2 : (!quake.ref) -> ()
%measOut = quake.mz %0 name "aux_1" : (!quake.ref) -> !quake.measure
%3 = quake.discriminate %measOut : (!quake.measure) -> i1
%measOut_0 = quake.mz %1 name "aux_2" : (!quake.ref) -> !quake.measure
%4 = quake.discriminate %measOut_0 : (!quake.measure) -> i1
%5 = cc.cast unsigned %3 : (i1) -> i64
%6 = arith.cmpi eq, %5, %c0_i64 : i64
%7 = arith.cmpi eq, %6, %false : i1
%8 = cc.if(%7) -> i1 {
cc.continue %false : i1
} else {
%9 = cc.cast unsigned %4 : (i1) -> i64
%10 = arith.cmpi eq, %9, %c0_i64 : i64
cc.continue %10 : i1
}
cc.if(%8) {
quake.x [%0] %2 : (!quake.ref, !quake.ref) -> ()
%measOut_1 = quake.mz %2 name "a" : (!quake.ref) -> !quake.measure
}
return
}