diff --git a/qiskit/qpy/__init__.py b/qiskit/qpy/__init__.py index eccb09ce73d6..579fbe2e587e 100644 --- a/qiskit/qpy/__init__.py +++ b/qiskit/qpy/__init__.py @@ -116,6 +116,13 @@ .. autoexception:: QPYLoadingDeprecatedFeatureWarning +.. 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. + QPY format version history -------------------------- diff --git a/qiskit/qpy/common.py b/qiskit/qpy/common.py index 84acebcf335d..6084f53a1701 100644 --- a/qiskit/qpy/common.py +++ b/qiskit/qpy/common.py @@ -322,6 +322,17 @@ def load_symengine_payload(payload: bytes) -> symengine.Expr: major = payload[2] minor = payload[3] if int(symengine_version[1]) != minor: + if major != "0": + raise exceptions.QpyError( + "Qiskit doesn't support loading a symengine payload generated with symengine >= 1.0" + ) + if minor == 9: + raise exceptions.QpyError( + "Qiskit doesn't support loading a historical QPY file with `use_symengine=True` " + "generated in an environment using symengine 0.9.0. If you need to load this file " + "you can do so with Qiskit 0.45.x or 0.46.x and re-export the QPY file using " + "`use_symengine=False`." + ) if minor not in (11, 13): raise exceptions.QpyError( f"Incompatible symengine version {major}.{minor} used to generate the QPY " diff --git a/qiskit/qpy/interface.py b/qiskit/qpy/interface.py index d89117bc6a1c..dd9eab0809ef 100644 --- a/qiskit/qpy/interface.py +++ b/qiskit/qpy/interface.py @@ -144,6 +144,16 @@ def dump( from the QPY format at that version will persist. This should only be used if compatibility with loading the payload with an older version of Qiskit is necessary. + .. 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. + + Raises: QpyError: When multiple data format is mixed in the output. TypeError: When invalid data type is input. diff --git a/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml b/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml index b018ac74ef42..328be02bed2c 100644 --- a/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml +++ b/releasenotes/notes/fix-qpy-symengine-compat-858970a9a1d6bc14.yaml @@ -11,3 +11,29 @@ fixes: 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. +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``. + - | + 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``.