Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected behavior when kernel takes list of booleans #2262

Closed
3 of 4 tasks
jezerjojo14 opened this issue Oct 9, 2024 · 3 comments · May be fixed by #2349
Closed
3 of 4 tasks

Unexpected behavior when kernel takes list of booleans #2262

jezerjojo14 opened this issue Oct 9, 2024 · 3 comments · May be fixed by #2349
Assignees

Comments

@jezerjojo14
Copy link

jezerjojo14 commented Oct 9, 2024

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

I needed to send a list of $n$ booleans as a parameter to a kernel to specify which of $n$ qubits to apply $X$ gates on. The kernel does not throw any errors, but does not seem to be interpreting this list of booleans correctly. I'm not sure but I think it might be interpreting the list of booleans as a single integer?

Steps to reproduce the bug

This is the kernel:

import cudaq
@cudaq.kernel
def circ_test(n: int, bools: list[bool]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==False:
            x(q[j])

This is how it behaves for different examples:

print(cudaq.draw(circ_test,5,[True,True,True,True,True]))
          
q0 : ─────
     ╭───╮
q1 : ┤ x ├
     ├───┤
q2 : ┤ x ├
     ├───┤
q3 : ┤ x ├
     ├───┤
q4 : ┤ x ├
     ╰───╯


print(cudaq.draw(circ_test,5,[False,True,True,False,True]))

q0 : ─────
     ╭───╮
q1 : ┤ x ├
     ├───┤
q2 : ┤ x ├
     ├───┤
q3 : ┤ x ├
     ├───┤
q4 : ┤ x ├
     ╰───╯
print(cudaq.draw(circ_test,5,[False,False,False,False,False]))

     ╭───╮
q0 : ┤ x ├
     ├───┤
q1 : ┤ x ├
     ├───┤
q2 : ┤ x ├
     ├───┤
q3 : ┤ x ├
     ├───┤
q4 : ┤ x ├
     ╰───╯

Here's a modified kernel:

import cudaq
@cudaq.kernel
def circ_test_2(n: int, bools: list[bool]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==True:
            x(q[j])
print(cudaq.draw(circ_test_2,5,[False,False,False,False,False]))

No output

print(cudaq.draw(circ_test_2,5,[True,True,True,True,True]))

No output

print(cudaq.draw(circ_test_2,5,[False,True,False,False,True]))

No output

print(cudaq.draw(circ_test_2,5,[True,False,False,False,False]))

     ╭───╮
q0 : ┤ x ├
     ╰───╯

Expected behavior

For the first kernel, I expect an $X$ gate to be applied on the $i$-th qubit if and only if the $i$-th element of the boolean list is False. For the second kernel I expect the same but for when the $i$-th element of the boolean list is True.

Is this a regression? If it is, put the last known working version (or commit) here.

Not a regression

Environment

Suggestions

No response

@bebora
Copy link
Contributor

bebora commented Oct 10, 2024

Hi @jezerjojo14 , I tested some other variants of your code, changing the value being checked, the defined type for the list and the actual values in the list.

Boolean list, boolean comparison

import cudaq
@cudaq.kernel
def circ_test(n: int, bools: list[bool]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==True:
            x(q[j])

print(cudaq.draw(circ_test,5,[False,True,False,True,False]))

Output:
Empty
If we were to call the kernel with a list of integers, it would throw an error:

print(cudaq.draw(circ_test,5,[0,1,0,1,0]))

Output:
RuntimeError: kernel argument's element type is 'bool' but argument provided is not (argument 1, element 0, value=0, type=<class 'int'>).

Boolean list, integer comparison

import cudaq
@cudaq.kernel
def circ_test(n: int, bools: list[bool]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==1:
            x(q[j])

print(cudaq.draw(circ_test,5,[False,True,False,True,False]))

Output:
Empty

Integer list, boolean comparison

import cudaq
@cudaq.kernel
def circ_test(n: int, bools: list[int]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==True:
            x(q[j])

print(cudaq.draw(circ_test,5,[0,1,0,1,0]))

Output:

error: 'arith.cmpi' op requires all operands to have the same type
RuntimeError: Failure while executing pass pipeline.

Integer list, integer comparison

import cudaq
@cudaq.kernel
def circ_test(n: int, bools: list[int]):
    q = cudaq.qvector(n)
    for j in range(n):
        b=bools[j]
        if b==1:
            x(q[j])

print(cudaq.draw(circ_test,5,[0,1,0,1,0]))

Output:

q0 : ─────
     ╭───╮
q1 : ┤ x ├
     ╰───╯
q2 : ─────
     ╭───╮
q3 : ┤ x ├
     ╰───╯

If we were to call the kernel with a list of booleans, it would work too:

print(cudaq.draw(circ_test,5,[False,True,False,True,False]))

Output:

q0 : ─────
     ╭───╮
q1 : ┤ x ├
     ╰───╯
q2 : ─────
     ╭───╮
q3 : ┤ x ├
     ╰───╯

Takeaway

You can currently call your kernel passing a list of booleans as long as the kernel treats it as a list of integers. There is likely something wrong when using lists of booleans inside quantum kernels. A simplified version of your code where the kernel receives a bool instead of a list[bool] works fine, so the bool type is not problematic per se.

@jezerjojo14
Copy link
Author

I'm curious as to what was going wrong in the first place but this is a great solution to the problem I was facing. Thanks @bebora 👍

@schweitzpgi
Copy link
Collaborator

Fixed with #2338

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants