From 3cf096f5199d1f946da5b86c7dc968904386542d Mon Sep 17 00:00:00 2001 From: "riseproject-dev[bot]" <330740410+riseproject-dev[bot]@users.noreply.github.com> Date: Sat, 3 Oct 2026 07:45:07 +0000 Subject: [PATCH 1/3] matscipy: Add version 1.3.0 Signed-off-by: riseproject-dev[bot] <330740410+riseproject-dev[bot]@users.noreply.github.com> --- docs/packages/matscipy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/packages/matscipy.yaml b/docs/packages/matscipy.yaml index 84d81baef9c..effcfa8bcd7 100644 --- a/docs/packages/matscipy.yaml +++ b/docs/packages/matscipy.yaml @@ -16,3 +16,4 @@ versions: - filename: matscipy-1.2.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl sha256: edec7c83ef02d487442a94a3b4ad5f2f180d4f98ae927c6628eb0b54e2b6a8da requires-python: '>=3.9.0' +- version: 1.3.0 From bc215d69ad1c5e19f0a0168c6d4d40b7715f04f9 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 9 Oct 2026 16:31:44 +0000 Subject: [PATCH 2/3] matscipy: carry forward riscv64 patches to 1.3.0 Nightly version bump omitted the patches/matscipy/ directory for 1.3.0, so the build's unconditional `git apply .../*.patch` step failed with "No such file or directory" before any build/test ran. Copied forward the same patch set from 1.2.0 (unchanged since then). --- ...ex-1-element-arrays-before-int-float.patch | 33 +++++++ ...born-drop-removed-sqrtm-disp-keyword.patch | 38 ++++++++ ...ata-replace-ndarray-resize-for-py314.patch | 88 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch create mode 100644 patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch create mode 100644 patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch diff --git a/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch b/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch new file mode 100644 index 00000000000..2095d3a1252 --- /dev/null +++ b/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 01 Oct 2026 00:00:00 +0000 +Subject: [PATCH] eam/io: index 1-element arrays before int()/float() + +write_eam's "eam" (DYNAMO funcfl) branch calls int(atomic_numbers) and +float(atomic_masses)/float(lattice_parameters) directly on the +EAMParameters fields, which read_eam builds as 1-element numpy arrays +(np.array((int(words[0]),), dtype=int), etc.), not scalars - the +function's own "# FIXME: atomic numbers etc are now arrays, and not +scalars" comment already says as much. NumPy 2.x turned the implicit +conversion of a non-0-d array into a hard TypeError: "only +0-dimensional arrays can be converted to Python scalars", so +test_eam_io.py::test_eam_read_write's round-trip through this branch +fails outright. Indexing [0] before the int()/float() calls is what +the FIXME already describes as the fix; upstream made the same change +in 255201ab (released in 1.3.0). + +Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/255201aba4d827bb97dead8964c80e7276161603] + +Signed-off-by: Ludovic Henry +--- +--- a/matscipy/calculators/eam/io.py ++++ b/matscipy/calculators/eam/io.py +@@ -548,7 +548,7 @@ + # parameters unpacked + # FIXME: atomic numbers etc are now arrays, and not scalars + crystal_structures_str = ' '.join(s for s in crystal_structures) +- atline = f"{int(atomic_numbers)} {float(atomic_masses)} {float(lattice_parameters)} {crystal_structures_str}" ++ atline = f"{int(atomic_numbers[0])} {float(atomic_masses[0])} {float(lattice_parameters[0])} {crystal_structures_str}" + parameterline = f'{int(Nrho)}\t{float(drho):.16e}\t{int(Nr)}\t{float(dr):.16e}\t{float(cutoff):.10e}' + potheader = f"# EAM potential from : # {source} \n {atline} \n {parameterline}" + # --- Writing new EAM alloy pot file --- # diff --git a/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch b/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch new file mode 100644 index 00000000000..e65d73032a3 --- /dev/null +++ b/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 01 Oct 2026 00:00:00 +0000 +Subject: [PATCH] cauchy_born: drop the removed sqrtm(disp=) keyword + +SciPy 1.18 removed the deprecated disp= keyword of scipy.linalg.sqrtm, +so CubicCauchyBorn's two sqrtm(Usqr, disp=True) calls raise +"TypeError: sqrtm() got an unexpected keyword argument 'disp'" and all +nine test_cauchy_born_corrector.py::TestPredictCauchyBornShifts tests +fail. disp=True was the default, so sqrtm(Usqr) is unchanged on older +SciPy. Upstream made the same change in 75f077ff (released in 1.3.0). + +Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/75f077ff7de629fc65814b760d6ebd225b630d64] + +Signed-off-by: Ludovic Henry +--- +diff --git a/matscipy/cauchy_born.py b/matscipy/cauchy_born.py +index c84a2534..ad973424 100644 +--- a/matscipy/cauchy_born.py ++++ b/matscipy/cauchy_born.py +@@ -268,7 +268,7 @@ class CubicCauchyBorn: + # get U^2 + Usqr = 2 * E + np.eye(3) + # square root matrix to get U +- U = sqrtm(Usqr, disp=True) ++ U = sqrtm(Usqr) + + # this is just the symmetric stretch tensor, exactly what we need. + x = U +@@ -1330,7 +1330,7 @@ class CubicCauchyBorn: + # get U^2 + Usqr = 2 * E + np.eye(3) + # square root matrix +- U = sqrtm(Usqr, disp=True) ++ U = sqrtm(Usqr) + + # this is just the symmetric stretch tensor, exactly what we need. + x = U diff --git a/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch b/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch new file mode 100644 index 00000000000..930360d3d63 --- /dev/null +++ b/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 01 Oct 2026 00:00:00 +0000 +Subject: [PATCH] molecules, io/lammpsdata: replace ndarray.resize for Python 3.14 + +From NumPy 2.4 on, ndarray.resize(refcheck=True) on Python >= 3.14 uses +PyUnstable_Object_IsUniquelyReferenced, which an attribute-held array +never satisfies, so Molecules.__init__ and LAMMPSData's setter/reader +raise "ValueError: cannot resize an array that may be referenced by +another object" on cp314 only (test_newmb.py, test_neighbours.py, +test_io.py collection errors, test_manybody_molecules.py setup errors). +Upstream replaced every such resize with a fresh np.empty of the same +dtype in libAtoms/matscipy#312 (commits 1b006eb4 and 3a1ec1dc, released +in 1.3.0); this is those two hunks unchanged. + +Upstream-Status: Backport [https://github.com/libAtoms/matscipy/pull/312] + +Signed-off-by: Ludovic Henry +--- +diff --git a/matscipy/io/lammpsdata.py b/matscipy/io/lammpsdata.py +index 4525a786..e7200f0a 100644 +--- a/matscipy/io/lammpsdata.py ++++ b/matscipy/io/lammpsdata.py +@@ -193,10 +193,15 @@ class LAMMPSData: + """Set data component.""" + if name in self._type_names: + name = self._type_names[name] +- self.__data[name].resize(len(value)) ++ old = self.__data[name] ++ new_arr = np.empty(len(value), dtype=self._dtypes[name]) ++ n = min(len(old), len(value)) ++ if n > 0: ++ new_arr[:n] = old[:n] ++ self.__data[name] = new_arr + self.__data[name]['type'] = value + elif name in self._data_names: +- self.__data[name].resize(len(value)) ++ self.__data[name] = np.empty(len(value), dtype=self._dtypes[name]) + data = self.__data[name] + try: + data[data.dtype.names[-1]] = np.array(value) +@@ -309,16 +314,15 @@ class LAMMPSData: + for linum, line in enumerate(fd): + if 'Masses' in line: + ntypes = type_counts['atom types'] +- self['masses'].resize(ntypes) +- self['masses'][:] = \ ++ self.__data['masses'] = \ + np.genfromtxt(fd, skip_header=1, +- max_rows=ntypes, usecols=(1,)) ++ max_rows=ntypes, usecols=(1,), dtype=self._dtypes['masses']) + + else: + for label in self._data_names: + if self.__headers[label] in line: + nlines = data_counts[label] +- self[label].resize(nlines) ++ self.__data[label] = np.empty(nlines, dtype=self._dtypes[label]) + dtype = self[label].dtype + + raw_dtype = np.dtype([('num', np.int32)] + [ +diff --git a/matscipy/molecules.py b/matscipy/molecules.py +index 4657da62..d9a88996 100644 +--- a/matscipy/molecules.py ++++ b/matscipy/molecules.py +@@ -72,19 +72,19 @@ class Molecules: + self.__dict__[data] = np.array([], dtype=dtype) + + if bonds_connectivity is not None: +- self.bonds.resize(len(bonds_connectivity)) ++ self.bonds = np.empty(len(bonds_connectivity), dtype=self._dtypes["bonds"]) + self.bonds["atoms"][:] = bonds_connectivity + self.bonds["type"][:] = bonds_types \ + if bonds_types is not None else default_type + + if angles_connectivity is not None: +- self.angles.resize(len(angles_connectivity)) ++ self.angles = np.empty(len(angles_connectivity), dtype=self._dtypes["angles"]) + self.angles["atoms"][:] = angles_connectivity + self.angles["type"][:] = angles_types \ + if angles_types is not None else default_type + + if dihedrals_connectivity is not None: +- self.dihedrals.resize(len(dihedrals_connectivity)) ++ self.dihedrals = np.empty(len(dihedrals_connectivity), dtype=self._dtypes["dihedrals"]) + self.dihedrals["atoms"][:] = dihedrals_connectivity + self.dihedrals["type"][:] = dihedrals_types \ + if dihedrals_types is not None else default_type From 009a81f291c6d3f76ffda5a9b3eb437859bda99e Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 10 Oct 2026 07:48:53 +0000 Subject: [PATCH 3/3] matscipy: drop 1.3.0 patches, all three are upstream The carried-forward 1.3.0 patch set no longer applies. All three fixes landed upstream in v1.3.0: - 0001 (eam/io int()/float() on 1-element arrays): upstream 255201ab, which also rewrote the "# FIXME" comment above the changed line, so the hunk's context at io.py:548 no longer matched. - 0002 (cauchy_born sqrtm disp=) and 0003 (ndarray.resize for py3.14): v1.3.0 source is byte-identical to the patched state (the patches reverse-apply cleanly). Make the patch step skip versions without a patches/ dir (same guard as build-asyncmy2/soundfile) and use xargs -r so the skip-worktree line is a no-op on an unpatched tree. --- .github/workflows/build-matscipy.yml | 8 +- ...ex-1-element-arrays-before-int-float.patch | 33 ------- ...born-drop-removed-sqrtm-disp-keyword.patch | 38 -------- ...ata-replace-ndarray-resize-for-py314.patch | 88 ------------------- 4 files changed, 6 insertions(+), 161 deletions(-) delete mode 100644 patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch delete mode 100644 patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch delete mode 100644 patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch diff --git a/.github/workflows/build-matscipy.yml b/.github/workflows/build-matscipy.yml index 0afaa146933..28649838e9c 100644 --- a/.github/workflows/build-matscipy.yml +++ b/.github/workflows/build-matscipy.yml @@ -73,12 +73,16 @@ jobs: - name: Patch matscipy source run: | - git apply python-wheels/patches/matscipy/${{ env.MATSCIPY_VERSION }}/*.patch + # 1.3.0 ships all of 1.2.0's fixes upstream, so not every version has a patch dir. + patches="python-wheels/patches/matscipy/${{ env.MATSCIPY_VERSION }}" + if [ -d "$patches" ]; then + git apply "$patches"/*.patch + fi # meson-python reads the wheel version from `git describe` on this tree; a # dirty tree gives "1.2.0.dirty", which packaging.version.Version rejects # outright (InvalidVersion), failing the build before compilation even # starts. Hide just the patched files from dirty-detection instead. - git diff --name-only | xargs git update-index --skip-worktree + git diff --name-only | xargs -r git update-index --skip-worktree - name: Build wheels uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 diff --git a/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch b/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch deleted file mode 100644 index 2095d3a1252..00000000000 --- a/patches/matscipy/1.3.0/0001-eam-io-index-1-element-arrays-before-int-float.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ludovic Henry -Date: Thu, 01 Oct 2026 00:00:00 +0000 -Subject: [PATCH] eam/io: index 1-element arrays before int()/float() - -write_eam's "eam" (DYNAMO funcfl) branch calls int(atomic_numbers) and -float(atomic_masses)/float(lattice_parameters) directly on the -EAMParameters fields, which read_eam builds as 1-element numpy arrays -(np.array((int(words[0]),), dtype=int), etc.), not scalars - the -function's own "# FIXME: atomic numbers etc are now arrays, and not -scalars" comment already says as much. NumPy 2.x turned the implicit -conversion of a non-0-d array into a hard TypeError: "only -0-dimensional arrays can be converted to Python scalars", so -test_eam_io.py::test_eam_read_write's round-trip through this branch -fails outright. Indexing [0] before the int()/float() calls is what -the FIXME already describes as the fix; upstream made the same change -in 255201ab (released in 1.3.0). - -Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/255201aba4d827bb97dead8964c80e7276161603] - -Signed-off-by: Ludovic Henry ---- ---- a/matscipy/calculators/eam/io.py -+++ b/matscipy/calculators/eam/io.py -@@ -548,7 +548,7 @@ - # parameters unpacked - # FIXME: atomic numbers etc are now arrays, and not scalars - crystal_structures_str = ' '.join(s for s in crystal_structures) -- atline = f"{int(atomic_numbers)} {float(atomic_masses)} {float(lattice_parameters)} {crystal_structures_str}" -+ atline = f"{int(atomic_numbers[0])} {float(atomic_masses[0])} {float(lattice_parameters[0])} {crystal_structures_str}" - parameterline = f'{int(Nrho)}\t{float(drho):.16e}\t{int(Nr)}\t{float(dr):.16e}\t{float(cutoff):.10e}' - potheader = f"# EAM potential from : # {source} \n {atline} \n {parameterline}" - # --- Writing new EAM alloy pot file --- # diff --git a/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch b/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch deleted file mode 100644 index e65d73032a3..00000000000 --- a/patches/matscipy/1.3.0/0002-cauchy_born-drop-removed-sqrtm-disp-keyword.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ludovic Henry -Date: Thu, 01 Oct 2026 00:00:00 +0000 -Subject: [PATCH] cauchy_born: drop the removed sqrtm(disp=) keyword - -SciPy 1.18 removed the deprecated disp= keyword of scipy.linalg.sqrtm, -so CubicCauchyBorn's two sqrtm(Usqr, disp=True) calls raise -"TypeError: sqrtm() got an unexpected keyword argument 'disp'" and all -nine test_cauchy_born_corrector.py::TestPredictCauchyBornShifts tests -fail. disp=True was the default, so sqrtm(Usqr) is unchanged on older -SciPy. Upstream made the same change in 75f077ff (released in 1.3.0). - -Upstream-Status: Backport [https://github.com/libAtoms/matscipy/commit/75f077ff7de629fc65814b760d6ebd225b630d64] - -Signed-off-by: Ludovic Henry ---- -diff --git a/matscipy/cauchy_born.py b/matscipy/cauchy_born.py -index c84a2534..ad973424 100644 ---- a/matscipy/cauchy_born.py -+++ b/matscipy/cauchy_born.py -@@ -268,7 +268,7 @@ class CubicCauchyBorn: - # get U^2 - Usqr = 2 * E + np.eye(3) - # square root matrix to get U -- U = sqrtm(Usqr, disp=True) -+ U = sqrtm(Usqr) - - # this is just the symmetric stretch tensor, exactly what we need. - x = U -@@ -1330,7 +1330,7 @@ class CubicCauchyBorn: - # get U^2 - Usqr = 2 * E + np.eye(3) - # square root matrix -- U = sqrtm(Usqr, disp=True) -+ U = sqrtm(Usqr) - - # this is just the symmetric stretch tensor, exactly what we need. - x = U diff --git a/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch b/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch deleted file mode 100644 index 930360d3d63..00000000000 --- a/patches/matscipy/1.3.0/0003-molecules-lammpsdata-replace-ndarray-resize-for-py314.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ludovic Henry -Date: Thu, 01 Oct 2026 00:00:00 +0000 -Subject: [PATCH] molecules, io/lammpsdata: replace ndarray.resize for Python 3.14 - -From NumPy 2.4 on, ndarray.resize(refcheck=True) on Python >= 3.14 uses -PyUnstable_Object_IsUniquelyReferenced, which an attribute-held array -never satisfies, so Molecules.__init__ and LAMMPSData's setter/reader -raise "ValueError: cannot resize an array that may be referenced by -another object" on cp314 only (test_newmb.py, test_neighbours.py, -test_io.py collection errors, test_manybody_molecules.py setup errors). -Upstream replaced every such resize with a fresh np.empty of the same -dtype in libAtoms/matscipy#312 (commits 1b006eb4 and 3a1ec1dc, released -in 1.3.0); this is those two hunks unchanged. - -Upstream-Status: Backport [https://github.com/libAtoms/matscipy/pull/312] - -Signed-off-by: Ludovic Henry ---- -diff --git a/matscipy/io/lammpsdata.py b/matscipy/io/lammpsdata.py -index 4525a786..e7200f0a 100644 ---- a/matscipy/io/lammpsdata.py -+++ b/matscipy/io/lammpsdata.py -@@ -193,10 +193,15 @@ class LAMMPSData: - """Set data component.""" - if name in self._type_names: - name = self._type_names[name] -- self.__data[name].resize(len(value)) -+ old = self.__data[name] -+ new_arr = np.empty(len(value), dtype=self._dtypes[name]) -+ n = min(len(old), len(value)) -+ if n > 0: -+ new_arr[:n] = old[:n] -+ self.__data[name] = new_arr - self.__data[name]['type'] = value - elif name in self._data_names: -- self.__data[name].resize(len(value)) -+ self.__data[name] = np.empty(len(value), dtype=self._dtypes[name]) - data = self.__data[name] - try: - data[data.dtype.names[-1]] = np.array(value) -@@ -309,16 +314,15 @@ class LAMMPSData: - for linum, line in enumerate(fd): - if 'Masses' in line: - ntypes = type_counts['atom types'] -- self['masses'].resize(ntypes) -- self['masses'][:] = \ -+ self.__data['masses'] = \ - np.genfromtxt(fd, skip_header=1, -- max_rows=ntypes, usecols=(1,)) -+ max_rows=ntypes, usecols=(1,), dtype=self._dtypes['masses']) - - else: - for label in self._data_names: - if self.__headers[label] in line: - nlines = data_counts[label] -- self[label].resize(nlines) -+ self.__data[label] = np.empty(nlines, dtype=self._dtypes[label]) - dtype = self[label].dtype - - raw_dtype = np.dtype([('num', np.int32)] + [ -diff --git a/matscipy/molecules.py b/matscipy/molecules.py -index 4657da62..d9a88996 100644 ---- a/matscipy/molecules.py -+++ b/matscipy/molecules.py -@@ -72,19 +72,19 @@ class Molecules: - self.__dict__[data] = np.array([], dtype=dtype) - - if bonds_connectivity is not None: -- self.bonds.resize(len(bonds_connectivity)) -+ self.bonds = np.empty(len(bonds_connectivity), dtype=self._dtypes["bonds"]) - self.bonds["atoms"][:] = bonds_connectivity - self.bonds["type"][:] = bonds_types \ - if bonds_types is not None else default_type - - if angles_connectivity is not None: -- self.angles.resize(len(angles_connectivity)) -+ self.angles = np.empty(len(angles_connectivity), dtype=self._dtypes["angles"]) - self.angles["atoms"][:] = angles_connectivity - self.angles["type"][:] = angles_types \ - if angles_types is not None else default_type - - if dihedrals_connectivity is not None: -- self.dihedrals.resize(len(dihedrals_connectivity)) -+ self.dihedrals = np.empty(len(dihedrals_connectivity), dtype=self._dtypes["dihedrals"]) - self.dihedrals["atoms"][:] = dihedrals_connectivity - self.dihedrals["type"][:] = dihedrals_types \ - if dihedrals_types is not None else default_type