-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[0.46] Finalise support for Numpy 2.0 (#12189)
* Finalise support for Numpy 2.0 This commit brings the Qiskit test suite to a passing state (with all optionals installed) with Numpy 2.0.0b1, building on previous commits that handled much of the rest of the changing requirements: - gh-10890 - gh-10891 - gh-10892 - gh-10897 - gh-11023 Notably, this commit did not actually require a rebuild of Qiskit, despite us compiling against Numpy; it seems to happen that the C API stuff we use via `rust-numpy` (which loads the Numpy C extensions dynamically during module initialisation) hasn't changed. The main changes are: - adapting to the changed `copy=None` and `copy=False` semantics in `array` and `asarray`. - making sure all our implementers of `__array__` accept both `dtype` and `copy` arguments. Co-authored-by: Lev S. Bishop <[email protected]> * Update `__array__` methods for Numpy 2.0 compatibility As of Numpy 2.0, implementers of `__array__` are expected and required to have a signature def __array__(self, dtype=None, copy=None): ... In Numpys before 2.0, the `copy` argument will never be passed, and the expected signature was def __array__(self, dtype=None): ... Because of this, we have latitude to set `copy` in our implementations to anything we like if we're running against Numpy 1.x, but we should default to `copy=None` if we're running against Numpy 2.0. The semantics of the `copy` argument to `np.array` changed in Numpy 2.0. Now, `copy=False` means "raise a `ValueError` if a copy is required" and `copy=None` means "copy only if required". In Numpy 1.x, `copy=False` meant "copy only if required". In _both_ Numpy 1.x and 2.0, `ndarray.astype` takes a `copy` argument, and in both, `copy=False` means "copy only if required". In Numpy 2.0 only, `np.asarray` gained a `copy` argument with the same semantics as the `np.array` copy argument from Numpy 2.0. Further, the semantics of the `__array__` method changed in Numpy 2.0, particularly around copying. Now, Numpy will assume that it can pass `copy=True` and the implementer will handle this. If `copy=False` is given and a copy or calculation is required, then the implementer is required to raise `ValueError`. We have a few places where the `__array__` method may (or always does) calculate the array, so in all these, we must forbid `copy=False`. With all this in mind: this PR sets up all our implementers of `__array__` to either default to `copy=None` if they will never actually need to _use_ the `copy` argument within themselves (except perhaps to test if it was set by Numpy 2.0 to `False`, as Numpy 1.x will never set it), or to a compatibility shim `_numpy_compat.COPY_ONLY_IF_NEEDED` if they do naturally want to use it with those semantics. The pattern def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED): dtype = self._array.dtype if dtype is None else dtype return np.array(self._array, dtype=dtype, copy=copy) using `array` instead of `asarray` lets us achieve all the desired behaviour between the interactions of `dtype` and `copy` in a way that is compatible with both Numpy 1.x and 2.x. --------- Co-authored-by: Lev S. Bishop <[email protected]> Co-authored-by: Raynel Sanchez <[email protected]>
- Loading branch information
1 parent
86acb27
commit 44b3146
Showing
42 changed files
with
319 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2024. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""Compatiblity helpers for the Numpy 1.x to 2.0 transition.""" | ||
|
||
import re | ||
import typing | ||
import warnings | ||
|
||
import numpy as np | ||
|
||
# This version pattern is taken from the pypa packaging project: | ||
# https://github.com/pypa/packaging/blob/21.3/packaging/version.py#L223-L254 which is dual licensed | ||
# Apache 2.0 and BSD see the source for the original authors and other details. | ||
_VERSION_PATTERN = r""" | ||
v? | ||
(?: | ||
(?:(?P<epoch>[0-9]+)!)? # epoch | ||
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment | ||
(?P<pre> # pre-release | ||
[-_\.]? | ||
(?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) | ||
[-_\.]? | ||
(?P<pre_n>[0-9]+)? | ||
)? | ||
(?P<post> # post release | ||
(?:-(?P<post_n1>[0-9]+)) | ||
| | ||
(?: | ||
[-_\.]? | ||
(?P<post_l>post|rev|r) | ||
[-_\.]? | ||
(?P<post_n2>[0-9]+)? | ||
) | ||
)? | ||
(?P<dev> # dev release | ||
[-_\.]? | ||
(?P<dev_l>dev) | ||
[-_\.]? | ||
(?P<dev_n>[0-9]+)? | ||
)? | ||
) | ||
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version | ||
""" | ||
|
||
VERSION = np.lib.NumpyVersion(np.__version__) | ||
VERSION_PARTS: typing.Tuple[int, ...] | ||
"""The numeric parts of the Numpy release version, e.g. ``(2, 0, 0)``. Does not include pre- or | ||
post-release markers (e.g. ``rc1``).""" | ||
if match := re.fullmatch(_VERSION_PATTERN, np.__version__, flags=re.VERBOSE | re.IGNORECASE): | ||
# Assuming Numpy won't ever introduce epochs, and we don't care about pre/post markers. | ||
VERSION_PARTS = tuple(int(x) for x in match["release"].split(".")) | ||
else: | ||
# Just guess a version. We know all existing Numpys have good version strings, so the only way | ||
# this should trigger is from a new or a dev version. | ||
warnings.warn( | ||
f"Unrecognized version string for Numpy: '{np.__version__}'. Assuming Numpy 2.0.", | ||
RuntimeWarning, | ||
) | ||
VERSION_PARTS = (2, 0, 0) | ||
|
||
COPY_ONLY_IF_NEEDED = None if VERSION_PARTS >= (2, 0, 0) else False | ||
"""The sentinel value given to ``np.array`` and ``np.ndarray.astype`` (etc) to indicate that a copy | ||
should be made only if required.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.