-
-
Notifications
You must be signed in to change notification settings - Fork 12k
Closed
Labels
Milestone
Description
Describe the issue:
numpy 2.4.0 introduces a memory leak that ultimately traces to ites_ass_subscript() and PyArray_IterNew(). Running the same code with 2.3.5 does not show any definitely lost bytes.
Reproduce the code example:
# Run the below using `valgrind --leak-check=full --show-leak-kinds=definite python myproblem.py`
import numpy as np
for _ in range(42):
matrix = np.eye(10, dtype=np.complex128)Error message:
With 2.3.5, valgrind shows no definitely lost, while for 2.4.0:
==26907== HEAP SUMMARY:
==26907== in use at exit: 1,795,829 bytes in 1,168 blocks
==26907== total heap usage: 10,563 allocs, 9,395 frees, 22,379,641 bytes allocated
==26907==
==26907== 110,544 bytes in 42 blocks are definitely lost in loss record 301 of 305
==26907== at 0x4841984: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26907== by 0x5997D59: PyArray_IterNew (in /tmp/numpy_test/lib/python3.11/site-packages/numpy/_core/_multiarray_umath.cpython-311-x86_64-linux-gnu.so)
==26907== by 0x5999174: iter_ass_subscript (in /tmp/numpy_test/lib/python3.11/site-packages/numpy/_core/_multiarray_umath.cpython-311-x86_64-linux-gnu.so)
==26907== by 0x4A75AD8: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4B484F9: PyEval_EvalCode (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD3F4C: ??? (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD3FEB: ??? (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD40C2: ??? (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD43A4: _PyRun_SimpleFileObject (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD4493: _PyRun_AnyFileObject (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD47EA: Py_RunMain (in /usr/lib64/libpython3.11.so.1.0)
==26907== by 0x4BD5528: Py_BytesMain (in /usr/lib64/libpython3.11.so.1.0)
==26907==
==26907== LEAK SUMMARY:
==26907== definitely lost: 110,544 bytes in 42 blocks
==26907== indirectly lost: 0 bytes in 0 blocks
==26907== possibly lost: 183,992 bytes in 103 blocks
==26907== still reachable: 1,501,261 bytes in 1,022 blocks
==26907== suppressed: 32 bytes in 1 blocks
==26907== Reachable blocks (those to which a pointer was found) are not shown.
==26907== To see them, rerun with: --leak-check=full --show-leak-kinds=all
Using instead conda-forge based python3.14.2 shows a very identical output with the same leaks:
==27653== HEAP SUMMARY:
==27653== in use at exit: 1,378,468 bytes in 830 blocks
==27653== total heap usage: 27,163 allocs, 26,333 frees, 181,204,009 bytes allocated
==27653==
==27653== 110,544 bytes in 42 blocks are definitely lost in loss record 235 of 239
==27653== at 0x4841984: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27653== by 0x8D5FF89: PyArray_IterNew (in /tmp/miniforge3/envs/finesse3/lib/python3.14/site-packages/numpy/_core/_multiarray_umath.cpython-314-x86_64-linux-gnu.so)
==27653== by 0x8D6142B: iter_ass_subscript (in /tmp/miniforge3/envs/finesse3/lib/python3.14/site-packages/numpy/_core/_multiarray_umath.cpython-314-x86_64-linux-gnu.so)
==27653== by 0x2F6925: _PyEval_EvalFrameDefault (generated_cases.c.h:11500)
==27653== by 0x2ED947: UnknownInlinedFun (pycore_ceval.h:121)
==27653== by 0x2ED947: _PyEval_Vector (ceval.c:2083)
==27653== by 0x3C9494: PyEval_EvalCode (ceval.c:975)
==27653== by 0x409EAC: run_mod.lto_priv.0 (pythonrun.c:1459)
==27653== by 0x408AB7: pyrun_file.lto_priv.0 (pythonrun.c:1293)
==27653== by 0x4087FE: _PyRun_SimpleFileObject (pythonrun.c:521)
==27653== by 0x4084BC: _PyRun_AnyFileObject (pythonrun.c:81)
==27653== by 0x3BE020: UnknownInlinedFun (main.c:410)
==27653== by 0x3BE020: UnknownInlinedFun (main.c:429)
==27653== by 0x3BE020: UnknownInlinedFun (main.c:694)
==27653== by 0x3BE020: Py_RunMain (main.c:775)
==27653== by 0x3B8046: Py_BytesMain (main.c:829)
==27653==
==27653== LEAK SUMMARY:
==27653== definitely lost: 110,544 bytes in 42 blocks
==27653== indirectly lost: 0 bytes in 0 blocks
==27653== possibly lost: 172,240 bytes in 95 blocks
==27653== still reachable: 1,095,652 bytes in 692 blocks
==27653== suppressed: 32 bytes in 1 blocks
==27653== Reachable blocks (those to which a pointer was found) are not shown.
==27653== To see them, rerun with: --leak-check=full --show-leak-kinds=allPython and NumPy Versions:
OpenSUSE LEAP with python3.11 (using venv and pip to install numpy 2.4.0 or 2.3.5)
2.4.0
3.11.14 (main, Nov 20 2025, 22:16:35) [GCC]
Likewise for a 3.14.2 based conda (using pip to install 2.4.0 or 2.3.5)
2.4.0
3.14.2 | packaged by conda-forge | (main, Dec 6 2025, 11:21:58) [GCC 14.3.0]
Runtime Environment:
[{'numpy_version': '2.4.0',
'python': '3.11.14 (main, Nov 20 2025, 22:16:35) [GCC]',
'uname': uname_result(system='Linux', node='XXXXXX', release='6.18.0-lp156.12.g2fafc8d-default', version='#1 SMP PREEMPT_DYNAMIC Wed Dec 3 02:59:05 UTC 2025 (2fafc8d)', machine='x86_64')},
{'simd_extensions': {'baseline': ['X86_V2'],
'found': ['X86_V3', 'X86_V4', 'AVX512_ICL'],
'not_found': ['AVX512_SPR']}},
{'ignore_floating_point_errors_in_matmul': False},
{'architecture': 'SkylakeX',
'filepath': '/tmp/numpy_test/lib/python3.11/site-packages/numpy.libs/libscipy_openblas64_-fdde5778.so',
'internal_api': 'openblas',
'num_threads': 8,
'prefix': 'libscipy_openblas',
'threading_layer': 'pthreads',
'user_api': 'blas',
'version': '0.3.30'}]
How does this issue affect you or how did you find it:
We found a memleak test in our code https://gitlab.com/ifosim/finesse/finesse3 starting to fail when moving to numpy 2.4.0. For now the test is disabled, but that's obviously suboptimal.