Skip to content

Commit 128d1ae

Browse files
authored
Merge pull request numpy#26750 from ngoldbaum/lapacklite-locking
ENH: Add locking to umath_linalg if no lapack is detected at build time
2 parents 2f3da0d + 97b5a27 commit 128d1ae

File tree

5 files changed

+106
-1
lines changed

5 files changed

+106
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
`lapack_lite` is now thread safe
2+
--------------------------------
3+
4+
NumPy provides a minimal low-performance version of LAPACK named ``lapack_lite``
5+
that can be used if no BLAS/LAPACK system is detected at build time.
6+
7+
Until now, ``lapack_lite`` was not thread safe. Single-threaded use cases did
8+
not hit any issues, but running linear algebra operations in multiple threads
9+
could lead to errors, incorrect results, or seg faults due to data races.
10+
11+
We have added a global lock, serializing access to ``lapack_lite`` in multiple
12+
threads.

numpy/_core/config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
#mesondefine HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE
109109
#mesondefine HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE
110110

111+
#mesondefine HAVE_EXTERNAL_LAPACK
112+
111113
#ifndef __cplusplus
112114
/* #undef inline */
113115
#endif

numpy/_core/meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,10 @@ if cc.has_function_attribute('visibility:hidden') and host_machine.system() != '
506506
endif
507507
cdata.set('NPY_VISIBILITY_HIDDEN', visibility_hidden)
508508

509+
# if not set, we're using lapack_lite
510+
if have_lapack
511+
cdata.set10('HAVE_EXTERNAL_LAPACK', have_lapack)
512+
endif
509513

510514
config_h = configure_file(
511515
input: 'config.h.in',

numpy/_core/tests/test_multithreading.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,16 @@ def func(count):
7171
(alarge + blarge) - 2
7272

7373
run_threaded(func, 100, pass_count=True)
74+
75+
76+
def test_eigvalsh_thread_safety():
77+
# if lapack isn't thread safe this will randomly segfault or error
78+
# see gh-24512
79+
rng = np.random.RandomState(873699172)
80+
matrices = (
81+
rng.random((5, 10, 10, 3, 3)),
82+
rng.random((5, 10, 10, 3, 3)),
83+
)
84+
85+
run_threaded(lambda i: np.linalg.eigvalsh(matrices[i]), 2,
86+
pass_count=True)

0 commit comments

Comments
 (0)