From 9c7f1f32e5e3b46dbe8906a143cd3e6880701770 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Wed, 2 Oct 2024 12:00:00 +0100 Subject: [PATCH] Rewrite support documentation --- qiskit/qpy/__init__.py | 25 +++++- qiskit/qpy/interface.py | 11 +-- ...qpy-symengine-compat-858970a9a1d6bc14.yaml | 87 +++++++++++-------- 3 files changed, 77 insertions(+), 46 deletions(-) diff --git a/qiskit/qpy/__init__.py b/qiskit/qpy/__init__.py index 579fbe2e587..d6928a134a8 100644 --- a/qiskit/qpy/__init__.py +++ b/qiskit/qpy/__init__.py @@ -118,10 +118,27 @@ .. note:: - When loading a QPY file generated using Qiskit 0.45.x or 0.46.x where :func:`.qpy.dump` - was called with the ``use_symengine`` argument set ``True`` these files can not be - loaded by Qiskit releases >= 1.0.0 due to API differences in the ``symengine`` library - that is used when QPY serializes :class:`.ParameterExpression` objects. + With versions of Qiskit before 1.2.3, the ``use_symengine=True`` argument to :func:`.qpy.dump` + could cause problems with backwards compatibility if there were :class:`.ParameterExpression` + objects to serialize. In particular: + + * When the loading version of Qiskit is 1.2.3 or greater, QPY files generated with any version + of Qiskit >= 0.46.0 can be loaded. If a version of Qiskit between 0.45.0 and 0.45.3 was used + to generate the files, and the non-default argument ``use_symengine=True`` was given to + :func:`.qpy.dump`, the file can only be read if the version of ``symengine`` used in the + generating environment was in the 0.11 or 0.13 series, but if the environment was created + during the support window of Qiskit 0.45, it is likely that ``symengine==0.9.2`` was used. + + * When the loading version of Qiskit is between 0.46.0 and 1.2.2 inclusive, the file can only be + read if the installed version of ``symengine`` in the loading environment matches the version + used in the generating environment. + + To recover a QPY file that fails with ``symengine`` version-related errors during a call to + :func:`.qpy.load`, first attempt to use Qiskit >= 1.2.3 to load the file. If this still fails, + it is likely because Qiskit 0.45.x was used to generate the file with ``use_symengine=True``. + In this case, use Qiskit 0.45.3 with ``symengine==0.9.2`` to load the file, and then re-export + it to QPY setting ``use_symengine=False``. The resulting file can then be loaded by any later + version of Qiskit. QPY format version history -------------------------- diff --git a/qiskit/qpy/interface.py b/qiskit/qpy/interface.py index dd9eab0809e..827857ab2b0 100644 --- a/qiskit/qpy/interface.py +++ b/qiskit/qpy/interface.py @@ -147,11 +147,12 @@ def dump( .. note:: If serializing a :class:`.QuantumCircuit` or :class:`.ScheduleBlock` that contain - :class:`.ParameterExpression` objects with version set to - :attr:`.qpy.QPY_COMPATIBILITY_VERSION` with the intent to load the payload using - a historical release of Qiskit, ensure you set the ``use_symengine`` flag to - ``False``. The symengine versions used between the Qiskit 1.0 major version boundary - are not compatible and you will be unable to load the QPY file in those cases. + :class:`.ParameterExpression` objects with ``version`` set low with the intent to + load the payload using a historical release of Qiskit, it is safest to set the + ``use_symengine`` flag to ``False``. Versions of Qiskit prior to 1.2.3 cannot load + QPY files containing ``symengine``-serialized :class:`.ParameterExpression` objects + unless the version of ``symengine`` used between the loading and generating + environments matches. Raises: diff --git a/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml b/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml index ca0a443c563..d8ed6b504de 100644 --- a/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml +++ b/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml @@ -1,50 +1,63 @@ --- fixes: - | - Fixed an issue with :func:`.qpy.load` when loading a QPY payload that - contains a :class:`.ParameterExpression` that was generated when symengine - 0.11 was installed and trying to load it in an environment where symengine - 0.13 (the latest symengine release as of this qiskit release) or vice versa. - Previously, an error would have been raised by symengine around this version - mismatch. This has been worked around for these two specific symengine versions - but if you're trying to use different versions of symengine and there is a - mismatch with this version of Qiskit this might not work. You will need to - install Qiskit >1.3.0 to fix this mismatch issue more broadly for any potential - future version of symengine. + Fixed an issue with :func:`.qpy.load` when loading a QPY file containing + a :class:`.ParameterExpression`, if the versions of ``symengine`` installed + in the generating and loading environments were not the same. For example, + if a QPY file containing :class:`.ParameterExpression`\ s was generated + using Qiskit 1.2.2 with ``symengine==0.11.0`` installed, Qiskit 1.2.2 with + ``syengine==0.13.0`` installed would be unable to load it. + + Previously, an error would have been raised by ``symengine`` around this + version mismatch. This has been worked around for ``symengine`` 0.11 and + 0.13 (there was no 0.12), but if you're trying to use different versions of + ``symengine`` and there is a mismatch, this version of Qiskit still might not + work. issues: - | - When dumping a QPY file using :func:`.qpy.dump` with the ``version=10`` flag and there are - unbound :class:`.ParameterExpression` in the circuit the output file - will not be loadable by Qiskit 0.45.x or 0.46.x due to incompatibilities - in the symengine serialization used between the symengine libraries used - in the different versions of Qiskit. Qiskit >= 1.0 requires symengine >= - 0.11 and Qiskit < 1.0 required symengine >= 0.9.0 and < 0.10.0. Symengine - 0.9.x and 0.11.0 (or 0.13.0) don't have a compatible serialization formats - which prevents the files from being loaded. In these cases the only option - available to generate a QPY file with unbound - :class:`.ParameterExpression` that can be loaded with Qiskit 0.45.x or - 0.46.x is to set both ``version=10`` and ``use_symengine=False``. + Versions of Qiskit before 1.2.3 will not be able to load QPY files dumped + using :func:`.qpy.dump`, even with ``version`` set appropriately, if: + + * there are unbound :class:`.ParameterExpression`\ s in the circuit, + * the ``use_symengine=True`` flag was set (which is the default in Qiskit >= + 1.0.0) in :func:`.qpy.dump`, + * the version of ``symengine`` installed in the generating and loading + environments are not within the same minor version (e.g. both 0.11, or + both 0.13). + + This applies regardless of the version of Qiskit used in the generation (at + least up to Qiskit 1.2.3 inclusive). + + If you want to maximize compatibility with older versions of Qiskit, you + should set ``use_symengine=False``. Newer versions of Qiskit should not + require this. - | - When loading a QPY file generated with Qiskit 0.45.x or 0.46.x and the - ``use_symengine`` flag set to ``True`` (an optional feature), these - payloads are not parsable with Qiskit >= 1.0 (including this release). - This is due to changes in the required symengine versions across the - Qiskit 1.0 major version boundary. Qiskit >= 1.0 requires symengine >= - 0.11 and Qiskit < 1.0 required symengine >= 0.9.0 and < 0.10.0. Symengine - 0.9.x and 0.11.0 (or 0.13.0) don't have a compatible serialization formats - which prevents newer version of Qiskit from loading those payloads. If you - have a QPY file generated with Qiskit 0.45.x or 0.46.x and the - ``use_symengine`` flag was set to ``True`` your only option is to load - the QPY file using Qiskit 0.46.3 and regenerate it using - ``use_symengine=False``. + QPY files from the Qiskit 0.45 series can, under a very specific and unlikely + set of circumstances, fail to load with any newer version of Qiskit, + including Qiskit 1.2.3. The criteria are: + + * the :class:`.QuantumCircuit` or :class:`.ScheduleBlock` to be dumped + contained unbound :class:`.ParameterExpression` objects, + * the installed version of ``symengine`` was in the 0.9 series (which was the + most recent release during the support window of Qiskit 0.45), + * the ``use_symengine=True`` flag was set (which was *not* the default). + + Later versions of Qiskit used during generation are not affected, because + they required newer versions than ``symengine`` 0.9. + + In this case, you can recover the QPY file by reloading it with an environment + with Qiskit 0.45.3 and ``symengine`` 0.9.2 installed. Then, use + :func:`.qpy.dump` with ``use_symengine=False`` to re-export the file. This + will then be readable by any newer version of Qiskit. upgrade: - | - The requirement on the support versions of `symengine `__ - has been pre-emptively capped at < 0.14.0 (which is the next minor version as of this release). - This has been done to protect against a potential incompatibility in :mod:`.qpy` when serializing + The supported versions of `symengine `__ + have been pre-emptively capped at < 0.14.0 (which is expected to be the next + minor version, as of this release of Qiskit). This has been done to protect + against a potential incompatibility in :mod:`.qpy` when serializing :class:`.ParameterExpression` objects. The serialization used in :ref:`qpy_format` versions 10, 11, and 12 for :class:`.ParameterExpression` - objects is tied to the symengine version used to generate it and there is the potential + objects is tied to the symengine version used to generate it, and there is the potential for a future symengine release to not be compatible. This upper version cap is to prevent a future release of symengine causing incompatibilities when trying to load QPY files using :class:`.qpy.load`.