The CPU fallback for the computation of probabilities is not working.
Run the following code. (replace 31 with the maximum number of qubits that your GPU supports)
import qibo
from qibo.models import Circuit
from qibo import gates
c = Circuit(31)
for i in range(31):
c.add(gates.H(i))
c.add(gates.M(i))
result = c(nshots=1000).frequencies()
Qibo 0.1.7rc1.dev0|INFO|2021-11-18 11:17:16]: Using qibojit backend on /GPU:0
[Qibo 0.1.7rc1.dev0|WARNING|2021-11-18 11:17:19]: Falling back to CPU because the GPU is out-of-memory.
Traceback (most recent call last):
File ".../qibo/backends/abstract.py", line 110, in cpu_fallback
return func(*args)
File ".../qibo/core/gates.py", line 270, in calculate_probs
probs = state.probabilities(measurement_gate=self)
File ".../qibo/core/states.py", line 75, in wrapper
return func(self, qubits=set(qubits)) # pylint: disable=E1102
File ".../qibo/core/states.py", line 82, in probabilities
state = K.reshape(K.square(K.abs(self.tensor)), self.nqubits * (2,))
File ".../qibo/backends/numpy.py", line 152, in abs
return self.backend.abs(x)
File "cupy/_core/_kernel.pyx", line 1161, in cupy._core._kernel.ufunc.__call__
File "cupy/_core/_kernel.pyx", line 586, in cupy._core._kernel._get_out_args
File "cupy/_core/core.pyx", line 2540, in cupy._core.core._ndarray_init
File "cupy/_core/core.pyx", line 184, in cupy._core.core.ndarray._init_fast
File "cupy/cuda/memory.pyx", line 718, in cupy.cuda.memory.alloc
File "cupy/cuda/memory.pyx", line 1395, in cupy.cuda.memory.MemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1416, in cupy.cuda.memory.MemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1096, in cupy.cuda.memory.SingleDeviceMemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1117, in cupy.cuda.memory.SingleDeviceMemoryPool._malloc
File "cupy/cuda/memory.pyx", line 1355, in cupy.cuda.memory.SingleDeviceMemoryPool._try_malloc
cupy.cuda.memory.OutOfMemoryError: Out of memory allocating 17,179,869,184 bytes (allocated so far: 34,359,759,872 bytes).
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../script.py", line 9, in <module>
result = c(nshots=1000).frequencies()
File ".../qibo/abstractions/circuit.py", line 712, in __call__
return self.execute(initial_state=initial_state, nshots=nshots)
File ".../qibo/core/circuit.py", line 309, in execute
state.measure(self.measurement_gate, nshots, self.measurement_tuples)
File ".../qibo/core/states.py", line 86, in measure
self.measurements = gate(self, nshots)
File ".../qibo/core/gates.py", line 294, in __call__
self.result = self.measure(state, nshots)
File ".../qibo/core/gates.py", line 275, in measure
probs = K.cpu_fallback(calculate_probs)
File ".../qibo/backends/abstract.py", line 116, in cpu_fallback
return func(*args)
File ".../qibo/core/gates.py", line 270, in calculate_probs
probs = state.probabilities(measurement_gate=self)
File ".../qibo/core/states.py", line 75, in wrapper
return func(self, qubits=set(qubits)) # pylint: disable=E1102
File ".../qibo/core/states.py", line 82, in probabilities
state = K.reshape(K.square(K.abs(self.tensor)), self.nqubits * (2,))
File ".../qibo/backends/numpy.py", line 152, in abs
return self.backend.abs(x)
File "cupy/_core/core.pyx", line 1500, in cupy._core.core.ndarray.__array_ufunc__
File "cupy/_core/_kernel.pyx", line 1161, in cupy._core._kernel.ufunc.__call__
File "cupy/_core/_kernel.pyx", line 586, in cupy._core._kernel._get_out_args
File "cupy/_core/core.pyx", line 2540, in cupy._core.core._ndarray_init
File "cupy/_core/core.pyx", line 184, in cupy._core.core.ndarray._init_fast
File "cupy/cuda/memory.pyx", line 718, in cupy.cuda.memory.alloc
File "cupy/cuda/memory.pyx", line 1395, in cupy.cuda.memory.MemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1416, in cupy.cuda.memory.MemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1096, in cupy.cuda.memory.SingleDeviceMemoryPool.malloc
File "cupy/cuda/memory.pyx", line 1117, in cupy.cuda.memory.SingleDeviceMemoryPool._malloc
File "cupy/cuda/memory.pyx", line 1355, in cupy.cuda.memory.SingleDeviceMemoryPool._try_malloc
cupy.cuda.memory.OutOfMemoryError: Out of memory allocating 17,179,869,184 bytes (allocated so far: 34,359,759,872 bytes).
The first OOM error from CuPy is expected: in order to compute the probabilities, we compute and store K.square(K.abs())
of the state vector, so the required memory is increased by 50%.
Then, the CPU fallback is activated, the engine is changed from CuPy to Numba, and so self.backend
is changed from cp
to np
.
However, K.abs
of File ".../src/qibo/core/states.py", line 82, in probabilities
still calls CuPy, which raises OOM error again.
My guess is that K.abs(state)
calls CuPy regardless of self.backend
being cp
or np
because the state (self.tensor
in qibo/core/states.py
) is still a CuPy array.
However, I tried to remove that behavior by setting NUMPY_EXPERIMENTAL_ARRAY_FUNCTION=0
but it didn't change anything.