Expected behavior
When a QNode is configured with a shot vector such as qml.set_shots([10, 20]), its result
should preserve one independent result for each shot quantity.
The qml.set_shots documentation explicitly demonstrates this behavior:
new_circ = qml.set_shots(circuit_sample, shots=(4, 10))
result = new_circ()
a, b = result
a.shape # (4,)
b.shape # (10,)
In addition, default.clifford declares that its shots argument accepts Sequence[int].
Therefore, for [10, 20]:
qml.counts should return two dictionaries whose counts sum to 10 and 20;
qml.sample should return two arrays containing 10 and 20 samples;
qml.expval should return two independently estimated scalar values.
Actual behavior
On default.clifford, the shot partitions are not preserved:
qml.counts returns a tuple of outcome labels instead of two count dictionaries;
qml.sample returns one flattened tuple containing 30 samples;
qml.expval raises TypeError: 'numpy.float64' object is not iterable.
The same QNodes return correctly partitioned results on default.qubit.
Example output:
default.qubit
counts: ({'0': 3, '1': 7}, {'0': 8, '1': 12})
sample shapes: ((10, 1), (20, 1))
expval: (-0.2, 0.2)
default.clifford
counts: ('0', '1')
sample length: 30
expval: TypeError: 'numpy.float64' object is not iterable
The numerical values vary because these are finite-shot measurements, but their result structures
consistently differ as shown above.
Additional information
qml.set_shots correctly constructs and passes the partitioned shot configuration:
Shots([10, 20]).shot_vector
# (ShotCopies(10 shots x 1), ShotCopies(20 shots x 1))
The issue appears to be in DefaultClifford.measure_statistical. It uses only the total number of
shots:
num_shots = circuit.shots.total_shots
For Shots([10, 20]), this produces num_shots == 30. The implementation then performs a single
30-shot measurement and does not reconstruct separate results for the two shot-vector entries.
By comparison, other simulation paths explicitly check circuit.shots.has_partitioned_shots,
execute each shot partition separately, and return a tuple containing one result per partition.
Source code
import pennylane as qml
dev = qml.device("default.clifford", wires=1)
@qml.set_shots([10, 20])
@qml.qnode(dev)
def counts_circuit():
qml.Hadamard(0)
return qml.counts(wires=[0])
@qml.set_shots([10, 20])
@qml.qnode(dev)
def sample_circuit():
qml.Hadamard(0)
return qml.sample(wires=[0])
@qml.set_shots([10, 20])
@qml.qnode(dev)
def expval_circuit():
qml.Hadamard(0)
return qml.expval(qml.Z(0))
print(counts_circuit())
print(sample_circuit())
print(expval_circuit())
Tracebacks
TypeError: 'numpy.float64' object is not iterable
System information
Version: 0.45.0
Platform info: macOS
Python version: 3.13.13
Existing GitHub issues
Expected behavior
When a QNode is configured with a shot vector such as
qml.set_shots([10, 20]), its resultshould preserve one independent result for each shot quantity.
The
qml.set_shotsdocumentation explicitly demonstrates this behavior:In addition,
default.clifforddeclares that itsshotsargument acceptsSequence[int].Therefore, for
[10, 20]:qml.countsshould return two dictionaries whose counts sum to10and20;qml.sampleshould return two arrays containing10and20samples;qml.expvalshould return two independently estimated scalar values.Actual behavior
On
default.clifford, the shot partitions are not preserved:qml.countsreturns a tuple of outcome labels instead of two count dictionaries;qml.samplereturns one flattened tuple containing30samples;qml.expvalraisesTypeError: 'numpy.float64' object is not iterable.The same QNodes return correctly partitioned results on
default.qubit.Example output:
The numerical values vary because these are finite-shot measurements, but their result structures
consistently differ as shown above.
Additional information
qml.set_shotscorrectly constructs and passes the partitioned shot configuration:The issue appears to be in
DefaultClifford.measure_statistical. It uses only the total number ofshots:
For
Shots([10, 20]), this producesnum_shots == 30. The implementation then performs a single30-shot measurement and does not reconstruct separate results for the two shot-vector entries.
By comparison, other simulation paths explicitly check
circuit.shots.has_partitioned_shots,execute each shot partition separately, and return a tuple containing one result per partition.
Source code
Tracebacks
TypeError: 'numpy.float64' object is not iterableSystem information
Existing GitHub issues