-
-
Notifications
You must be signed in to change notification settings - Fork 12.1k
Description
Describe the issue:
Thanks for the great project! NumPy 2.0 introduced changes to NumPy data type promotion per NEP 50. To opt out of these changes, a developer can set promotion state to legacy. When working with threads, it seems as though promotion state is not consistent. In the following example, the main thread uses the new promotion rules, but the second thread uses legacy promotion rules. This appears to be the behavior of both NumPy 2.1.0 and 2.1.1. In 2.0.0 thru 2.0.2, the second thread uses the new promotion rules. I can recreate this behavior with multiple CPython versions on multiple Linux distros.
Reproduce the code example:
from threading import Thread
import numpy as np
def func(name):
x = np.uint8(100) + 200
print(name, x, type(x))
func("Main thread")
t = Thread(target=func, args=("Second thread",))
t.start()
t.join()Error message:
/home/mark/issue.py:5: RuntimeWarning: overflow encountered in scalar add
x = np.uint8(100) + 200
Main thread 44 <class 'numpy.uint8'>
Second thread 300 <class 'numpy.int64'>Python and NumPy Versions:
2.1.1
3.12.5 (main, Aug 9 2024, 08:20:41) [GCC 14.2.1 20240805]
Runtime Environment:
[{'numpy_version': '2.1.1',
'python': '3.12.5 (main, Aug 9 2024, 08:20:41) [GCC 14.2.1 20240805]',
'uname': uname_result(system='Linux', node='device', release='6.10.6-10-MANJARO', version='#1 SMP PREEMPT_DYNAMIC Sat Aug 24 16:17:40 UTC 2024', machine='x86_64')},
{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2'],
'not_found': ['AVX512F',
'AVX512CD',
'AVX512_KNL',
'AVX512_KNM',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL']}},
{'architecture': 'Haswell',
'filepath': '/home/mark/venv/lib/python3.12/site-packages/numpy.libs/libscipy_openblas64_-ff651d7f.so',
'internal_api': 'openblas',
'num_threads': 16,
'prefix': 'libscipy_openblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.27'}]
Context for the issue:
This was a rather hard issue to track down. The legacy promotion state is silently enabled in the second thread, the legacy rules are to silently allow changes to data types, and this behavior is inconsistent across NumPy versions. In 1.26.x, both threads use legacy rules. In 2.0.x, both threads use the new rules. In 2.1.x, each thread uses different rules. I discovered this issue only after migrating from 1.26 to 2.1, and then downgrading to 2.0 later on to appease a new dependency. Code that behaves variably is hard to debug!