Skip to content

Support for NumPy 2.0 in Neo Core - #1490

Merged
alejoe91 merged 40 commits into
NeuralEnsemble:masterfrom
zm711:numpy-2-0
Dec 13, 2024
Merged

alejoe91 merged 40 commits into
NeuralEnsemble:masterfrom
zm711:numpy-2-0

Conversation

@zm711

@zm711 zm711 commented Jun 18, 2024

Copy link
Copy Markdown
Contributor

following a policy of NEP 29 + 1 year.

@zm711

zm711 commented Jun 18, 2024

Copy link
Copy Markdown
Contributor Author

Looks like we have some work to do :)

@apdavison

Copy link
Copy Markdown
Member

note that quantities 0.16.0, with support for NumPy 2.0, has just been released

@zm711

zm711 commented Aug 27, 2024

Copy link
Copy Markdown
Contributor Author

I updated the branch so we should see the neo problems vs the quantities in the testing!

@zm711

zm711 commented Aug 27, 2024 •

Copy link
Copy Markdown
Contributor Author

I think @JuliaSprenger saw this error before right?

AssertionError: array(99.) * mV == array(99.) * mV

Actually this is an example of an error related to the fact we no longer have the copy behavior. this test was an assertNotEqual, but because the data is now a copy we edited in place and so the array is the same when it shouldn't be.

@zm711

zm711 commented Oct 17, 2024

Copy link
Copy Markdown
Contributor Author

Let's squash this one when it is ready. A lot of this is me tweaking the action and then messing up on one version. So a lot of these are trash commits.

@zm711

zm711 commented Oct 17, 2024 •

Copy link
Copy Markdown
Contributor Author

Okay current core failures can be reproduced with the following:

>>> import quantities as pq
>>> import numpy as np
>>> times = np.arange(10, dtype=np.float32)
>>> times.dtype
'float32'
>>> times= times * pq.ms
>>> times.dtype
'float64'

and for the other failing test

>>> import quantities as pq
>>> import numpy as np
>>> times = [1,2,3] * pq.s
>>> np.concatenate((times, times))
array([1,2,3,1,2,3]) * dimensionless

I need to read more about numpy 2.0 changes to figure out these parts of the tests that have changed. Any ideas @apdavison and @samuelgarcia ?

The first issue seems like it could be numpy but the second issue seems like quantities needs to hand np.concatenate better no?

@zm711

zm711 commented Oct 17, 2024

Copy link
Copy Markdown
Contributor Author

Actually it was a change in default numpy behavior which requires an extra as type in tests. My bad.

Comment thread neo/core/spiketrain.py
omitted_keys_other = [
key
for key in np.unique([key for other in others for key in other.array_annotations])
for key in set([key for other in others for key in other.array_annotations])

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only actual change to code base. numpy 2.0 returns this as a np.str_ thing rather than as the actual string. Using set instead of np.unique returns the string both >2.0 and < 2.0 for NumPy. Maybe a slight performance hit, but probably not too bad since the annotations should be small either way and this is in a list and not array.

@zm711 zm711 changed the title Update core-tests to see Numpy 2.0 problem points Support for NumPy 2.0 in Neo Core Oct 18, 2024
@zm711

zm711 commented Oct 18, 2024 •

Copy link
Copy Markdown
Contributor Author

Also a reminder please squash before merge and let's at minimum wait until after the point release :)

@zm711 zm711 mentioned this pull request Oct 18, 2024
sorting = np.argsort(expected)
expected = expected[sorting]
np.testing.assert_array_equal(result.times, expected)
np.testing.assert_array_equal(result.times.magnitude, expected.magnitude)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is necessary because as of numpy 2.0 because numpy assert_array_equal actually checks that the quantities are the same which leads to a units issue. If someone else understands this better please post here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is annoying @apdavison any comments ?

@zm711

zm711 commented Oct 18, 2024 •

Copy link
Copy Markdown
Contributor Author

RTD is not building the correct version of neo. I don't know why. Maybe I just need to give it a little time (I had hoped switching to 3.12 would flush any cache, but it still had the wrong Neo and it had other errors). I'll just try to rerun RTD build this weekend and see if time fixes it.

@zm711

zm711 commented Oct 21, 2024

Copy link
Copy Markdown
Contributor Author

Sam and I looked over the RTD failure and we aren't sure why it is happening. I think it should fix itself once this is merged into main since the problem showing up is fixed in main.

Comment on lines 315 to +319
times = np.arange(10, dtype="f4") * pq.ms
# this step is required for NumPy 2.0 which now casts to float64 in the case either value/array
# is float64 even if not necessary
# https://numpy.org/devdocs/numpy_2_0_migration_guide.html
times = times.astype(dtype="f4")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on discussion with Sam my comment may not have been clear enough. The problem is that
1* pq.ms is at baseline at 'float64' and as of numpy 2.0+ everything is up-cast to the bigger dtype even if not necessarily. So in old versions of our test times would remain a float32, but with new versions of numpy make it into a 'float64'. I did the astype to keep our original idea explict, but we could think of other rewrites of this test to maintain the dtype test.

@zm711

zm711 commented Oct 28, 2024

Copy link
Copy Markdown
Contributor Author

@apdavison this is ready for review, the RTD is broken with some cache issue, but I fixed the problem on main (and merging main into this branch didn't fix it). so our options are you review and merge ignoring the RTD problem or I open a new PR built off of the current main and make the exact same fixes to make sure all tests pass. What's your preference?

@alejoe91
alejoe91 merged commit 830c461 into NeuralEnsemble:master Dec 13, 2024
@zm711
zm711 deleted the numpy-2-0 branch December 13, 2024 15:15
@samuelgarcia

Copy link
Copy Markdown
Contributor

thanks for for @zm711 @apdavison and @alejoe91

I did not folow so much. Does finally we are making a copy of the buffer every time we create a data object from numpy or not ?

@zm711

zm711 commented Jan 6, 2025

Copy link
Copy Markdown
Contributor Author

It should force the user to return a view rather than a copy. So if someone wants to change the dtype at initialization they can't create a copy anymore at that stage. So they have to return the view and then change the dtype themselves (which will make the copy later). Same is true for quantity units. They can no longer change units at initialization. They have to do it later and make a copy at that time.

I think a couple structures may need to copy the view at a few places because of the views, but globally everything should start out as views.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants