Skip to content

BUG: NumPy 2.3.0 regression - corrupted array values #29038

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
user27182 opened this issue May 23, 2025 · 4 comments · Fixed by #29041
Closed

BUG: NumPy 2.3.0 regression - corrupted array values #29038

user27182 opened this issue May 23, 2025 · 4 comments · Fixed by #29041
Labels

Comments

@user27182
Copy link

Describe the issue:

Hi,
At PyVista, we test against the numpy nightly wheels. Our tests recently failed and a patch (pyvista/pyvista#7538) was needed to fix the tests. However, I think this patch should not be needed, and is in fact a regression with numpy (i.e. a bug has been introduced).

I locally checked out, installed, and tested against recent commits to main and found that the regression is caused by #29006

As mentioned in pyvista/pyvista#7538, our tests usually pass with

assert np.array_equal([42], [42])

But with #29006, we are getting variable results like:

assert np.array_equal([1], [42])
assert np.array_equal([44636345150720], [42])

I don't really understand the changes in #29006 or how they might cause this, but from our end the error is generated for a special case where our code creates a temporary object internally to store the array, and it seems the reference to the array is being lost somehow or pre-maturely freed, causing the array values to be corrupted.

The code below fails with commit 0506cf6, but succeeds with c2d5e00 (i.e. the commit immediately preceding). I tried creating a minimal example using only numpy, but the references to the array are complex and difficult to reproduce since PyVista wraps a lower-level C++ package (VTK) which also holds its own references to the array data.

Reproduce the code example:

import pyvista as pv 
import numpy as np

# Define an array-like input
key = 'data'
value = [42]

# Store the array with a container
# internally, the array is cast as an `ndarray` instance
multi = pv.MultiBlock()
multi.field_data[key] = value

# Nest the container into another
name = 'nested'
root = pv.MultiBlock({name:multi})

# Move the array from the nested container to the root.
# Internally, this method will use a temp object to store the array
separator = '::'
root.move_nested_field_data_to_root(field_data_mode='prepend', separator=separator)

# The root container should now contain the values from the nested 
# array that was moved to the root
new_key = name + separator + key
assert np.array_equal(root.field_data[new_key], value)  # ERROR

Error message:

N/A

Python and NumPy Versions:

2.3.0.dev0+git20250519.0506cf6
3.12.2 (v3.12.2:6abddd9f6a, Feb 6 2024, 17:02:06) [Clang 13.0.0 (clang-1300.0.29.30)]

Runtime Environment:

No response

Context for the issue:

This bug seems to cause arrays to be pre-maturely gc'd in some cases, which should probably be avoided. And the root cause has been identified, meaning that the fix can be easily implemented with a simple revert.

@seberg
Copy link
Member

seberg commented May 23, 2025

There is a bug here in that the commit shouldn't have changed anything but got the logic wrong and disabled the caching often!
Nice sleuthing that this is the commit that changed it.

However, it's unclear that the underlying issue here is NumPy and not just made visible by this change. A possible place where this could arise is if you use where=... togeether with out=... (which leaves data uninitialized), but more likely is a C level bug somewhere.

I had hoped valgrind would throw something, but it didn't (with pv == 45.2), if you are on linux, maybe try running yourself with just:

PYTHONMALLOC=malloc valgrind ipython

(put the imports on their own, they'll probably create some false positives). Sanitizers are great, but valgrind has zero setup-cost if it works.

meaning that the fix can be easily implemented with a simple revert.

Yeah, and revert we should. But the problem is that this change is correct, there is an real underlying bug just hidden by the caching and if you just make the array larger you may always run into it.

EDIT: Milestone for the revert, not to find an underlying issue (which I still think has a good chance of not being in NumPy).

@seberg
Copy link
Member

seberg commented May 23, 2025

Didn't mean to auto-close, there is still an issue even if I think it is at least as likely to be an issue downstream. That said, I guess we can close it soon without follow up from you @user27182.

Again the PR change wasn't a bug (except that it should have been a speed regression) it just made a bug more visible.

@seberg seberg reopened this May 23, 2025
@user27182
Copy link
Author

This does appear to have resolved the issue with our failed test, thanks @seberg! I tested this fix locally but was going to wait until our CI passed again with the nightly wheels before confirming here.

@user27182
Copy link
Author

Can confirm that the initial test failure caused by #29006 has been fixed by #29041, and our CI is green again after reverting our patch (pyvista/pyvista#7540). Thanks again @seberg.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy