qiboteam / qibo

A framework for quantum computing
https://qibo.science
Apache License 2.0
287 stars 58 forks source link

GlobalBackend() fails if qibojit isn't available #1424

Closed chmwzc closed 1 month ago

chmwzc commented 1 month ago

To Reproduce Install only qibo in a new virtual environment, then run

from qibo.hamiltonians import SymbolicHamiltonian

ham = SymbolicHamiltonian()

Error message:

[Qibo 0.2.11|ERROR|2024-08-21 04:16:20]: The 'qibojit' backends' provider is not available. Check that a Python package named 'qibojit' is installed, and it is exposing valid Qibo backends.
Traceback (most recent call last):
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/backends/__init__.py", line 224, in construct_backend
    module = import_module(provider)
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'qibojit'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/wongzc/test.py", line 6, in <module>
    ham = SymbolicHamiltonian()
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/hamiltonians/hamiltonians.py", line 332, in __init__
    self.backend = _check_backend(backend)
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/backends/__init__.py", line 192, in _check_backend
    return GlobalBackend()
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/backends/__init__.py", line 90, in __new__
    cls._instance = construct_backend(**kwargs)
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/backends/__init__.py", line 230, in construct_backend
    raise_error(
  File "/home/wongzc/miniforge3/envs/test/lib/python3.10/site-packages/qibo/config.py", line 46, in raise_error
    raise exception(message)
ValueError: The 'qibojit' backends' provider is not available. Check that a Python package named 'qibojit' is installed, and it is exposing valid Qibo backends.

From what I can see, I think the problem is here

https://github.com/qiboteam/qibo/blob/8fb9af92c8ee4049d6575571ab33edd756196f2d/src/qibo/backends/__init__.py#L88C1-L93C25

and here:

https://github.com/qiboteam/qibo/blob/8fb9af92c8ee4049d6575571ab33edd756196f2d/src/qibo/backends/__init__.py#L223C1-L236C1

The raise_error(ValueError, ...) is killing the try/except part in the for loop looking for available backends

alecandido commented 1 month ago

Yes, that's correct: the GlobalBackend.__new__ is looking for an ImportError (ModuleNotFoundError is a subclass, so it's even redundant), while construct_backend is turning it in a ValueError.

I'd propose to change it back to a generic ImportError. In this way it will be caught by GlobalBackend.__new__, and keep looking for another backend.

I can also attempt to design a (tricky) test for the CI to reproduce it (I have to somehow hijack the import mechanism, because qibojit will always be installed there).

chmwzc commented 1 month ago

I'd propose to change it back to a generic ImportError. In this way it will be caught by GlobalBackend.__new__, and keep looking for another backend.

Yeah, this is good enough, I don't see the point in hacking around too much for a small bug like this :)