From: Brad Smith Subject: UPDATE: numpy To: ports@openbsd.org Cc: daniel@openbsd.org Date: Fri, 20 Jun 2025 01:25:11 -0400 Here is a diff for numpy that backports patches to enable CPU feature detection via elf_aux_info() on ARM, PowerPC64, and RISC-V 64. Index: Makefile =================================================================== RCS file: /cvs/ports/math/py-numpy/Makefile,v retrieving revision 1.93 diff -u -p -u -p -r1.93 Makefile --- Makefile 17 Jun 2025 11:59:23 -0000 1.93 +++ Makefile 20 Jun 2025 03:23:08 -0000 @@ -4,7 +4,7 @@ COMMENT= fast array and numeric programm MODPY_DISTV= 2.2.6 DISTNAME= numpy-${MODPY_DISTV} PKGNAME= py-${DISTNAME} -REVISION= 0 +REVISION= 1 CATEGORIES= math devel Index: patches/patch-numpy__core_src_common_npy_cpu_features_c =================================================================== RCS file: /cvs/ports/math/py-numpy/patches/patch-numpy__core_src_common_npy_cpu_features_c,v retrieving revision 1.1 diff -u -p -u -p -r1.1 patch-numpy__core_src_common_npy_cpu_features_c --- patches/patch-numpy__core_src_common_npy_cpu_features_c 17 Jun 2025 11:59:23 -0000 1.1 +++ patches/patch-numpy__core_src_common_npy_cpu_features_c 20 Jun 2025 03:23:08 -0000 @@ -1,24 +1,98 @@ -Implement getauxval(3) using elf_aux_info(3) to unbreak -riscv64 cpu feature detection. +- ENH: Detect CPU features on OpenBSD ARM and PowerPC64 + d1c67573569885087a253120c1a9f2caf3ccf084 +- ENH: Detect CPU features on FreeBSD / OpenBSD RISC-V64 + 5cbc0bcebbe031140b63d2ffba06b73e471b43b2 Index: numpy/_core/src/common/npy_cpu_features.c --- numpy/_core/src/common/npy_cpu_features.c.orig +++ numpy/_core/src/common/npy_cpu_features.c -@@ -825,6 +825,17 @@ npy__cpu_init_features(void) +@@ -561,7 +561,7 @@ npy__cpu_init_features(void) - #include + #elif defined(NPY_CPU_PPC64) || defined(NPY_CPU_PPC64LE) +-#if defined(__linux__) || defined(__FreeBSD__) ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) + #ifdef __FreeBSD__ + #include // defines PPC_FEATURE_HAS_VSX + #endif +@@ -584,7 +584,7 @@ static void + npy__cpu_init_features(void) + { + memset(npy__cpu_have, 0, sizeof(npy__cpu_have[0]) * NPY_CPU_FEATURE_MAX); +-#if defined(__linux__) || defined(__FreeBSD__) ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) + #ifdef __linux__ + unsigned int hwcap = getauxval(AT_HWCAP); + if ((hwcap & PPC_FEATURE_HAS_VSX) == 0) +@@ -611,7 +611,7 @@ npy__cpu_init_features(void) + npy__cpu_have[NPY_CPU_FEATURE_VSX2] = (hwcap & PPC_FEATURE2_ARCH_2_07) != 0; + npy__cpu_have[NPY_CPU_FEATURE_VSX3] = (hwcap & PPC_FEATURE2_ARCH_3_00) != 0; + npy__cpu_have[NPY_CPU_FEATURE_VSX4] = (hwcap & PPC_FEATURE2_ARCH_3_1) != 0; +-// TODO: AIX, OpenBSD ++// TODO: AIX + #else + npy__cpu_have[NPY_CPU_FEATURE_VSX] = 1; + #if defined(NPY_CPU_PPC64LE) || defined(NPY_HAVE_VSX2) +@@ -675,7 +675,7 @@ npy__cpu_init_features_arm8(void) + npy__cpu_have[NPY_CPU_FEATURE_ASIMD] = 1; + } + +-#if defined(__linux__) || defined(__FreeBSD__) ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) + /* + * we aren't sure of what kind kernel or clib we deal with + * so we play it safe +@@ -686,7 +686,7 @@ npy__cpu_init_features_arm8(void) + #if defined(__linux__) + __attribute__((weak)) unsigned long getauxval(unsigned long); // linker should handle it + #endif +-#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__OpenBSD__) -+static unsigned long getauxval(unsigned long k) -+{ -+ unsigned long val = 0ul; -+ if (elf_aux_info((int)k, (void *)&val, (int)sizeof(val)) != 0) { -+ return 0ul; -+ } -+ return val; -+} + __attribute__((weak)) int elf_aux_info(int, void *, int); // linker should handle it + + static unsigned long getauxval(unsigned long k) +@@ -784,7 +784,7 @@ static void + npy__cpu_init_features(void) + { + memset(npy__cpu_have, 0, sizeof(npy__cpu_have[0]) * NPY_CPU_FEATURE_MAX); +-#ifdef __linux__ ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) + if (npy__cpu_init_features_linux()) + return; + #endif +@@ -823,22 +823,30 @@ npy__cpu_init_features(void) + + #elif defined(__riscv) && __riscv_xlen == 64 + +-#include ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ++ #include + +-#ifndef HWCAP_RVV +- // https://github.com/torvalds/linux/blob/v6.8/arch/riscv/include/uapi/asm/hwcap.h#L24 +- #define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A')) ++ #ifndef HWCAP_RVV ++ // https://github.com/torvalds/linux/blob/v6.8/arch/riscv/include/uapi/asm/hwcap.h#L24 ++ #define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A')) ++ #endif + #endif + + static void + npy__cpu_init_features(void) + { + memset(npy__cpu_have, 0, sizeof(npy__cpu_have[0]) * NPY_CPU_FEATURE_MAX); +- ++#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ++#ifdef __linux__ + unsigned int hwcap = getauxval(AT_HWCAP); ++#else ++ unsigned long hwcap; ++ elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); +#endif -+ - #ifndef HWCAP_RVV - // https://github.com/torvalds/linux/blob/v6.8/arch/riscv/include/uapi/asm/hwcap.h#L24 - #define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A')) + if (hwcap & COMPAT_HWCAP_ISA_V) { + npy__cpu_have[NPY_CPU_FEATURE_RVV] = 1; + } ++#endif + } + + /*********** Unsupported ARCH ***********/