1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
DISTUTILS_EXT=1
DISTUTILS_USE_PEP517=meson-python
PYTHON_COMPAT=( python3_{11..14} pypy3_11 )
PYTHON_REQ_USE="threads(+)"
FORTRAN_NEEDED=lapack
inherit distutils-r1 flag-o-matic fortran-2 pypi
DESCRIPTION="Fast array and numerical python library"
HOMEPAGE="
https://numpy.org/
https://github.com/numpy/numpy/
https://pypi.org/project/numpy/
"
LICENSE="BSD"
SLOT="0/2"
KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
# +lapack because the internal fallbacks are pretty slow. Building without blas
# is barely supported anyway, see bug #914358.
IUSE="big-endian +cpudetection +lapack"
# upstream-flag[:gentoo-flag]
ARM_FLAGS=( neon{,-fp16} vfpv4 asimd{,hp,dp,fhm} sve )
PPC_FLAGS=( vsx vsx2 vsx3 vsx4 )
X86_FLAGS=(
sse{,2,3,4_1,4_2} ssse3 popcnt avx{,2} xop fma{3,4}
f16c avx512{f,cd,pf,er,dq,bw,vl,ifma,vbmi}
avx512_{vpopcntdq,4vnniw,4fmaps,vbmi2,bitalg,fp16,vnni}
)
IUSE+="
${ARM_FLAGS[*]/#/cpu_flags_arm_}
${PPC_FLAGS[*]/#/cpu_flags_ppc_}
${X86_FLAGS[*]/#/cpu_flags_x86_}
"
RDEPEND="
lapack? (
>=virtual/cblas-3.8
>=virtual/lapack-3.8
)
"
BDEPEND="
${RDEPEND}
>=dev-build/meson-1.5.2
>=dev-python/cython-3.0.6[${PYTHON_USEDEP}]
lapack? (
virtual/pkgconfig
)
test? (
$(python_gen_cond_dep '
>=dev-python/cffi-1.14.0[${PYTHON_USEDEP}]
' 'python*')
dev-python/charset-normalizer[${PYTHON_USEDEP}]
>=dev-python/pytz-2019.3[${PYTHON_USEDEP}]
)
"
QA_CONFIG_IMPL_DECL_SKIP=(
# https://bugs.gentoo.org/925367
vrndq_f32
)
EPYTEST_PLUGINS=( hypothesis pytest-timeout )
EPYTEST_XDIST=1
distutils_enable_tests pytest
PATCHES=(
# https://github.com/numpy/numpy/pull/29459
"${FILESDIR}"/${P}-no-detect.patch
# https://github.com/numpy/numpy/pull/29579
"${FILESDIR}"/${P}-arm-asimddp.patch
)
has_all_x86() {
local flag
for flag; do
if ! use "cpu_flags_x86_${flag}"; then
return 1
fi
done
return 0
}
python_configure_all() {
local cpu_baseline=()
local map flag
case ${ARCH} in
arm)
# every flag implies the previous one
for map in NEON:neon NEON_FP16:neon-fp16 NEON_VFPV4:vfpv4; do
if ! use "cpu_flags_arm_${map#*:}"; then
break
fi
cpu_baseline+=( "${map%:*}" )
done
;&
arm64)
# on 32-bit ARM, ASIMD implies all NEON* flags
# on 64-bit ARM, they are all linked together
if use arm64 ||
[[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == NEON_VFPV4 ]]
then
cpu_baseline+=( $(usev cpu_flags_arm_asimd ASIMD) )
fi
# these two imply ASIMD
if [[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == ASIMD ]]; then
for flag in dp hp; do
cpu_baseline+=(
$(usev "cpu_flags_arm_asimd${flag}" "ASIMD${flag^^}")
)
done
fi
# these two imply ASIMDHP
if [[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == ASIMDHP ]]; then
for flag in asimdfhm sve; do
cpu_baseline+=(
$(usev "cpu_flags_arm_${flag}" "${flag^^}")
)
done
fi
;;
ppc64)
# every flag implies the previous one
for flag in '' 2 3 4; do
if ! use "cpu_flags_ppc_vsx${flags}"; then
break
fi
cpu_baseline+=( "VSX${flag}" )
done
;;
amd64|x86)
# every flag implies the previous one
for flag in sse{,2,3} ssse3 sse4_1 popcnt sse4_2 avx; do
if ! use "cpu_flags_x86_${flag}"; then
break
fi
flag=${flag/_}
cpu_baseline+=( "${flag^^}" )
done
# these imply AVX
if [[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == AVX ]]; then
for flag in xop fma4 f16c; do
if use "cpu_flags_x86_${flag}"; then
cpu_baseline+=( "${flag^^}" )
fi
done
fi
# another chain started on implying F16C
if [[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == F16C ]]; then
for flag in fma3 avx2 avx512f avx512cd; do
if ! use "cpu_flags_x86_${flag}"; then
break
fi
cpu_baseline+=( "${flag^^}" )
done
fi
if [[ ${cpu_baseline[@]} && ${cpu_baseline[-1]} == AVX512CD ]]; then
# upstream combines multiple instructions into per-CPU sets
local -A avx512_mapping=(
[AVX512_KNL]="avx512pf avx512er"
[AVX512_KNM]="avx512_vpopcntdq avx512_4vnniw avx512_4fmaps"
[AVX512_SKX]="avx512dq avx512bw avx512vl"
[AVX512_CLX]="avx512_vnni"
[AVX512_CNL]="avx512ifma avx512vbmi"
[AVX512_ICL]="avx512_vbmi2 avx512_bitalg"
[AVX512_SPR]="avx512_fp16"
)
# 1. AVX512CD -> AVX512_KNL -> AVX512_KNM
if has_all_x86 ${avx512_mapping[AVX512_KNL]}; then
cpu_baseline+=( AVX512_KNL )
if has_all_x86 ${avx512_mapping[AVX512_KNM]}; then
cpu_baseline+=( AVX512_KNM )
fi
fi
# 2. AVX512CD -> AVX512_SKX -> [AVX512_CLX, AVX512_CNL]
if has_all_x86 ${avx512_mapping[AVX512_SKX]}; then
cpu_baseline+=( AVX512_SKX )
if has_all_x86 ${avx512_mapping[AVX512_CLX]}; then
cpu_baseline+=( AVX512_CLX )
fi
if has_all_x86 ${avx512_mapping[AVX512_CNL]}; then
cpu_baseline+=( AVX512_CNL )
fi
fi
# 3. [AVX512_CLX, AVX512_CNL] -> AVX512_ICL -> AVX512_SPR
if [[ ${cpu_baseline[-1]} == AVX512_CNL &&
${cpu_baseline[-2]} == AVX512_CLX ]]
then
if has_all_x86 ${avx512_mapping[AVX512_ICL]}; then
cpu_baseline+=( AVX512_ICL )
if has_all_x86 ${avx512_mapping[AVX512_SPR]}; then
cpu_baseline+=( AVX512_SPR )
fi
fi
fi
fi
;;
*)
cpu_baseline=MIN
;;
esac
DISTUTILS_ARGS=(
-Dallow-noblas=$(usex !lapack true false)
-Dblas=$(usev lapack cblas)
-Dlapack=$(usev lapack lapack)
-Dcpu-baseline="${cpu_baseline[*]}"
-Dcpu-baseline-detect=disabled
# '-XOP -FMA4' is upstream default, since these are deprecated
-Dcpu-dispatch="$(usev cpudetection 'MAX -XOP -FMA4')"
)
# bug #922457
filter-lto
# https://github.com/numpy/numpy/issues/25004
append-flags -fno-strict-aliasing
}
python_test() {
# don't run tests that require more than 2 GiB of RAM (per process)
local -x NPY_AVAILABLE_MEM="2 GiB"
local EPYTEST_DESELECT=(
# Very disk-and-memory-hungry
numpy/lib/tests/test_io.py::TestSavezLoad::test_closing_fid
numpy/lib/tests/test_io.py::TestSavezLoad::test_closing_zipfile_after_load
# Precision problems
numpy/_core/tests/test_umath_accuracy.py::TestAccuracy::test_validate_transcendentals
numpy/typing/tests/test_typing.py
# Flaky, reruns don't help
numpy/f2py/tests/test_crackfortran.py
numpy/f2py/tests/test_f2py2e.py::test_gh22819_cli
numpy/f2py/tests/test_data.py::TestDataF77::test_crackedlines
)
if [[ $(uname -m) == armv8l ]]; then
# Degenerate case of arm32 chroot on arm64, bug #774108
EPYTEST_DESELECT+=(
numpy/_core/tests/test_cpu_features.py::Test_ARM_Features::test_features
)
fi
case ${ARCH} in
arm)
EPYTEST_DESELECT+=(
# TODO: warnings
numpy/_core/tests/test_umath.py::TestSpecialFloats::test_unary_spurious_fpexception
# TODO
numpy/_core/tests/test_function_base.py::TestLinspace::test_denormal_numbers
numpy/f2py/tests/test_kind.py::TestKind::test_real
numpy/f2py/tests/test_kind.py::TestKind::test_quad_precision
# require too much memory
'numpy/_core/tests/test_multiarray.py::TestDot::test_huge_vectordot[complex128]'
'numpy/_core/tests/test_multiarray.py::TestDot::test_huge_vectordot[float64]'
)
;;
hppa)
EPYTEST_DESELECT+=(
# https://bugs.gentoo.org/942689
"numpy/_core/tests/test_dtype.py::TestBuiltin::test_dtype[int]"
"numpy/_core/tests/test_dtype.py::TestBuiltin::test_dtype[float]"
"numpy/_core/tests/test_dtype.py::TestBuiltin::test_dtype_bytes_str_equivalence[datetime64]"
"numpy/_core/tests/test_dtype.py::TestBuiltin::test_dtype_bytes_str_equivalence[timedelta64]"
"numpy/_core/tests/test_dtype.py::TestBuiltin::test_dtype_bytes_str_equivalence[<f]"
"numpy/_core/tests/test_dtype.py::TestPickling::test_pickle_dtype[dt28]"
numpy/f2py/tests/test_kind.py::TestKind::test_real
numpy/f2py/tests/test_kind.py::TestKind::test_quad_precision
numpy/tests/test_ctypeslib.py::TestAsArray::test_reference_cycles
numpy/tests/test_ctypeslib.py::TestAsArray::test_segmentation_fault
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_scalar
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_subarray
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_structure
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_structure_aligned
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_union
numpy/tests/test_ctypeslib.py::TestAsCtypesType::test_padded_union
)
;;
ppc|x86)
EPYTEST_DESELECT+=(
# require too much memory
'numpy/_core/tests/test_multiarray.py::TestDot::test_huge_vectordot[complex128]'
'numpy/_core/tests/test_multiarray.py::TestDot::test_huge_vectordot[float64]'
)
;;
esac
if [[ ${CHOST} == powerpc64le-* ]]; then
EPYTEST_DESELECT+=(
# long double thingy
numpy/_core/tests/test_scalarprint.py::TestRealScalars::test_ppc64_ibm_double_double128
)
fi
if use big-endian; then
EPYTEST_DESELECT+=(
# ppc64 and sparc
numpy/linalg/tests/test_linalg.py::TestDet::test_generalized_sq_cases
numpy/linalg/tests/test_linalg.py::TestDet::test_sq_cases
"numpy/f2py/tests/test_return_character.py::TestFReturnCharacter::test_all_f77[s1]"
"numpy/f2py/tests/test_return_character.py::TestFReturnCharacter::test_all_f77[t1]"
"numpy/f2py/tests/test_return_character.py::TestFReturnCharacter::test_all_f90[s1]"
"numpy/f2py/tests/test_return_character.py::TestFReturnCharacter::test_all_f90[t1]"
)
fi
if ! has_version -b "~${CATEGORY}/${P}[${PYTHON_USEDEP}]" ; then
# depends on importing numpy.random from system namespace
EPYTEST_DESELECT+=(
'numpy/random/tests/test_extending.py::test_cython'
)
fi
if has_version ">=dev-python/setuptools-74[${PYTHON_USEDEP}]"; then
# msvccompiler removal
EPYTEST_DESELECT+=(
numpy/tests/test_public_api.py::test_all_modules_are_expected_2
numpy/tests/test_public_api.py::test_api_importable
)
EPYTEST_IGNORE+=(
numpy/distutils/tests/test_mingw32ccompiler.py
numpy/distutils/tests/test_system_info.py
)
fi
cd "${BUILD_DIR}/install$(python_get_sitedir)" || die
epytest
}
python_install_all() {
local DOCS=( LICENSE.txt README.md THANKS.txt )
distutils-r1_python_install_all
}
|