Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.1k stars 2.34k forks source link

`BitArray.get_counts()` fails given an empty classical register #12062

Open garrison opened 6 months ago

garrison commented 6 months ago

Environment

What is happening?

BitArray is not fully tested with empty classical registers. For instance, get_counts() fails during the reshape if the output has zero bits. It appears that get_int_counts() will have the same problem, too.

How can we reproduce the issue?

import numpy as np
from qiskit.primitives.containers import BitArray

data = BitArray(np.zeros([1024, 0], dtype=np.uint8), 0)
data.get_counts()

results in

Traceback (most recent call last):
  File "/home/garrison/Qiskit/empty-creg-counts.py", line 7, in <module>
    data.get_counts()
  File "/home/garrison/serverless/.direnv/python-3.11.0/lib/python3.11/site-packages/qiskit/primitives/containers/bit_array.py", line 292, in get_counts
    return self._get_counts(loc=loc, converter=converter)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/garrison/serverless/.direnv/python-3.11.0/lib/python3.11/site-packages/qiskit/primitives/containers/bit_array.py", line 146, in _get_counts
    arr = self._array.reshape(-1, self._array.shape[-1]) if loc is None else self._array[loc]
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: cannot reshape array of size 0 into shape (0)

What should happen?

I expect a sensible result, such as {"": 1024} for get_counts() or {0: 1024} for get_int_counts().

Any suggestions?

No response

atharva-satpute commented 5 months ago

Shouldn't it return {} instead of some key-value pairs considering the fact that np.zeros([1024, 0]) is an empty array

garrison commented 5 months ago

Shouldn't it return {} instead of some key-value pairs considering the fact that np.zeros([1024, 0]) is an empty array

That array may be "empty" but it still has a shape. It just means there are 1024 instances of nothing.

Also, following my suggestion means there are fewer special cases a user must worry about; for instance, it maintains that the dict's values will sum up to the total number of shots, even if the register is empty.

ihincks commented 5 months ago

Thanks @garrison . It looks like from_samples also breaks with num_bits=0, so we'd need to fix that too for full support.