diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index e873d316f70b..b8226171db3f 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -25,15 +25,16 @@ jobs: submodules: recursive fetch-depth: 0 - name: Install Cygwin - uses: cygwin/cygwin-install-action@006ad0b0946ca6d0a3ea2d4437677fa767392401 # v4 + uses: egor-tensin/setup-cygwin@d2c752bab416d4b0662591bd366fc2686297c82d #v4 with: platform: x86_64 install-dir: 'C:\tools\cygwin' packages: >- - python39-devel python39-pip python-pip-wheel python-setuptools-wheel - liblapack-devel liblapack0 gcc-fortran gcc-g++ git dash cmake ninja + python39=3.9.16-1 python39-devel=3.9.16-1 python39-pip python-pip-wheel + python-setuptools-wheel liblapack-devel liblapack0 gcc-fortran + gcc-g++ git dash cmake ninja - name: Set Windows PATH - uses: egor-tensin/cleanup-path@8469525c8ee3eddabbd3487658621a6235b3c581 # v3 + uses: egor-tensin/cleanup-path@f04bc953e6823bf491cc0bdcff959c630db1b458 # v4.0.1 with: dirs: 'C:\tools\cygwin\bin;C:\tools\cygwin\lib\lapack' - name: Verify that bash is Cygwin bash @@ -63,7 +64,7 @@ jobs: cd tools /usr/bin/python3.9 -m pytest --pyargs numpy -n2 -m "not slow" - name: Upload wheel if tests fail - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 if: failure() with: name: numpy-cygwin-wheel diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ee9db137641d..5a7ebbecc80e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,7 +26,7 @@ jobs: python-version: ["3.11"] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: submodules: recursive fetch-depth: 0 @@ -104,7 +104,7 @@ jobs: if: "github.repository == 'numpy/numpy'" runs-on: macos-13 steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: submodules: recursive fetch-depth: 0 diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 2049322173c6..fbc82c03aaa8 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -118,8 +118,7 @@ jobs: python-version: "3.x" - name: Build wheels - uses: pypa/cibuildwheel@a873dd9cbf9e3c4c73a1fd11ac31cf835f6eb502 # v2.16.0 - #uses: pypa/cibuildwheel@fff9ec32ed25a9c576750c91e06b410ed0c15db7 # v2.16.2 + uses: pypa/cibuildwheel@ce3fb7832089eb3e723a0a99cab7f3eaccf074fd # v2.16.5 env: CIBW_PRERELEASE_PYTHONS: True CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }} diff --git a/.gitmodules b/.gitmodules index 27ee5e6625eb..ce025743e7c1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,3 @@ [submodule "vendored-meson/meson"] path = vendored-meson/meson url = https://github.com/numpy/meson.git -[submodule "vendored-meson/meson-python"] - path = vendored-meson/meson-python - url = https://github.com/numpy/meson-python.git diff --git a/LICENSES_bundled.txt b/LICENSES_bundled.txt index 26faf7ff3021..aae0e774fae9 100644 --- a/LICENSES_bundled.txt +++ b/LICENSES_bundled.txt @@ -30,11 +30,6 @@ Files: vendored-meson/meson/* License: Apache 2.0 For license text, see vendored-meson/meson/COPYING -Name: meson-python -Files: vendored-meson/meson-python/* -License: MIT - For license text, see vendored-meson/meson-python/LICENSE - Name: spin Files: .spin/cmds.py License: BSD-3 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ce78d07777fa..e0b4b1f3c8bc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -85,6 +85,7 @@ stages: displayName: 'Run 32-bit manylinux2014 Docker Build / Tests' - job: Windows + timeoutInMinutes: 120 pool: vmImage: 'windows-2019' strategy: diff --git a/doc/changelog/1.26.4-changelog.rst b/doc/changelog/1.26.4-changelog.rst new file mode 100644 index 000000000000..f365ff1546eb --- /dev/null +++ b/doc/changelog/1.26.4-changelog.rst @@ -0,0 +1,45 @@ + +Contributors +============ + +A total of 13 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Charles Harris +* Elliott Sales de Andrade +* Lucas Colley + +* Mark Ryan + +* Matti Picus +* Nathan Goldbaum +* Ola x Nilsson + +* Pieter Eendebak +* Ralf Gommers +* Sayed Adel +* Sebastian Berg +* Stefan van der Walt +* Stefano Rivera + +Pull requests merged +==================== + +A total of 19 pull requests were merged for this release. + +* `#25323 `__: BUG: Restore missing asstr import +* `#25523 `__: MAINT: prepare 1.26.x for further development +* `#25539 `__: BUG: ``numpy.array_api``: fix ``linalg.cholesky`` upper decomp... +* `#25584 `__: CI: Bump azure pipeline timeout to 120 minutes +* `#25585 `__: MAINT, BLD: Fix unused inline functions warnings on clang +* `#25599 `__: BLD: include fix for MinGW platform detection +* `#25618 `__: TST: Fix test_numeric on riscv64 +* `#25619 `__: BLD: fix building for windows ARM64 +* `#25620 `__: MAINT: add ``newaxis`` to ``__all__`` in ``numpy.array_api`` +* `#25630 `__: BUG: Use large file fallocate on 32 bit linux platforms +* `#25643 `__: TST: Fix test_warning_calls on Python 3.12 +* `#25645 `__: TST: Bump pytz to 2023.3.post1 +* `#25658 `__: BUG: Fix AVX512 build flags on Intel Classic Compiler +* `#25670 `__: BLD: fix potential issue with escape sequences in ``__config__.py`` +* `#25718 `__: CI: pin cygwin python to 3.9.16-1 and fix typing tests [skip... +* `#25720 `__: MAINT: Bump cibuildwheel to v2.16.4 +* `#25748 `__: BLD: unvendor meson-python on 1.26.x and upgrade to meson-python... +* `#25755 `__: MAINT: Include header defining backtrace +* `#25756 `__: BUG: Fix np.quantile([Fraction(2,1)], 0.5) (#24711) diff --git a/doc/release/upcoming_changes/25181.compatibility.rst b/doc/release/upcoming_changes/25181.compatibility.rst deleted file mode 100644 index aefe7cd7a437..000000000000 --- a/doc/release/upcoming_changes/25181.compatibility.rst +++ /dev/null @@ -1,4 +0,0 @@ -``f2py`` will no longer accept ambiguous ``-m`` and ``.pyf`` CLI combinations. -When more than one ``.pyf`` file is passed, an error is raised. When both ``-m`` -and a ``.pyf`` is passed, a warning is emitted and the ``-m`` provided name is -ignored. diff --git a/doc/release/upcoming_changes/25186.improvement.rst b/doc/release/upcoming_changes/25186.improvement.rst deleted file mode 100644 index 6c55a2f500a1..000000000000 --- a/doc/release/upcoming_changes/25186.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -``f2py`` now handles ``common`` blocks which have ``kind`` specifications from modules. This further expands the usability of intrinsics like ``iso_fortran_env`` and ``iso_c_binding``. diff --git a/doc/source/release.rst b/doc/source/release.rst index 0af815c16a46..69ff5b7777e6 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -5,6 +5,7 @@ Release notes .. toctree:: :maxdepth: 3 + 1.26.4 1.26.3 1.26.2 1.26.1 diff --git a/doc/source/release/1.26.4-notes.rst b/doc/source/release/1.26.4-notes.rst new file mode 100644 index 000000000000..4db2a02c8b50 --- /dev/null +++ b/doc/source/release/1.26.4-notes.rst @@ -0,0 +1,57 @@ +.. currentmodule:: numpy + +========================== +NumPy 1.26.4 Release Notes +========================== + +NumPy 1.26.4 is a maintenance release that fixes bugs and regressions +discovered after the 1.26.3 release. The Python versions supported by this +release are 3.9-3.12. This is the last planned release in the 1.26.x series. + + +Contributors +============ + +A total of 13 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Charles Harris +* Elliott Sales de Andrade +* Lucas Colley + +* Mark Ryan + +* Matti Picus +* Nathan Goldbaum +* Ola x Nilsson + +* Pieter Eendebak +* Ralf Gommers +* Sayed Adel +* Sebastian Berg +* Stefan van der Walt +* Stefano Rivera + + +Pull requests merged +==================== + +A total of 19 pull requests were merged for this release. + +* `#25323 `__: BUG: Restore missing asstr import +* `#25523 `__: MAINT: prepare 1.26.x for further development +* `#25539 `__: BUG: ``numpy.array_api``: fix ``linalg.cholesky`` upper decomp... +* `#25584 `__: CI: Bump azure pipeline timeout to 120 minutes +* `#25585 `__: MAINT, BLD: Fix unused inline functions warnings on clang +* `#25599 `__: BLD: include fix for MinGW platform detection +* `#25618 `__: TST: Fix test_numeric on riscv64 +* `#25619 `__: BLD: fix building for windows ARM64 +* `#25620 `__: MAINT: add ``newaxis`` to ``__all__`` in ``numpy.array_api`` +* `#25630 `__: BUG: Use large file fallocate on 32 bit linux platforms +* `#25643 `__: TST: Fix test_warning_calls on Python 3.12 +* `#25645 `__: TST: Bump pytz to 2023.3.post1 +* `#25658 `__: BUG: Fix AVX512 build flags on Intel Classic Compiler +* `#25670 `__: BLD: fix potential issue with escape sequences in ``__config__.py`` +* `#25718 `__: CI: pin cygwin python to 3.9.16-1 and fix typing tests [skip... +* `#25720 `__: MAINT: Bump cibuildwheel to v2.16.4 +* `#25748 `__: BLD: unvendor meson-python on 1.26.x and upgrade to meson-python... +* `#25755 `__: MAINT: Include header defining backtrace +* `#25756 `__: BUG: Fix np.quantile([Fraction(2,1)], 0.5) (#24711) + diff --git a/meson_cpu/x86/meson.build b/meson_cpu/x86/meson.build index caf6bf09c14e..598f80ff0c89 100644 --- a/meson_cpu/x86/meson.build +++ b/meson_cpu/x86/meson.build @@ -143,8 +143,8 @@ if compiler_id in ['intel', 'intel-cl'] # Intel compilers don't support the following features independently FMA3.update(implies: [F16C, AVX2]) AVX2.update(implies: [F16C, FMA3]) - AVX512F.update(implies: [AVX2, AVX512CD, AVX512_SKX]) - AVX512CD.update(implies: [AVX512F, AVX512_SKX]) + AVX512F.update(implies: [AVX2, AVX512CD]) + AVX512CD.update(implies: [AVX512F]) XOP.update(disable: 'Intel Compiler does not support it') FMA4.update(disable: 'Intel Compiler does not support it') endif @@ -170,10 +170,10 @@ endif if compiler_id == 'intel' clear_m = '^(-mcpu=|-march=)' clear_any = '^(-mcpu=|-march=|-x[A-Z0-9\-])' - FMA3.update(args: {'val': '-march=core-avx2', 'match': clear_m}) - AVX2.update(args: {'val': '-march=core-avx2', 'match': clear_m}) - AVX512F.update(args: {'val': '-march=common-avx512', 'match': clear_m}) - AVX512CD.update(args: {'val': '-march=common-avx512', 'match': clear_m}) + FMA3.update(args: {'val': '-xCORE-AVX2', 'match': clear_m}) + AVX2.update(args: {'val': '-xCORE-AVX2', 'match': clear_m}) + AVX512F.update(args: {'val': '-xCOMMON-AVX512', 'match': clear_m}) + AVX512CD.update(args: {'val': '-xCOMMON-AVX512', 'match': clear_m}) AVX512_KNL.update(args: {'val': '-xKNL', 'match': clear_any}) AVX512_KNM.update(args: {'val': '-xKNM', 'match': clear_any}) AVX512_SKX.update(args: {'val': '-xSKYLAKE-AVX512', 'match': clear_any}) diff --git a/numpy/__config__.py.in b/numpy/__config__.py.in index 6c6c21cb85d4..f3b32c28c100 100644 --- a/numpy/__config__.py.in +++ b/numpy/__config__.py.in @@ -32,21 +32,27 @@ CONFIG = _cleanup( "Compilers": { "c": { "name": "@C_COMP@", - "linker": "@C_COMP_LINKER_ID@", + "linker": r"@C_COMP_LINKER_ID@", "version": "@C_COMP_VERSION@", - "commands": "@C_COMP_CMD_ARRAY@", + "commands": r"@C_COMP_CMD_ARRAY@", + "args": r"@C_COMP_ARGS@", + "linker args": r"@C_COMP_LINK_ARGS@", }, "cython": { "name": "@CYTHON_COMP@", - "linker": "@CYTHON_COMP_LINKER_ID@", + "linker": r"@CYTHON_COMP_LINKER_ID@", "version": "@CYTHON_COMP_VERSION@", - "commands": "@CYTHON_COMP_CMD_ARRAY@", + "commands": r"@CYTHON_COMP_CMD_ARRAY@", + "args": r"@CYTHON_COMP_ARGS@", + "linker args": r"@CYTHON_COMP_LINK_ARGS@", }, "c++": { "name": "@CPP_COMP@", - "linker": "@CPP_COMP_LINKER_ID@", + "linker": r"@CPP_COMP_LINKER_ID@", "version": "@CPP_COMP_VERSION@", - "commands": "@CPP_COMP_CMD_ARRAY@", + "commands": r"@CPP_COMP_CMD_ARRAY@", + "args": r"@CPP_COMP_ARGS@", + "linker args": r"@CPP_COMP_LINK_ARGS@", }, }, "Machine Information": { @@ -72,7 +78,7 @@ CONFIG = _cleanup( "detection method": "@BLAS_TYPE_NAME@", "include directory": r"@BLAS_INCLUDEDIR@", "lib directory": r"@BLAS_LIBDIR@", - "openblas configuration": "@BLAS_OPENBLAS_CONFIG@", + "openblas configuration": r"@BLAS_OPENBLAS_CONFIG@", "pc file directory": r"@BLAS_PCFILEDIR@", }, "lapack": { @@ -82,7 +88,7 @@ CONFIG = _cleanup( "detection method": "@LAPACK_TYPE_NAME@", "include directory": r"@LAPACK_INCLUDEDIR@", "lib directory": r"@LAPACK_LIBDIR@", - "openblas configuration": "@LAPACK_OPENBLAS_CONFIG@", + "openblas configuration": r"@LAPACK_OPENBLAS_CONFIG@", "pc file directory": r"@LAPACK_PCFILEDIR@", }, }, diff --git a/numpy/array_api/__init__.py b/numpy/array_api/__init__.py index 77f227882e3e..edc3205fd5c4 100644 --- a/numpy/array_api/__init__.py +++ b/numpy/array_api/__init__.py @@ -127,7 +127,7 @@ from ._constants import e, inf, nan, pi, newaxis -__all__ += ["e", "inf", "nan", "pi"] +__all__ += ["e", "inf", "nan", "pi", "newaxis"] from ._creation_functions import ( asarray, diff --git a/numpy/array_api/linalg.py b/numpy/array_api/linalg.py index 09af9dfc3ae2..c18360f6e6f9 100644 --- a/numpy/array_api/linalg.py +++ b/numpy/array_api/linalg.py @@ -9,6 +9,7 @@ complex128 ) from ._manipulation_functions import reshape +from ._elementwise_functions import conj from ._array_object import Array from ..core.numeric import normalize_axis_tuple @@ -53,7 +54,10 @@ def cholesky(x: Array, /, *, upper: bool = False) -> Array: raise TypeError('Only floating-point dtypes are allowed in cholesky') L = np.linalg.cholesky(x._array) if upper: - return Array._new(L).mT + U = Array._new(L).mT + if U.dtype in [complex64, complex128]: + U = conj(U) + return U return Array._new(L) # Note: cross is the numpy top-level namespace, not np.linalg diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py index 2cdaba52d9e2..d9d7862b2879 100644 --- a/numpy/core/code_generators/genapi.py +++ b/numpy/core/code_generators/genapi.py @@ -304,15 +304,6 @@ def find_functions(filename, tag='API'): fo.close() return functions -def should_rebuild(targets, source_files): - from distutils.dep_util import newer_group - for t in targets: - if not os.path.exists(t): - return True - sources = API_FILES + list(source_files) + [__file__] - if newer_group(sources, targets[0], missing='newer'): - return True - return False def write_file(filename, data): """ diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py index ae38c4efc2e3..640bae9e5ff4 100644 --- a/numpy/core/code_generators/generate_numpy_api.py +++ b/numpy/core/code_generators/generate_numpy_api.py @@ -148,12 +148,7 @@ def generate_api(output_dir, force=False): targets = (h_file, c_file) sources = numpy_api.multiarray_api - - if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])): - return targets - else: - do_generate_api(targets, sources) - + do_generate_api(targets, sources) return targets def do_generate_api(targets, sources): diff --git a/numpy/core/code_generators/generate_ufunc_api.py b/numpy/core/code_generators/generate_ufunc_api.py index e03299a52cf7..3734cbd6a069 100644 --- a/numpy/core/code_generators/generate_ufunc_api.py +++ b/numpy/core/code_generators/generate_ufunc_api.py @@ -125,12 +125,7 @@ def generate_api(output_dir, force=False): targets = (h_file, c_file) sources = ['ufunc_api_order.txt'] - - if (not force and not genapi.should_rebuild(targets, sources + [__file__])): - return targets - else: - do_generate_api(targets, sources) - + do_generate_api(targets, sources) return targets def do_generate_api(targets, sources): diff --git a/numpy/core/feature_detection_stdio.h b/numpy/core/feature_detection_stdio.h index bc14d16d04ff..d8bbfbd8b23c 100644 --- a/numpy/core/feature_detection_stdio.h +++ b/numpy/core/feature_detection_stdio.h @@ -1,6 +1,9 @@ +#define _GNU_SOURCE #include #include +#if 0 /* Only for setup_common.py, not the C compiler */ off_t ftello(FILE *stream); int fseeko(FILE *stream, off_t offset, int whence); int fallocate(int, int, off_t, off_t); +#endif diff --git a/numpy/core/src/common/npy_cpu_features.c b/numpy/core/src/common/npy_cpu_features.c index 64a85f6fb202..bd149f8b437a 100644 --- a/numpy/core/src/common/npy_cpu_features.c +++ b/numpy/core/src/common/npy_cpu_features.c @@ -656,7 +656,7 @@ npy__cpu_init_features(void) /***************** ARM ******************/ -#elif defined(__arm__) || defined(__aarch64__) +#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64) static inline void npy__cpu_init_features_arm8(void) @@ -781,7 +781,7 @@ npy__cpu_init_features(void) return; #endif // We have nothing else todo -#if defined(NPY_HAVE_ASIMD) || defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 8) +#if defined(NPY_HAVE_ASIMD) || defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 8) || defined(_M_ARM64) #if defined(NPY_HAVE_FPHP) || defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) npy__cpu_have[NPY_CPU_FEATURE_FPHP] = 1; #endif diff --git a/numpy/core/src/multiarray/convert.c b/numpy/core/src/multiarray/convert.c index 60c1a1b9b011..8ec0aeefb7af 100644 --- a/numpy/core/src/multiarray/convert.c +++ b/numpy/core/src/multiarray/convert.c @@ -23,8 +23,9 @@ #include "array_coercion.h" #include "refcount.h" -int -fallocate(int fd, int mode, off_t offset, off_t len); +#if defined(HAVE_FALLOCATE) && defined(__linux__) +#include +#endif /* * allocate nbytes of diskspace for file fp diff --git a/numpy/core/src/multiarray/temp_elide.c b/numpy/core/src/multiarray/temp_elide.c index 0bf500ed29c5..289040673571 100644 --- a/numpy/core/src/multiarray/temp_elide.c +++ b/numpy/core/src/multiarray/temp_elide.c @@ -59,6 +59,9 @@ */ #if defined HAVE_BACKTRACE && defined HAVE_DLFCN_H && ! defined PYPY_VERSION + +#include + /* 1 prints elided operations, 2 prints stacktraces */ #define NPY_ELIDE_DEBUG 0 #define NPY_MAX_STACKSIZE 10 diff --git a/numpy/core/src/umath/loops_arithmetic.dispatch.c.src b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src index e07bb79808af..d056046e054a 100644 --- a/numpy/core/src/umath/loops_arithmetic.dispatch.c.src +++ b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src @@ -36,12 +36,20 @@ * q = TRUNC((n - (-dsign ) + (-nsign))/d) - (-qsign); ********************************************************************************/ +#if (defined(NPY_HAVE_VSX) && !defined(NPY_HAVE_VSX4)) || defined(NPY_HAVE_NEON) + // Due to integer 128-bit multiplication emulation, SIMD 64-bit division + // may not perform well on both neon and up to VSX3 compared to scalar + // division. + #define SIMD_DISABLE_DIV64_OPT +#endif + #if NPY_SIMD /**begin repeat * Signed types * #sfx = s8, s16, s32, s64# * #len = 8, 16, 32, 64# */ +#if @len@ < 64 || (@len@ == 64 && !defined(SIMD_DISABLE_DIV64_OPT)) static inline void simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len) { @@ -101,6 +109,7 @@ simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len) } npyv_cleanup(); } +#endif /**end repeat**/ /**begin repeat @@ -108,6 +117,7 @@ simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len) * #sfx = u8, u16, u32, u64# * #len = 8, 16, 32, 64# */ +#if @len@ < 64 || (@len@ == 64 && !defined(SIMD_DISABLE_DIV64_OPT)) static inline void simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len) { @@ -129,6 +139,7 @@ simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len) } npyv_cleanup(); } +#endif /**end repeat**/ #if defined(NPY_HAVE_VSX4) @@ -335,8 +346,7 @@ vsx4_simd_divide_contig_@sfx@(char **args, npy_intp len) #define TO_SIMD_SFX(X) X##_s@len@ /**end repeat1**/ #endif - -#if NPY_BITSOF_@TYPE@ == 64 && !defined(NPY_HAVE_VSX4) && (defined(NPY_HAVE_VSX) || defined(NPY_HAVE_NEON)) +#if NPY_BITSOF_@TYPE@ == 64 && defined(SIMD_DISABLE_DIV64_OPT) #undef TO_SIMD_SFX #endif diff --git a/numpy/core/src/umath/loops_exponent_log.dispatch.c.src b/numpy/core/src/umath/loops_exponent_log.dispatch.c.src index 1fac3c150c73..85dac9c20dd8 100644 --- a/numpy/core/src/umath/loops_exponent_log.dispatch.c.src +++ b/numpy/core/src/umath/loops_exponent_log.dispatch.c.src @@ -123,18 +123,6 @@ fma_blend(__m256 x, __m256 y, __m256 ymask) return _mm256_blendv_ps(x, y, ymask); } -NPY_FINLINE __m256 -fma_invert_mask_ps(__m256 ymask) -{ - return _mm256_andnot_ps(ymask, _mm256_set1_ps(-1.0)); -} - -NPY_FINLINE __m256i -fma_invert_mask_pd(__m256i ymask) -{ - return _mm256_andnot_si256(ymask, _mm256_set1_epi32(0xFFFFFFFF)); -} - NPY_FINLINE __m256 fma_get_exponent(__m256 x) { @@ -311,18 +299,6 @@ avx512_blend(__m512 x, __m512 y, __mmask16 ymask) return _mm512_mask_mov_ps(x, ymask, y); } -NPY_FINLINE __mmask16 -avx512_invert_mask_ps(__mmask16 ymask) -{ - return _mm512_knot(ymask); -} - -NPY_FINLINE __mmask8 -avx512_invert_mask_pd(__mmask8 ymask) -{ - return _mm512_knot(ymask); -} - NPY_FINLINE __m512 avx512_get_exponent(__m512 x) { diff --git a/numpy/core/src/umath/loops_minmax.dispatch.c.src b/numpy/core/src/umath/loops_minmax.dispatch.c.src index 236e2e2eb760..319072c01fbe 100644 --- a/numpy/core/src/umath/loops_minmax.dispatch.c.src +++ b/numpy/core/src/umath/loops_minmax.dispatch.c.src @@ -225,7 +225,8 @@ simd_binary_ccc_@intrin@_@sfx@(const npyv_lanetype_@sfx@ *ip1, const npyv_lanety } } // non-contiguous for float 32/64-bit memory access -#if @is_fp@ +#if @is_fp@ && !defined(NPY_HAVE_NEON) +// unroll scalars faster than non-contiguous vector load/store on Arm static inline void simd_binary_@intrin@_@sfx@(const npyv_lanetype_@sfx@ *ip1, npy_intp sip1, const npyv_lanetype_@sfx@ *ip2, npy_intp sip2, diff --git a/numpy/core/src/umath/loops_trigonometric.dispatch.c.src b/numpy/core/src/umath/loops_trigonometric.dispatch.c.src index f07cb70f3977..31de906098e3 100644 --- a/numpy/core/src/umath/loops_trigonometric.dispatch.c.src +++ b/numpy/core/src/umath/loops_trigonometric.dispatch.c.src @@ -19,8 +19,9 @@ /**begin repeat * #check = F64, F32# * #sfx = f64, f32# + * #enable = 0, 1# */ -#if NPY_SIMD_@check@ +#if NPY_SIMD_@check@ && @enable@ /* * Vectorized Cody-Waite range reduction technique * Performs the reduction step x* = x - y*C in three steps: @@ -39,8 +40,10 @@ simd_range_reduction_@sfx@(npyv_@sfx@ x, npyv_@sfx@ y, npyv_@sfx@ c1, npyv_@sfx@ } #endif /**end repeat**/ - -#if NPY_SIMD_F64 +/* Disable SIMD code and revert to libm: see + * https://mail.python.org/archives/list/numpy-discussion@python.org/thread/C6EYZZSR4EWGVKHAZXLE7IBILRMNVK7L/ + * for detailed discussion on this*/ +#if 0 // NPY_SIMD_F64 /**begin repeat * #op = cos, sin# */ diff --git a/numpy/core/src/umath/loops_unary.dispatch.c.src b/numpy/core/src/umath/loops_unary.dispatch.c.src index 1e2a81d20b24..bfe4d892d0c9 100644 --- a/numpy/core/src/umath/loops_unary.dispatch.c.src +++ b/numpy/core/src/umath/loops_unary.dispatch.c.src @@ -195,6 +195,8 @@ simd_unary_nc_@intrin@_@sfx@(const npyv_lanetype_@sfx@ *ip, npy_intp istride, #undef UNROLL #define UNROLL 2 #endif +// X86 does better with unrolled scalar for heavy non-contiguous +#ifndef NPY_HAVE_SSE2 static NPY_INLINE void simd_unary_nn_@intrin@_@sfx@(const npyv_lanetype_@sfx@ *ip, npy_intp istride, npyv_lanetype_@sfx@ *op, npy_intp ostride, @@ -226,6 +228,7 @@ simd_unary_nn_@intrin@_@sfx@(const npyv_lanetype_@sfx@ *ip, npy_intp istride, *op = scalar_@intrin@(*ip); } } +#endif // NPY_HAVE_SSE2 #endif // @supports_ncontig@ #undef UNROLL #endif // @simd_chk@ @@ -314,8 +317,8 @@ NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@) ); goto clear; } - // SSE2 does better with unrolled scalar for heavy non-contiguous - #if !defined(NPY_HAVE_SSE2) + // X86 does better with unrolled scalar for heavy non-contiguous + #ifndef NPY_HAVE_SSE2 else if (istride != 1 && ostride != 1) { // non-contiguous input and output TO_SIMD_SFX(simd_unary_nn_@intrin@)( diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index d2d041f71ef2..e5edd3efce5a 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -477,7 +477,14 @@ def setup_method(self): self.signd[self.ed] *= -1. self.signf[1::6][self.ef[1::6]] = -np.inf self.signd[1::6][self.ed[1::6]] = -np.inf - self.signf[3::6][self.ef[3::6]] = -np.nan + # On RISC-V, many operations that produce NaNs, such as converting + # a -NaN from f64 to f32, return a canonical NaN. The canonical + # NaNs are always positive. See section 11.3 NaN Generation and + # Propagation of the RISC-V Unprivileged ISA for more details. + # We disable the float32 sign test on riscv64 for -np.nan as the sign + # of the NaN will be lost when it's converted to a float32. + if platform.processor() != 'riscv64': + self.signf[3::6][self.ef[3::6]] = -np.nan self.signd[3::6][self.ed[3::6]] = -np.nan self.signf[4::6][self.ef[4::6]] = -0. self.signd[4::6][self.ed[4::6]] = -0. diff --git a/numpy/f2py/tests/util.py b/numpy/f2py/tests/util.py index 75b257cdb825..6ed6c0855fb8 100644 --- a/numpy/f2py/tests/util.py +++ b/numpy/f2py/tests/util.py @@ -20,6 +20,7 @@ import numpy from pathlib import Path +from numpy.compat import asstr from numpy._utils import asunicode from numpy.testing import temppath, IS_WASM from importlib import import_module diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index e75aca1e58ec..a3dab04d3331 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -4655,7 +4655,8 @@ def _lerp(a, b, t, out=None): diff_b_a = subtract(b, a) # asanyarray is a stop-gap until gh-13105 lerp_interpolation = asanyarray(add(a, diff_b_a * t, out=out)) - subtract(b, diff_b_a * (1 - t), out=lerp_interpolation, where=t >= 0.5) + subtract(b, diff_b_a * (1 - t), out=lerp_interpolation, where=t >= 0.5, + casting='unsafe', dtype=type(lerp_interpolation.dtype)) if lerp_interpolation.ndim == 0 and out is None: lerp_interpolation = lerp_interpolation[()] # unpack 0d arrays return lerp_interpolation diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 11e44630e79d..2bb73b600380 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -3606,6 +3606,10 @@ def test_fraction(self): assert_equal(q, Fraction(7, 2)) assert_equal(type(q), Fraction) + q = np.quantile(x, .5) + assert_equal(q, 1.75) + assert_equal(type(q), np.float64) + q = np.quantile(x, Fraction(1, 2)) assert_equal(q, Fraction(7, 4)) assert_equal(type(q), Fraction) diff --git a/numpy/linalg/umath_linalg.cpp b/numpy/linalg/umath_linalg.cpp index b0857ab8ba1d..135e89119e17 100644 --- a/numpy/linalg/umath_linalg.cpp +++ b/numpy/linalg/umath_linalg.cpp @@ -2259,7 +2259,7 @@ process_geev_results(GEEV_PARAMS_t *params, scalar_trait) } } - +#if 0 static inline fortran_int call_geev(GEEV_PARAMS_t* params) { @@ -2275,6 +2275,8 @@ call_geev(GEEV_PARAMS_t* params) &rv); return rv; } +#endif + static inline fortran_int call_geev(GEEV_PARAMS_t* params) { diff --git a/numpy/tests/test_warnings.py b/numpy/tests/test_warnings.py index ee5124c5d511..df90fcef8c59 100644 --- a/numpy/tests/test_warnings.py +++ b/numpy/tests/test_warnings.py @@ -5,7 +5,6 @@ import pytest from pathlib import Path -import sys import ast import tokenize import numpy @@ -33,7 +32,7 @@ def visit_Call(self, node): ast.NodeVisitor.generic_visit(self, node) if p.ls[-1] == 'simplefilter' or p.ls[-1] == 'filterwarnings': - if node.args[0].s == "ignore": + if node.args[0].value == "ignore": raise AssertionError( "warnings should have an appropriate stacklevel; found in " "{} on line {}".format(self.__filename, node.lineno)) @@ -57,8 +56,6 @@ def visit_Call(self, node): @pytest.mark.slow -@pytest.mark.skipif(sys.version_info >= (3, 12), - reason="Deprecation warning in ast") def test_warning_calls(): # combined "ignore" and stacklevel error base = Path(numpy.__file__).parent diff --git a/numpy/typing/tests/test_typing.py b/numpy/typing/tests/test_typing.py index 68c6f5d03fab..6f778e551576 100644 --- a/numpy/typing/tests/test_typing.py +++ b/numpy/typing/tests/test_typing.py @@ -86,8 +86,6 @@ def strip_func(match: re.Match[str]) -> str: return match.groups()[1] -@pytest.mark.slow -@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed") @pytest.fixture(scope="module", autouse=True) def run_mypy() -> None: """Clears the cache and run mypy before running any of the typing tests. diff --git a/pavement.py b/pavement.py index 649e19d1fd1f..fac0955a7892 100644 --- a/pavement.py +++ b/pavement.py @@ -38,7 +38,7 @@ #----------------------------------- # Path to the release notes -RELEASE_NOTES = 'doc/source/release/1.26.3-notes.rst' +RELEASE_NOTES = 'doc/source/release/1.26.4-notes.rst' #------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 9ba86eb13486..a7f47fbcd7bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,23 +1,13 @@ [build-system] build-backend = "mesonpy" -backend-path = ['./vendored-meson/meson-python'] requires = [ "Cython>=0.29.34,<3.1", - # All dependencies of the vendored meson-python (except for meson, because - # we've got that vendored too - that's the point of this exercise). - 'pyproject-metadata >= 0.7.1', - 'tomli >= 1.0.0; python_version < "3.11"', - 'setuptools >= 60.0; python_version >= "3.12"', - 'colorama; os_name == "nt"', - # Note that `ninja` and (on Linux) `patchelf` are added dynamically by - # meson-python if those tools are not already present on the system. No - # need to worry about those unless one does a non-isolated build - in that - # case they must already be installed on the system. + "meson-python>=0.15.0,<0.16.0", ] [project] name = "numpy" -version = "1.26.3" +version = "1.26.4" # TODO: add `license-files` once PEP 639 is accepted (see meson-python#88) license = {file = "LICENSE.txt"} @@ -191,6 +181,9 @@ environment = {PKG_CONFIG_PATH="/opt/32/lib/pkgconfig"} config-settings = "setup-args=--vsenv setup-args=-Dallow-noblas=true" repair-wheel-command = "" +[tool.meson-python] +meson = 'vendored-meson/meson/meson.py' + [tool.spin] package = 'numpy' diff --git a/pyproject.toml.setuppy b/pyproject.toml.setuppy index dd97279fa503..c9bd3e2208e5 100644 --- a/pyproject.toml.setuppy +++ b/pyproject.toml.setuppy @@ -3,7 +3,7 @@ # to avoid building with Meson (e.g., in the Emscripten/Pyodide CI job) [project] name = "numpy" -version = "1.26.3" +version = "1.26.4" [build-system] requires = [ diff --git a/test_requirements.txt b/test_requirements.txt index ff1ed284e37d..1eba0371e558 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -4,7 +4,7 @@ setuptools==59.2.0 ; python_version < '3.12' setuptools ; python_version >= '3.12' hypothesis==6.81.1 pytest==7.4.0 -pytz==2023.3 +pytz==2023.3.post1 pytest-cov==4.1.0 meson pytest-xdist diff --git a/vendored-meson/build-backend-wrapper/npbuild/__init__.py b/vendored-meson/build-backend-wrapper/npbuild/__init__.py deleted file mode 100644 index 6c0711b2bd06..000000000000 --- a/vendored-meson/build-backend-wrapper/npbuild/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -import sys -import pathlib - -from mesonpy import ( - build_sdist, - build_wheel, - build_editable, - get_requires_for_build_sdist, - get_requires_for_build_wheel, - get_requires_for_build_editable, -) - - -# The numpy-vendored version of Meson. Put the directory that the executable -# `meson` is in at the front of the PATH. -curdir = pathlib.Path(__file__).parent.resolve() -meson_executable_dir = str(curdir.parent.parent / 'entrypoint') -os.environ['PATH'] = meson_executable_dir + os.pathsep + os.environ['PATH'] - -# Check that the meson git submodule is present -meson_import_dir = curdir.parent.parent / 'meson' / 'mesonbuild' -if not meson_import_dir.exists(): - raise RuntimeError( - 'The `vendored-meson/meson` git submodule does not exist! ' + - 'Run `git submodule update --init` to fix this problem.' - ) diff --git a/vendored-meson/entrypoint/meson b/vendored-meson/entrypoint/meson deleted file mode 100755 index f440b6ec55c0..000000000000 --- a/vendored-meson/entrypoint/meson +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import re -import sys -import pathlib - - -# The numpy-vendored version of Meson -meson_dir = str(pathlib.Path(__file__).resolve().parent.parent / 'meson') -sys.path.insert(0, meson_dir) - -from mesonbuild.mesonmain import main -import mesonbuild -if not 'vendored-meson' in mesonbuild.__path__[0]: - # Note: only the print statement will show most likely, not the exception. - # If this goes wrong, it first fails inside meson-python on the `meson - # --version` check. - print(f'picking up the wrong `meson`: {mesonbuild.__path__}') - raise RuntimeError('incorrect mesonbuild module, exiting') - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/vendored-meson/meson b/vendored-meson/meson index e6e1bf974b25..4e370ca8ab73 160000 --- a/vendored-meson/meson +++ b/vendored-meson/meson @@ -1 +1 @@ -Subproject commit e6e1bf974b2557974c06254c2447e862a59aae7f +Subproject commit 4e370ca8ab73c07f7b84abe8a4b937caace050a4 diff --git a/vendored-meson/meson-python b/vendored-meson/meson-python deleted file mode 160000 index 206a31a96458..000000000000 --- a/vendored-meson/meson-python +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 206a31a96458af6cf5e29272b4ea1f6ea500b91b