Skip to content

Commit c2055ba

Browse files
mattipngoldbaum
authored andcommitted
MAINT: update openblas to 0.3.33.112.0 (#31649)
Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
1 parent ce17c81 commit c2055ba

3 files changed

Lines changed: 66 additions & 3 deletions

File tree

numpy/_core/tests/test_multithreading.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,69 @@ def test_eigvalsh_thread_safety():
8989
pass_count=True)
9090

9191

92+
def _detected_blas():
93+
blas = np.show_config('dicts').get('Build Dependencies', {}).get('blas', {})
94+
return blas.get('name', 'unknown'), blas.get('version', 'unknown')
95+
96+
97+
def _openblas_predates_gemm_fix(name, version):
98+
if 'openblas' not in name:
99+
return False
100+
try:
101+
parsed = tuple(int(p) for p in version.split('.'))
102+
except ValueError:
103+
return False
104+
return parsed < (0, 3, 33, 112)
105+
106+
107+
def test_blas_gemm_thread_safety():
108+
# gh-31618: concurrently run transpose and no-transpose GEMM variants to
109+
# exercise possible thread safety issues due to lock sharding between
110+
# kernels, see OpenBLAS issue #5836.
111+
num_threads = 8
112+
num_iters = 10
113+
M = 512 * 512
114+
115+
rng = np.random.default_rng(0x9e3779b9)
116+
no_trans = rng.random((M, 4)) # C-contiguous -> NoTrans GEMM
117+
no_trans_w = rng.random((4, 2))
118+
trans = rng.random((2, M)).T # F-contiguous -> Trans GEMM
119+
trans_w = rng.random((2, 2))
120+
expected_no_trans = no_trans @ no_trans_w
121+
expected_trans = trans @ trans_w
122+
123+
mismatches = 0
124+
lock = threading.Lock()
125+
126+
def closure(i, b):
127+
nonlocal mismatches
128+
count = 0
129+
for _ in range(num_iters):
130+
b.wait()
131+
if i % 2:
132+
ok = np.array_equal(no_trans @ no_trans_w, expected_no_trans)
133+
else:
134+
ok = np.array_equal(trans @ trans_w, expected_trans)
135+
if not ok:
136+
count += 1
137+
with lock:
138+
mismatches += count
139+
140+
run_threaded(closure, num_threads, pass_count=True, pass_barrier=True)
141+
142+
blas_name, blas_version = _detected_blas()
143+
if mismatches and _openblas_predates_gemm_fix(blas_name, blas_version):
144+
pytest.xfail(
145+
f"OpenBLAS version ({blas_version}) predates first OpenBLAS "
146+
"version with a fix (0.3.33.112)"
147+
)
148+
149+
assert mismatches == 0, (
150+
f"{mismatches} concurrent matmul results were corrupted "
151+
f"({blas_name} {blas_version})"
152+
)
153+
154+
92155
def test_printoptions_thread_safety():
93156
# until NumPy 2.1 the printoptions state was stored in globals
94157
# this verifies that they are now stored in a context variable

requirements/ci32_requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
spin
22
# Keep this in sync with ci_requirements.txt
3-
scipy-openblas32==0.3.33.0.0
3+
scipy-openblas32==0.3.33.112.0

requirements/ci_requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
spin
22
# Keep this in sync with ci32_requirements.txt
3-
scipy-openblas32==0.3.33.0.0
4-
scipy-openblas64==0.3.33.0.0
3+
scipy-openblas32==0.3.33.112.0
4+
scipy-openblas64==0.3.33.112.0

0 commit comments

Comments
 (0)