When cudaq.observe is called with a list or 2D-array argument -> triggers the broadcast path -> it crashes with a TypeError on any REST-based QPU target (including emulated targets like oqc and quantinuum):
TypeError: __init__(): incompatible function arguments. The following argument types are supported:
1. __init__(self, arg0: float, arg1: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SpinOperator, arg2: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SampleResult, /) -> None
2. __init__(self, arg0: float, arg1: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SpinOperator, arg2: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SampleResult, /) -> None
3. __init__(self, arg0: float, arg1: object, arg2: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SampleResult, /) -> None
Invoked with types: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.ObserveResult, NoneType, cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SpinOperator, cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.SampleResult
The crash occurs because ctx.getExpectationValue() returns None for all REST QPU backends, and __broadcastObserve in observe.py) passes it directly to ObserveResult without a None fallback.
Steps to reproduce
import cudaq
from cudaq import spin
import numpy as np
from typing import List
cudaq.set_target("oqc", emulate=True) # or "quantinuum", emulate=True
qubit_count = 5
sample_count = 10
parameters = np.random.default_rng(13).uniform(low=0, high=1,
size=(sample_count, qubit_count))
@cudaq.kernel
def kernel(qubit_count: int, parameters: List[float]):
qvector = cudaq.qvector(qubit_count)
for i in range(qubit_count - 1):
rx(parameters[i], qvector[i])
results = cudaq.observe(kernel, spin.z(0), [qubit_count] * sample_count, parameters)
print([r.expectation() for r in results])
Root cause
REST QPU backends (OQC, Quantinuum, IonQ, etc.) (BaseRemoteRESTQPU) never write to executionContext->expectationValue, i.e., None.
The non-broadcast path in observe.py already handles this correctly (computes the expectation value from the sample counts). __broadcastObserve is missing the same fallback mechanism.
When
cudaq.observeis called with a list or 2D-array argument -> triggers the broadcast path -> it crashes with aTypeErroron any REST-based QPU target (including emulated targets likeoqcandquantinuum):The crash occurs because
ctx.getExpectationValue()returnsNonefor all REST QPU backends, and__broadcastObserveinobserve.py) passes it directly toObserveResultwithout aNonefallback.Steps to reproduce
Root cause
REST QPU backends (OQC, Quantinuum, IonQ, etc.) (
BaseRemoteRESTQPU) never write toexecutionContext->expectationValue, i.e.,None.The non-broadcast path in
observe.pyalready handles this correctly (computes the expectation value from the sample counts).__broadcastObserveis missing the same fallback mechanism.