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

UnknownApiError on get_qc("2q-noisy-qvm") call #1762

Closed cosenal closed 2 months ago

cosenal commented 3 months ago

Pre-Report Checklist

Issue Description

I am in a Python environment with Cirq and pyquil==3.5.4. This is the latest possible version of pyquil supported by cirq-rigetti at the moment, until this PR gets merged.

I spin up QVM & quilc servers from the Docker images (see commands below).

When I run get_qc("2q-noisy-qvm") I get an UnknownApiError.

Is pyquil v3 still compatible with the QVM?

How to Reproduce

Code Snippet

from pyquil import get_qc
get_qc("2q-noisy-qvm")

Error Output

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm_client.py:280, in QVMClient._parse_error(res)
    279 try:
--> 280     body = res.json()
    281 except JSONDecodeError:

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/httpx/_models.py:756, in Response.json(self, **kwargs)
    755         return jsonlib.loads(self.content.decode(encoding), **kwargs)
--> 756 return jsonlib.loads(self.text, **kwargs)

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    343 if (cls is None and object_hook is None and
    344         parse_int is None and parse_float is None and
    345         parse_constant is None and object_pairs_hook is None and not kw):
--> 346     return _default_decoder.decode(s)
    347 if cls is None:

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
    333 """Return the Python representation of ``s`` (a ``str`` instance
    334 containing a JSON document).
    335
    336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338 end = _w(s, end).end()

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
    354 except StopIteration as err:
--> 355     raise JSONDecodeError("Expecting value", s, err.value) from None
    356 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

UnknownApiError                           Traceback (most recent call last)
Cell In[1], line 1
----> 1 from pyquil import get_qc; get_qc("2q-noisy-qvm")

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_quantum_computer.py:822, in get_qc(***failed resolving arguments***)
    820     if qvm_type is None:
    821         raise ValueError("Please name a valid quantum_processor or run as a QVM")
--> 822     return _get_unrestricted_qvm(
    823         client_configuration=client_configuration,
    824         name=name,
    825         noisy=noisy,
    826         n_qubits=n_qubits,
    827         qvm_type=qvm_type,
    828         compiler_timeout=compiler_timeout,
    829         execution_timeout=execution_timeout,
    830     )
    832 # 3. Check for "9q-square" qvm
    833 if prefix == "9q-square":

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_quantum_computer.py:669, in _get_unrestricted_qvm(client_configuration, name, noisy, n_qubits, qvm_type, compiler_timeout, execution_timeout)
    654 """
    655 A qvm with a fully-connected topology.
    656
   (...)
    666 :return: A pre-configured QuantumComputer
    667 """
    668 topology = nx.complete_graph(n_qubits)
--> 669 return _get_qvm_with_topology(
    670     client_configuration=client_configuration,
    671     name=name,
    672     topology=topology,
    673     noisy=noisy,
    674     qvm_type=qvm_type,
    675     compiler_timeout=compiler_timeout,
    676     execution_timeout=execution_timeout,
    677 )

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_quantum_computer.py:598, in _get_qvm_with_topology(client_configuration, name, topology, noisy, qvm_type, compiler_timeout, execution_timeout)
    596 else:
    597     noise_model = None
--> 598 return _get_qvm_qc(
    599     client_configuration=client_configuration,
    600     name=name,
    601     qvm_type=qvm_type,
    602     quantum_processor=quantum_processor,
    603     noise_model=noise_model,
    604     compiler_timeout=compiler_timeout,
    605     execution_timeout=execution_timeout,
    606 )

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_quantum_computer.py:551, in _get_qvm_qc(client_configuration, name, qvm_type, quantum_processor, compiler_timeout, execution_timeout, noise_model)
    525 def _get_qvm_qc(
    526     *,
    527     client_configuration: QCSClientConfiguration,
   (...)
    533     noise_model: Optional[NoiseModel],
    534 ) -> QuantumComputer:
    535     """Construct a QuantumComputer backed by a QVM.
    536
    537     This is a minimal wrapper over the QuantumComputer, QVM, and QVMCompiler constructors.
   (...)
    546     :return: A QuantumComputer backed by a QVM with the above options.
    547     """
    549     return QuantumComputer(
    550         name=name,
--> 551         qam=_get_qvm_or_pyqvm(
    552             client_configuration=client_configuration,
    553             qvm_type=qvm_type,
    554             noise_model=noise_model,
    555             quantum_processor=quantum_processor,
    556             execution_timeout=execution_timeout,
    557         ),
    558         compiler=QVMCompiler(
    559             quantum_processor=quantum_processor,
    560             timeout=compiler_timeout,
    561             client_configuration=client_configuration,
    562         ),
    563     )

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_quantum_computer.py:517, in _get_qvm_or_pyqvm(client_configuration, qvm_type, noise_model, quantum_processor, execution_timeout)
    508 def _get_qvm_or_pyqvm(
    509     *,
    510     client_configuration: QCSClientConfiguration,
   (...)
    514     execution_timeout: float,
    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

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm.py:116, in QVM.__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()

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm.py:120, in QVM.connect(self)
    118 def connect(self) -> None:
    119     try:
--> 120         version = self.get_version_info()
    121         check_qvm_version(version)
    122     except ConnectionError:

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm.py:175, in QVM.get_version_info(self)
    169 def get_version_info(self) -> str:
    170     """
    171     Return version information for the QVM.
    172
    173     :return: String with version information
    174     """
--> 175     return self._qvm_client.get_version()

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm_client.py:176, in QVMClient.get_version(self)
    172 def get_version(self) -> str:
    173     """
    174     Get version info for QVM server.
    175     """
--> 176     return self._post_json({"type": "version"}).text.split()[0]

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm_client.py:261, in QVMClient._post_json(self, json)
    259     response = http.post("/", json=json)
    260     if response.status_code >= 400:
--> 261         raise self._parse_error(response)
    262 return response

File /opt/miniconda3/envs/mitiqenv/lib/python3.11/site-packages/pyquil/api/_qvm_client.py:282, in QVMClient._parse_error(res)
    280     body = res.json()
    281 except JSONDecodeError:
--> 282     raise UnknownApiError(res.text)
    284 if "error_type" not in body:
    285     raise UnknownApiError(str(body))

UnknownApiError:

Environment Context

Operating System: macOS 14.3.1 (23D60)

Python Version (python -V): Python 3.11.8

Quilc Version (quilc --version): 1.26.0 [7aef642]

Version comes from:

docker run --rm -idt -p 5555:5555 rigetti/quilc -R
docker exec -it <container_id> bash
quilc --version

QVM Version (qvm --version): 1.17.2 [266c11e]

Version comes from:

docker run --rm -idt -p 5000:5000 rigetti/qvm -S
docker exec -it <container_id> bash
qvm --version

Python Environment Details (pip freeze or conda list): It's basically a fresh environment for https://github.com/unitaryfund/mitiq

accessible-pygments==0.0.4
alabaster==0.7.16
amazon-braket-default-simulator==1.20.6
amazon-braket-schemas==1.20.2
amazon-braket-sdk==1.69.1
antlr4-python3-runtime==4.9.2
anyio==4.3.0
appdirs==1.4.4
appnope==0.1.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
async-lru==2.0.4
attrs==21.4.0
autograd==1.6.2
autoray==0.6.9
Babel==2.14.0
backoff==2.2.1
beautifulsoup4==4.12.3
bleach==6.1.0
boltons==23.1.1
boto3==1.34.61
botocore==1.34.61
bqskit==1.0.4
bqskitrs==0.4.1
cachetools==5.3.3
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
cirq==1.1.0
cirq-aqt==1.1.0
cirq-core==1.1.0
cirq-ft==1.3.0
cirq-google==1.1.0
cirq-ionq==1.1.0
cirq-pasqal==1.1.0
cirq-rigetti==1.1.0
cirq-web==1.1.0
click==8.1.7
cloudpickle==2.2.1
cma==3.3.0
comm==0.2.2
contourpy==1.2.0
coverage==7.4.3
cryptography==42.0.5
cycler==0.12.1
dask==2022.12.1
debugpy==1.8.1
decorator==5.1.1
defusedxml==0.7.1
Deprecated==1.2.14
deprecation==2.1.0
dill==0.3.8
distributed==2022.12.1
docutils==0.20.1
duet==0.2.9
execnet==2.0.2
executing==2.0.1
fastjsonschema==2.19.1
fonttools==4.49.0
fqdn==1.5.1
fsspec==2024.2.0
future==1.0.0
google-api-core==1.34.1
google-auth==2.28.2
googleapis-common-protos==1.63.0
graphviz==0.20.1
grpcio==1.62.1
grpcio-status==1.48.2
h11==0.14.0
h5py==3.10.0
httpcore==0.16.3
httpx==0.23.3
hyperopt==0.2.7
ibm-cloud-sdk-core==3.18.0
ibm-platform-services==0.48.0
idna==3.6
imagesize==1.4.1
importlib_metadata==7.0.2
iniconfig==2.0.0
ipykernel==6.29.4
ipython==8.22.2
ipywidgets==8.1.2
iso8601==1.1.0
isoduration==20.11.0
jedi==0.19.1
Jinja2==3.1.3
jmespath==1.0.1
joblib==1.3.2
json5==0.9.24
jsonpointer==2.4
jsonschema==4.17.3
jsonschema-specifications==2023.12.1
jupyter-cache==1.0.0
jupyter-events==0.10.0
jupyter-lsp==2.2.4
jupyter_client==8.6.1
jupyter_core==5.7.2
jupyter_server==2.13.0
jupyter_server_terminals==0.5.3
jupyterlab==4.0.12
jupyterlab_pygments==0.3.0
jupyterlab_server==2.25.4
jupyterlab_widgets==3.0.10
jupytext==1.16.1
kiwisolver==1.4.5
lark==0.11.3
lark-parser==0.12.0
latexcodec==3.0.0
locket==1.0.0
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib==3.8.1
matplotlib-inline==0.1.6
mdit-py-plugins==0.4.0
mdurl==0.1.2
mistune==3.0.2
-e git+https://github.com/unitaryfund/mitiq.git@97de1a31a33814cd259ce6cf3f2b93f87659f9e4#egg=mitiq
mpmath==1.3.0
msgpack==1.0.8
mypy==1.0.0
mypy-extensions==1.0.0
myst-nb==1.0.0
myst-parser==2.0.0
nbclient==0.10.0
nbconvert==7.16.2
nbformat==5.10.2
nbsphinx==0.9.3
nest-asyncio==1.6.0
networkx==2.8.8
notebook_shim==0.2.4
numpy==1.23.5
openfermion==1.6.1
openfermionpyscf==0.5
openpulse==0.5.0
openqasm3==0.5.0
opt-einsum==3.3.0
oqpy==0.3.5
overrides==7.7.0
packaging==23.2
pandas==2.1.3
pandocfilters==1.5.1
parso==0.8.3
partd==1.4.1
pbr==6.0.0
PennyLane==0.35.1
PennyLane-qiskit==0.35.1
PennyLane_Lightning==0.35.1
pexpect==4.9.0
pillow==10.2.0
pipdeptree==2.16.2
platformdirs==4.2.0
pluggy==1.4.0
ply==3.11
prometheus_client==0.20.0
prompt-toolkit==3.0.43
proto-plus==1.23.0
protobuf==3.20.3
psutil==5.9.8
ptyprocess==0.7.0
PubChemPy==1.0.4
pure-eval==0.2.2
py4j==0.10.9.7
pyasn1==0.5.1
pyasn1-modules==0.3.0
pybtex==0.24.0
pybtex-docutils==1.0.3
pycparser==2.21
pydantic==1.10.14
pydata-sphinx-theme==0.15.2
Pygments==2.17.2
PyJWT==2.8.0
pyparsing==3.1.2
pyquil==3.5.4
pyrsistent==0.20.0
pyscf==2.5.0
pyspnego==0.10.2
pytest==8.0.0
pytest-cov==5.0.0
pytest-xdist==3.0.2
python-dateutil==2.9.0.post0
python-json-logger==2.0.7
python-rapidjson==1.16
pytket==1.25.0
pytz==2024.1
PyYAML==6.0.1
pyzmq==25.1.2
qcs-api-client==0.21.6
qcs-sdk-python==0.17.1
qibo==0.2.4
qiskit==0.45.3
qiskit-aer==0.13.3
qiskit-ibm-provider==0.10.0
qiskit-ibm-runtime==0.20.0
qiskit-terra==0.45.3
quil==0.6.6
qutip==4.7.5
qwasm==1.0.1
referencing==0.34.0
requests==2.31.0
requests-ntlm==1.2.0
retrying==1.3.4
rfc3339==6.2
rfc3339-validator==0.1.4
rfc3986==1.5.0
rfc3986-validator==0.1.1
rpcq==3.11.0
rpds-py==0.18.0
rsa==4.9
ruamel.yaml==0.18.6
ruamel.yaml.clib==0.2.8
ruff==0.3.1
rustworkx==0.14.2
s3transfer==0.10.0
scipy==1.11.4
seaborn==0.13.0
semantic-version==2.10.0
Send2Trash==1.8.2
six==1.16.0
sniffio==1.3.1
snowballstemmer==2.2.0
sortedcontainers==2.4.0
soupsieve==2.5
Sphinx==7.2.6
sphinx-autodoc-typehints==2.0.0
sphinx-copybutton==0.5.2
sphinx-gallery==0.15.0
sphinxcontrib-applehelp==1.0.8
sphinxcontrib-bibtex==2.6.2
sphinxcontrib-devhelp==1.0.6
sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
SQLAlchemy==2.0.28
stack-data==0.6.3
stevedore==5.2.0
stim==1.13.0
stimcirq==1.13.0
symengine==0.11.0
sympy==1.12
tabulate==0.9.0
tblib==3.0.0
tenacity==8.2.3
terminado==0.18.1
threadpoolctl==3.3.0
tinycss2==1.2.1
toml==0.10.2
toolz==0.12.1
tornado==6.4
tqdm==4.66.2
traitlets==5.14.2
types-Deprecated==1.2.9.20240311
types-pkg-resources==0.1.3
types-python-dateutil==2.8.19.20240311
types-retry==0.9.9.4
types-tabulate==0.9.0.20240106
typing_extensions==4.10.0
tzdata==2024.1
uri-template==1.3.0
urllib3==1.26.18
wcwidth==0.2.13
webcolors==1.13
webencodings==0.5.1
websocket-client==1.7.0
websockets==12.0
widgetsnbextension==4.0.10
wrapt==1.16.0
zict==3.0.0
zipp==3.18.0
cosenal commented 2 months ago

Closing as not an issue.

Tl;dr: I fell victim of this breaking change from Changelog.

I am running QVM on a port different than the default 5000, because of https://github.com/rigetti/pyquil/issues/1653. I was doing this by overriding the QVM url via the env variable QCS_SETTINGS_APPLICATIONS_QVM_URL mentioned here. The thing is.. this env variable used to have a different name (i.e., QCS_SETTINGS_APPLICATIONS_PYQUIL_QVM_URL) in pyQuil v3, which is the version I am using.

Snippet of working code from ipython:

In [2]: %env QCS_SETTINGS_APPLICATIONS_PYQUIL_QVM_URL=http://127.0.0.1:5001
env: QCS_SETTINGS_APPLICATIONS_PYQUIL_QVM_URL=http://127.0.0.1:5001

In [3]: from pyquil import get_qc
   ...: get_qc("2q-noisy-qvm")
Out[3]: QuantumComputer[name="2q-noisy-qvm"]