NVIDIA / cuda-quantum

C++ and Python support for the CUDA Quantum programming model for heterogeneous quantum-classical workflows
https://nvidia.github.io/cuda-quantum/
Other
533 stars 186 forks source link

Specify control state #2232

Open zohimchandani opened 1 month ago

zohimchandani commented 1 month ago

Required prerequisites

Describe the feature

This is how to perform controlled operations:

import cudaq

@cudaq.kernel
def x_kernel(qubit: cudaq.qubit):
    x(qubit)

@cudaq.kernel
def kernel():

    controls = cudaq.qvector(2)
    target = cudaq.qubit()

    # Default: apply the x_kernel if controls are |1> 
    cudaq.control(x_kernel, controls, target) 

results = cudaq.sample(kernel)
print(cudaq.draw(kernel))

Currently, when the controls = 11 the target is applied.

What if I want to specify the control state for which the target is applied?

I may want to apply the target when the controls = 01 or controls = 00

See here for similar feature in qiskit.

amccaskey commented 1 month ago

You can negate the polarity for the control qubits

import cudaq 

@cudaq.kernel 
def kernel():
    q = cudaq.qvector(2)
    x.ctrl(~q[0], q[1])

print(kernel)

might have to expand out your controls qvector.

zohimchandani commented 1 month ago

Seems like providing control qubits in a list format executes but does not do the intended operation - see below:

import cudaq 

@cudaq.kernel 
def kernel():

    cq = cudaq.qvector(2)
    tq = cudaq.qubit()

    #11 control, works 
    x(cq)
    x.ctrl(cq[0], cq[1], tq)  

    #00 control, works but not in list format 
    x.ctrl(~cq[0], ~cq[1], tq)  
    x.ctrl([~cq[0], ~cq[1]], tq) #providing cq in a list DOES NOT work 

    #01 control works 
    x(cq[1])
    x.ctrl(~cq[0], cq[1], tq)  

print(cudaq.draw(kernel))
print(cudaq.sample(kernel))

If we now do the same execersie but use the cudaq.control command instead:


import cudaq 

@cudaq.kernel
def x_kernel(qubit: cudaq.qubit):
    x(qubit)

@cudaq.kernel
def kernel():

    cq = cudaq.qvector(2)
    tq = cudaq.qubit()

    # 11 control, works 
    x(cq)
    cudaq.control(x_kernel, cq, tq) 

    # 11 control passed as a list, works
    x(cq)
    cudaq.control(x_kernel, [cq[0], cq[1]], tq) 

    # 00 control, executes fine but does not do intended operation 
    cudaq.control(x_kernel, [~cq[0], ~cq[1]], tq) 

    # 01 control, executes fine but does not do intended operation 
    x(cq[1])
    cudaq.control(x_kernel, [~cq[0], cq[1]], tq) 

results = cudaq.sample(kernel)
print(results)
print(cudaq.draw(kernel))
print(cudaq.__version__)

CUDA-Q Version latest (https://github.com/NVIDIA/cuda-quantum 176f1e7df8a58c2dc3d6b1b47bf7f63b4b8d3b63)

@amccaskey can you please verify?

bettinaheim commented 1 month ago

The workaround here is to manually do the state inversion (x before and after on the appropriate qubits).

zohimchandani commented 1 month ago

This is a bug since the code executes fine but does not do the intended operation right?