rigetti / pyquil

A Python library for quantum programming using Quil.
http://docs.rigetti.com
Apache License 2.0
1.39k stars 341 forks source link

Verification of qvm and quilc on Ubuntu 20.04 fails due to libffi.so.6 no longer used #1434

Open fieldofnodes opened 2 years ago

fieldofnodes commented 2 years ago

Pre-Report Checklist

Issue Description

I have tried to verify that qvm and quilc work correctly in Ubuntu 20.04, however I get en error

 qvm --version
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                    {10005C04F3}>:
  Error opening shared object "libffi.so.6":
  libffi.so.6: cannot open shared object file: No such file or directory.

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005C04F3}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SIMPLE-ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:
  ~A." {1000E05543}> #<unused argument> :QUIT T)
1: (SB-DEBUG::RUN-HOOK *INVOKE-DEBUGGER-HOOK* #<SIMPLE-ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:
  ~A." {1000E05543}>)
2: (INVOKE-DEBUGGER #<SIMPLE-ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:
  ~A." {1000E05543}>)
3: (ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:
  ~A." "libffi.so.6" "libffi.so.6: cannot open shared object file: No such file or directory")
4: (SB-SYS:DLOPEN-OR-LOSE #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"libffi.so.6" :NAMESTRING "libffi.so.6" :HANDLE NIL :DONT-SAVE NIL))
5: (SB-ALIEN::TRY-REOPEN-SHARED-OBJECT #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"libffi.so.6" :NAMESTRING "libffi.so.6" :HANDLE NIL :DONT-SAVE NIL))
6: (SB-SYS:REOPEN-SHARED-OBJECTS)
7: (SB-IMPL::FOREIGN-REINIT)
8: (SB-IMPL::REINIT)
9: ((FLET SB-UNIX::BODY :IN SAVE-LISP-AND-DIE))
10: ((FLET "WITHOUT-INTERRUPTS-BODY-14" :IN SAVE-LISP-AND-DIE))
11: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))

unhandled condition in --disable-debugger mode, quitting

Insert a short description of the bug here, along with what you expected the behavior to be.

Thanks for helping us improve pyQuil! 🙂

How to Reproduce

If useful, provide a numbered list of the steps that result in the error.

Otherwise, just fill out the "Code Snippet" and "Error Output" sections below.

Code Snippet

Include a snippet of the pyQuil code that produces the error here.

Error Output

Additionally, please copy and paste the output of the above code here.

Environment Context

Operating System: Ubuntu 20.04

Python Version (python -V): Python 3.9.7

Quilc Version (quilc --version):

QVM Version (qvm --version):

forest-sdk-2.23.0-linux-deb

Python Environment Details (pip freeze or conda list):

Copy and paste the output of `pip freeze` or `conda list` here.
dbanty commented 2 years ago

Thanks for reporting the issue @fieldofnodes! I think in order to fix this we're going to have to recompile and redistribute the binaries (FYI @notmgsk and @kalzoo).

For now, as a workaround, you can run via Docker by following these instructions

fieldofnodes commented 2 years ago

Cheers. That was an my list to do next.

fieldofnodes commented 2 years ago

@dbanty Will, you update this issue once the binaries have been recompiled and redistributed?

fieldofnodes commented 2 years ago

@dbanty I am having some issues with the docker image rigetti/forest which I pulled from Forest Docker Link. There is a connect error occurring.

From the Forest Docker Image page with instructions to

docker run --rm -it rigetti/forest

Which I do, though I need to use sudo first, then go to run

from pyquil import get_qc, Program
from pyquil.gates import H, CNOT, MEASURE
from pyquil.quilbase import Declare

program = Program(
    Declare("ro", "BIT", 2),
    H(0),
    CNOT(0, 1),
    MEASURE(0, ("ro", 0)),
    MEASURE(1, ("ro", 1)),
).wrap_in_numshots_loop(10)

qc = get_qc("2q-qvm")

qc.run(qc.compile(program)).readout_data.get("ro")

I do this and get this error

fieldofnodes@fieldofnodes:~$ sudo docker run --rm -it rigetti/forest
=========================================
=   WELCOME TO THE RIGETTI FOREST SDK   =
=========================================
Copyright (c) 2016-2019 Rigetti Computing

Python 3.7.12 (default, Feb  8 2022, 05:37:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.31.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pyquil import get_qc, Program
   ...: from pyquil.gates import H, CNOT, MEASURE
   ...: from pyquil.quilbase import Declare
   ...: 
   ...: program = Program(
   ...:     Declare("ro", "BIT", 2),
   ...:     H(0),
   ...:     CNOT(0, 1),
   ...:     MEASURE(0, ("ro", 0)),
   ...:     MEASURE(1, ("ro", 1)),
   ...: ).wrap_in_numshots_loop(10)
   ...: 
   ...: qc = get_qc("2q-qvm")
   ...: 
   ...: qc.run(qc.compile(program)).readout_data.get("ro")
---------------------------------------------------------------------------
ConnectError                              Traceback (most recent call last)
/usr/local/lib/python3.7/site-packages/httpx/_exceptions.py in map_exceptions(mapping, **kwargs)
    338     try:
--> 339         yield
    340     except Exception as exc:

/usr/local/lib/python3.7/site-packages/httpx/_client.py in _send_single_request(self, request, timeout)
    858                 stream=request.stream,  # type: ignore
--> 859                 ext={"timeout": timeout.as_dict()},
    860             )

/usr/local/lib/python3.7/site-packages/httpcore/_sync/connection_pool.py in request(self, method, url, headers, stream, ext)
    200                 response = connection.request(
--> 201                     method, url, headers=headers, stream=stream, ext=ext
    202                 )

/usr/local/lib/python3.7/site-packages/httpcore/_sync/connection.py in request(self, method, url, headers, stream, ext)
     86                     )
---> 87                     self.socket = self._open_socket(timeout)
     88                 self._create_connection(self.socket)

/usr/local/lib/python3.7/site-packages/httpcore/_sync/connection.py in _open_socket(self, timeout)
    112                     timeout,
--> 113                     local_address=self.local_address,
    114                 )

/usr/local/lib/python3.7/site-packages/httpcore/_backends/sync.py in open_tcp_stream(self, hostname, port, ssl_context, timeout, local_address)
    143                 )
--> 144             return SyncSocketStream(sock=sock)
    145 

/usr/local/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
    129             try:
--> 130                 self.gen.throw(type, value, traceback)
    131             except StopIteration as exc:

/usr/local/lib/python3.7/site-packages/httpcore/_exceptions.py in map_exceptions(map)
     11             if isinstance(exc, from_exc):
---> 12                 raise to_exc(exc) from None
     13         raise

ConnectError: [Errno 111] Connection refused

The above exception was the direct cause of the following exception:

ConnectError                              Traceback (most recent call last)
<ipython-input-1-eebbb5154ff1> in <module>
     11 ).wrap_in_numshots_loop(10)
     12 
---> 13 qc = get_qc("2q-qvm")
     14 
     15 qc.run(qc.compile(program)).readout_data.get("ro")

/usr/local/lib/python3.7/site-packages/pyquil/api/_quantum_computer.py in get_qc(***failed resolving arguments***)
    825             qvm_type=qvm_type,
    826             compiler_timeout=compiler_timeout,
--> 827             execution_timeout=execution_timeout,
    828         )
    829 

/usr/local/lib/python3.7/site-packages/pyquil/api/_quantum_computer.py in _get_unrestricted_qvm(client_configuration, name, noisy, n_qubits, qvm_type, compiler_timeout, execution_timeout)
    674         qvm_type=qvm_type,
    675         compiler_timeout=compiler_timeout,
--> 676         execution_timeout=execution_timeout,
    677     )
    678 

/usr/local/lib/python3.7/site-packages/pyquil/api/_quantum_computer.py in _get_qvm_with_topology(client_configuration, name, topology, noisy, qvm_type, compiler_timeout, execution_timeout)
    603         noise_model=noise_model,
    604         compiler_timeout=compiler_timeout,
--> 605         execution_timeout=execution_timeout,
    606     )
    607 

/usr/local/lib/python3.7/site-packages/pyquil/api/_quantum_computer.py in _get_qvm_qc(client_configuration, name, qvm_type, quantum_processor, compiler_timeout, execution_timeout, noise_model)
    554             noise_model=noise_model,
    555             quantum_processor=quantum_processor,
--> 556             execution_timeout=execution_timeout,
    557         ),
    558         compiler=QVMCompiler(

/usr/local/lib/python3.7/site-packages/pyquil/api/_quantum_computer.py in _get_qvm_or_pyqvm(client_configuration, qvm_type, noise_model, quantum_processor, execution_timeout)
    515 ) -> Union[QVM, PyQVM]:
    516     if qvm_type == "qvm":
--> 517         return QVM(noise_model=noise_model, timeout=execution_timeout, client_configuration=client_configuration)
    518     elif qvm_type == "pyqvm":
    519         assert quantum_processor is not None

/usr/local/lib/python3.7/site-packages/pyquil/api/_qvm.py in __init__(self, noise_model, gate_noise, measurement_noise, random_seed, timeout, client_configuration)
    114         client_configuration = client_configuration or QCSClientConfiguration.load()
    115         self._qvm_client = QVMClient(client_configuration=client_configuration, request_timeout=timeout)
--> 116         self.connect()
    117 
    118     def connect(self) -> None:

/usr/local/lib/python3.7/site-packages/pyquil/api/_qvm.py in connect(self)
    118     def connect(self) -> None:
    119         try:
--> 120             version = self.get_version_info()
    121             check_qvm_version(version)
    122         except ConnectionError:

/usr/local/lib/python3.7/site-packages/pyquil/api/_qvm.py in get_version_info(self)
    173         :return: String with version information
    174         """
--> 175         return self._qvm_client.get_version()
    176 
    177 

/usr/local/lib/python3.7/site-packages/pyquil/api/_qvm_client.py in get_version(self)
    174         Get version info for QVM server.
    175         """
--> 176         return self._post_json({"type": "version"}).text.split()[0]
    177 
    178     def run_program(self, request: RunProgramRequest) -> RunProgramResponse:

/usr/local/lib/python3.7/site-packages/pyquil/api/_qvm_client.py in _post_json(self, json)
    257     def _post_json(self, json: Dict[str, Any]) -> httpx.Response:
    258         with self._http_client() as http:  # type: httpx.Client
--> 259             response = http.post("/", json=json)
    260             if response.status_code >= 400:
    261                 raise self._parse_error(response)

/usr/local/lib/python3.7/site-packages/httpx/_client.py in post(self, url, content, data, files, json, params, headers, cookies, auth, allow_redirects, timeout)
    995             auth=auth,
    996             allow_redirects=allow_redirects,
--> 997             timeout=timeout,
    998         )
    999 

/usr/local/lib/python3.7/site-packages/httpx/_client.py in request(self, method, url, content, data, files, json, params, headers, cookies, auth, allow_redirects, timeout)
    720         )
    721         return self.send(
--> 722             request, auth=auth, allow_redirects=allow_redirects, timeout=timeout
    723         )
    724 

/usr/local/lib/python3.7/site-packages/httpx/_client.py in send(self, request, stream, auth, allow_redirects, timeout)
    756             timeout=timeout,
    757             allow_redirects=allow_redirects,
--> 758             history=[],
    759         )
    760 

/usr/local/lib/python3.7/site-packages/httpx/_client.py in _send_handling_auth(self, request, auth, timeout, allow_redirects, history)
    793                 timeout=timeout,
    794                 allow_redirects=allow_redirects,
--> 795                 history=history,
    796             )
    797             try:

/usr/local/lib/python3.7/site-packages/httpx/_client.py in _send_handling_redirects(self, request, timeout, allow_redirects, history)
    821                 )
    822 
--> 823             response = self._send_single_request(request, timeout)
    824             response.history = list(history)
    825 

/usr/local/lib/python3.7/site-packages/httpx/_client.py in _send_single_request(self, request, timeout)
    857                 headers=request.headers.raw,
    858                 stream=request.stream,  # type: ignore
--> 859                 ext={"timeout": timeout.as_dict()},
    860             )
    861 

/usr/local/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
    128                 value = type()
    129             try:
--> 130                 self.gen.throw(type, value, traceback)
    131             except StopIteration as exc:
    132                 # Suppress StopIteration *unless* it's the same exception that

/usr/local/lib/python3.7/site-packages/httpx/_exceptions.py in map_exceptions(mapping, **kwargs)
    354 
    355         message = str(exc)
--> 356         raise mapped_exc(message, **kwargs) from exc  # type: ignore
    357 
    358 

ConnectError: [Errno 111] Connection refused

In [2]: 

My system information

Linux fieldofnodes 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

With hardware information

  description: Notebook
    product: ROG Strix G513IE_G513IE
    vendor: ASUSTeK COMPUTER INC.
    version: 1.0
    serial: MBNRKD031787448
    width: 64 bits
    capabilities: smbios-3.2.0 dmi-3.2.0 smp vsyscall32
    configuration: boot=normal chassis=notebook family=ROG Strix
dbanty commented 2 years ago

Thanks @fieldofnodes, it looks like it's having the same issue in the image as you were on Ubuntu. I think the fix is the switch the base to an older version of Debian for now (until we recompile qvm). I'll try to have that done for you today.

dbanty commented 2 years ago

@fieldofnodes I got a fix into a prerelease, so you should be able to run docker run -it rigetti/forest:rc (the rc tag) and have that work for now. Let me know if it still causes you any trouble.

fieldofnodes commented 2 years ago

@dbanty Brilliant!! I just did this, and BOOM -- works.

Digest: sha256:9f05185cf529349282f2fe2670bebb669fca5a5fa98b76d228dbd0bbd88aa95c
Status: Downloaded newer image for rigetti/forest:rc
=========================================
=   WELCOME TO THE RIGETTI FOREST SDK   =
=========================================
Copyright (c) 2016-2019 Rigetti Computing

Python 3.7.13 (default, Apr 14 2022, 06:46:01) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.32.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pyquil import get_qc, Program
   ...: from pyquil.gates import H, CNOT, MEASURE
   ...: from pyquil.quilbase import Declare
   ...: 
   ...: program = Program(
   ...:     Declare("ro", "BIT", 2),
   ...:     H(0),
   ...:     CNOT(0, 1),
   ...:     MEASURE(0, ("ro", 0)),
   ...:     MEASURE(1, ("ro", 1)),
   ...: ).wrap_in_numshots_loop(10)
   ...: 
   ...: qc = get_qc("2q-qvm")
   ...: 
   ...: qc.run(qc.compile(program)).readout_data.get("ro")
Out[1]: 
array([[0, 0],
       [1, 1],
       [0, 0],
       [0, 0],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [1, 1],
       [0, 0]])

In [2]: 

Thanks for the swift feedback.

kalzoo commented 2 years ago

@dbanty ftw!

fieldofnodes commented 2 years ago

Out of curiosity, do I close this issue or someone from Rigetti will do this?

dbanty commented 2 years ago

We'll wait to close this one until we also get a new binary release for newer versions of Debian, since that's the underlying issue. I view pinning our Docker image as a workaround.

fieldofnodes commented 1 year ago

The libffi.so.6 issue is also asked on stack exchange (https://stackoverflow.com/questions/61875869/ubuntu-20-04-upgrade-python-missing-libffi-so-6)

I just installed it following the direction on the link and now i have both libffi.so.6 and libffi.so.7 installed and qvm and quilc work fine.

petergthatsme commented 4 months ago

this still seems to be a problem; I tried both the "full" forest-sdk install and the "barebones" one, and both try to link against libffi.so.6. From the description on the help page here, I thought that the full install would actually come with this lib (or link to it statically), so the problem of it missing in my OS (ubuntu 22.04) should only be with the 'barebones' - but i see the same thing with both.

If it's expected that this does not work on recent (i.e. two-year old) OSes it could be good to update documentation, to let people know. thx.