CUDA-Q Interface#

The CUDA-Q interface is provided by the separate package qrisp-cudaq. Install it with pip install "qrisp[cudaq]".

cudaq_kernel(func: Callable | None = None, execution_mode: Literal['run', 'sample'] = 'run', register_size: int | None = None) → cudaq.kernel.kernel_decorator.PyKernelDecorator[source]#

Decorator that compiles a Qrisp function to a native CUDA-Q kernel.

Mirrors @cudaq.kernel exactly: the decorated name is bound directly to a PyKernelDecorator โ€” compiled eagerly at decoration time โ€” and can be passed to cudaq.run without calling it first.

For functions with parameters, each parameter must carry a type annotation, just as @cudaq.kernel requires them. The annotation is used to generate a correctly-typed dummy value for Jaspr tracing, producing parametric MLIR whose @main function retains the parameter in its signature. The resulting kernel accepts runtime arguments via cudaq.run or direct calls.

Supported annotations:

  • int, float, bool โ€” scalar values passed directly.

  • FixedShapeNDArray [dtype, size] โ€” fixed-size NumPy array. Specify the element type (float, int, or bool) and the number of elements. At runtime, pass a numpy.ndarray of the matching dtype and length.

Parameters:
funccallable, optional

A Qrisp function that can be traced with make_jaspr. Parameters, if any, must be annotated with int, float, bool, or FixedShapeNDArray. The function may return int, float, bool, or a tuple of those types. When None, the decorator is used in its parameterised form (@cudaq_kernel(execution_mode=...)).

execution_modeLiteral[โ€œrunโ€, โ€œsampleโ€], optional
  • "run" (default) โ€” compile the kernel for use with cudaq.run; measurement results are returned as classical values per shot.

  • "sample" โ€” compile the kernel for use with cudaq.sample; measurements are collected by the runtime across all shots and returned as a SampleResult histogram.

register_sizeint, optional

If specified, the kernel will be compiled with a fixed register size. Only applicable when execution_mode is "sample".

Returns:
PyKernelDecorator

A compiled, callable CUDA-Q kernel bound to the decorated name.

Raises:
RuntimeError

If a parameter is missing a type annotation or has an unsupported annotation type.

RuntimeError

If tracing or compiling the function to CUDA-Q fails. This can happen when the kernel uses unsupported traced array arithmetic.

Examples

No-argument kernel โ€” identical usage to @cudaq.kernel:

import cudaq
from qrisp import QuantumVariable, cx, h, measure
from qrisp_cudaq import cudaq_kernel

@cudaq_kernel
def bell():
    qv = QuantumVariable(2)
    h(qv[0])
    cx(qv[0], qv[1])
    return measure(qv)

print(bell())                            # single-shot, e.g. 0 or 3
print(cudaq.run(bell, shots_count=100))  # multi-shot, no () needed

Multiple returns are supported; they are returned as a single tuple:

import cudaq
from qrisp import QuantumFloat, h, measure
from qrisp_cudaq import cudaq_kernel

@cudaq_kernel
def main():
    a = QuantumFloat(3)
    b = QuantumFloat(2)
    a[:] = 3
    h(b)
    a += b
    return measure(a), measure(b)

print(cudaq.run(main, shots_count=5))
# e.g. [(3.0, 0.0), (3.0, 0.0), (5.0, 2.0), (5.0, 2.0), (6.0, 3.0)]

Parameterised kernel with scalar and array annotations:

import cudaq
import numpy as np
from qrisp import QuantumFloat, h, ry, measure
from qrisp_cudaq import cudaq_kernel, FixedShapeNDArray

@cudaq_kernel
def circuit(k: int):
    qv = QuantumFloat(2)
    h(qv[0])
    return measure(qv[0]) + k

print(circuit(3))
print(cudaq.run(circuit, 3, shots_count=100))

@cudaq_kernel
def circuit_arr(angles: FixedShapeNDArray[float, 3]):
    qv = QuantumFloat(2)
    ry(angles[0], qv[0])
    return measure(qv[0])

angles = np.array([1.57, 0.78, 0.39])
print(circuit_arr(angles))
print(cudaq.run(circuit_arr, angles, shots_count=100))

Sample mode โ€” use @cudaq_kernel(execution_mode="sample") for cudaq.sample (void-return kernel, measurements collected by runtime):

import cudaq
from qrisp import QuantumVariable, cx, h, measure
from qrisp_cudaq import cudaq_kernel

@cudaq_kernel(execution_mode="sample")
def bell():
    qv = QuantumVariable(2)
    h(qv[0])
    cx(qv[0], qv[1])
    return measure(qv)

print(cudaq.sample(bell, shots_count=100))
class FixedShapeNDArray(dtype: type, size: int)[source]#

Type annotation for a fixed-size numpy array parameter in

@cudaq_kernel.

Mirrors the role of list[float] / list[int] in @cudaq.kernel but requires an explicit size, because JAX traces with concrete shapes. The decorator uses the element type and size to generate a correctly-typed dummy value for tracing.

Use the subscript syntax FixedShapeNDArray[dtype, size] in annotations, mirroring how Pythonโ€™s generics (e.g. list[int]) are used in type annotations, rather than calling the class directly.

Parameters:
dtypetype

Element type. Supported: float, int, bool.

sizeint

Number of elements. Must match the runtime array length.

Examples

import cudaq
import numpy as np
from qrisp import *
from qrisp_cudaq import cudaq_kernel, FixedShapeNDArray

@cudaq_kernel
def circuit(angles: FixedShapeNDArray[float, 3]):
    qv = QuantumFloat(2)
    ry(angles[0], qv[0])
    return measure(qv[0])

angles = np.array([1.57, 0.78, 0.39])
print(cudaq.run(circuit, angles, shots_count=100))