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
487 stars 180 forks source link

[compiler bug] Python MLIR doesn't catch incorrect arguments to rotation gates #1641

Closed anthony-santana closed 2 months ago

anthony-santana commented 4 months ago

Required prerequisites

Describe the bug

In python MLIR, we aren't catching when a user calls rotation gates with incorrect arguments.

Steps to reproduce the bug

@cudaq.kernel
def kernel():
    q = cudaq.qubit()
    # Examples of things we can get away with without error:
    rx(3.14)
    rx("random_argument")
    # Our regular gates do throw an error like this:
    # x("random_argument") 

print(kernel)

result = cudaq.sample(kernel)
print(result)

Expected behavior

Expect an error similar to the conventional gates, such as:

cudaq.kernel.ast_bridge.CompilerError: test.py:37: error: quantum operation x on incorrect quantum type <TYPENAME>.
         (offending source -> <VALUE>)

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

Not a regression

Environment

Suggestions

No response

anthony-santana commented 4 months ago

I do also think the general error message could use some improvement. Something that mentions function arguments. E.g

cudaq.kernel.ast_bridge.CompilerError: test.py:37: error: quantum operation <OP_NAME> received incorrect argument type <TYPENAME>.
         (offending source -> <VALUE>)
amccaskey commented 4 months ago

@anthony-santana you could add the following

diff --git a/python/cudaq/kernel/ast_bridge.py b/python/cudaq/kernel/ast_bridge.py
index 412174880..649e5618e 100644
--- a/python/cudaq/kernel/ast_bridge.py
+++ b/python/cudaq/kernel/ast_bridge.py
@@ -1365,11 +1365,16 @@ class PyASTBridge(ast.NodeVisitor):

             if node.func.id in ["rx", "ry", "rz", "r1"]:
                 numValues = len(self.valueStack)
+                if numValues < 2:
+                    self.emitFatalError(f'Invalid number of arguments ({numValues}) passed to {node.func.id} (requires at least 2 arguments)', node)
                 qubitTargets = [self.popValue() for _ in range(numValues - 1)]
                 qubitTargets.reverse()
                 param = self.popValue()
                 if IntegerType.isinstance(param.type):
                     param = arith.SIToFPOp(self.getFloatType(), param).result
+                if not F64Type.isinstance(param.type):
+                    self.emitFatalError('rotational parameter must be a float.', node)
+                self.checkControlAndTargetTypes([], qubitTargets)
                 self.__applyQuantumOperation(node.func.id, [param],
                                              qubitTargets)
                 return
sacpis commented 2 months ago

Wondering if this fix would also cover the following issue https://github.com/NVIDIA/cuda-quantum/issues/670

khalatepradnya commented 2 months ago

Wondering if this fix would also cover the following issue #670

It's not the same. I think it was fixed by something else since the issue was filed. I will add that as a test as well.