From 80c1780f553f450cac0fff593efc970e57a95a9c Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Tue, 12 Mar 2024 17:43:35 +0000 Subject: [PATCH] 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 <18673315+levbishop@users.noreply.github.com> --- .../quantum_info/operators/symplectic/clifford.py | 13 +++++++++++-- .../operators/symplectic/sparse_pauli_op.py | 7 ++++++- qiskit/visualization/array.py | 2 +- releasenotes/notes/numpy-2.0-2f3e35bd42c48518.yaml | 5 +++++ requirements.txt | 4 ++-- 5 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/numpy-2.0-2f3e35bd42c48518.yaml diff --git a/qiskit/quantum_info/operators/symplectic/clifford.py b/qiskit/quantum_info/operators/symplectic/clifford.py index 9c7217c4894f..55e89e51e861 100644 --- a/qiskit/quantum_info/operators/symplectic/clifford.py +++ b/qiskit/quantum_info/operators/symplectic/clifford.py @@ -165,8 +165,17 @@ def __init__(self, data, validate=True, copy=True): # Initialize StabilizerTable directly from the data else: - if isinstance(data, (list, np.ndarray)) and np.asarray(data, dtype=bool).ndim == 2: - data = np.array(data, dtype=bool, copy=copy) + if ( + isinstance(data, (list, np.ndarray)) + and (data_asarray := np.asarray(data, dtype=bool)).ndim == 2 + ): + # This little dance is to avoid Numpy 1/2 incompatiblities between the availability + # and meaning of the 'copy' argument in 'array' and 'asarray', when the input needs + # its dtype converting. 'asarray' prefers to return 'self' if possible in both. + if copy and np.may_share_memory(data, data_asarray): + data = data_asarray.copy() + else: + data = data_asarray if data.shape[0] == data.shape[1]: self.tableau = self._stack_table_phase( data, np.zeros(data.shape[0], dtype=bool) diff --git a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py index a09087864548..b4c63da4640b 100644 --- a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +++ b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py @@ -144,7 +144,12 @@ def __init__( if coeffs is None: coeffs = np.ones(pauli_list.size, dtype=complex) else: - coeffs = np.array(coeffs, copy=copy, dtype=dtype) + coeffs_asarray = np.asarray(coeffs, dtype=dtype) + coeffs = ( + coeffs_asarray.copy() + if copy and np.may_share_memory(coeffs, coeffs_asarray) + else coeffs_asarray + ) if ignore_pauli_phase: # Fast path used in copy operations, where the phase of the PauliList is already known diff --git a/qiskit/visualization/array.py b/qiskit/visualization/array.py index b076e38b174d..3a8ef2917156 100644 --- a/qiskit/visualization/array.py +++ b/qiskit/visualization/array.py @@ -33,7 +33,7 @@ def _num_to_latex(raw_value, decimals=15, first_term=True, coefficient=False): """ import sympy # runtime import - raw_value = np.around(raw_value, decimals=decimals) + raw_value = np.around(raw_value, decimals=decimals).item() value = sympy.nsimplify(raw_value, rational=False) if isinstance(value, sympy.core.numbers.Rational) and value.denominator > 50: diff --git a/releasenotes/notes/numpy-2.0-2f3e35bd42c48518.yaml b/releasenotes/notes/numpy-2.0-2f3e35bd42c48518.yaml new file mode 100644 index 000000000000..3595f2f936bd --- /dev/null +++ b/releasenotes/notes/numpy-2.0-2f3e35bd42c48518.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + This release of Qiskit finalizes support for NumPy 2.0. Qiskit will continue to support both + Numpy 1.x and 2.x for the foreseeable future. diff --git a/requirements.txt b/requirements.txt index e30c143b74ee..032d1d6578cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ rustworkx>=0.13.0 -numpy>=1.17,<2 +numpy>=1.17,<3 ply>=3.10 psutil>=5 scipy>=1.5 @@ -8,4 +8,4 @@ dill>=0.3 python-dateutil>=2.8.0 stevedore>=3.0.0 typing-extensions; python_version<'3.11' -symengine>=0.11; platform_machine == 'x86_64' or platform_machine == 'aarch64' or platform_machine == 'ppc64le' or platform_machine == 'amd64' or platform_machine == 'arm64' \ No newline at end of file +symengine>=0.11; platform_machine == 'x86_64' or platform_machine == 'aarch64' or platform_machine == 'ppc64le' or platform_machine == 'amd64' or platform_machine == 'arm64'