| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
How about if not isinstance(a, dtype): return a.astype(pack_fields(a.dtype))
Sorry, something went wrong.
There was a problem hiding this comment.
And fields reordered in memory
Sorry, something went wrong.
There was a problem hiding this comment.
Oh right I forgot about reordering. Will think about it tomorrow.
Sorry, something went wrong.
|
I'd rather not introduced any more global state into numpy, to avoid running into #9444 in more places. The legacy mode changes are alright, because nothing apart from doc tests should depend on them - but real code is likely to want to turn on this behavior. |
Sorry, something went wrong.
|
Here's a few different non-configurable ways we could go forward, which I would be OK with:
|
Sorry, something went wrong.
That actually doesn't seem too awful. It would be even better if we could preserve the view behavior under a different API, perhaps: a[['field3', 'field1']] # master creates a view, proposal copies a.view(a.dtype[['field3', 'field1']]) # a view no matter what |
Sorry, something went wrong.
|
I want to collect some past discussions on this issue: We discussed multifield-views more extensively in #350 and briefly in #5994 and #3641. This change has been originally planned as far back as numpy 1.7. It was mentioned as a FutureWarning in the 1.8 release note. I also found these mailing list threads. ★ means more important.
I think if that we want to argue in favor of the change, there is clearly a long history of planning and warning about it. As a reminder of reported issues caused by the copy->view change, we have:
|
Sorry, something went wrong.
|
While there is a history of planning and warning, it seems that support for the non-contiguous dtypes it creates was a gap in our preparation - depending on how much more we want to squeeze into 1.14.1, it might be better to roll back views for now to give us time to think about the right way to fix this problem in 1.15. |
Sorry, something went wrong.
|
Yes, that is what I'm thinking too. The problems caused by the new behavior really boil down to two issues: #10409 for views, and #10387 for save/load. If we delay this change until later, I am pretty sure we can fix #10387 before then so that it will not be a problem. I'd guess #10387 is the one causing the most test failures, too. But I think #10409 will cause unavoidable downstream code-breakage if we return a padded view. The best we can do is introduce pack_fields now, and perhaps add more warnings so people start using it. I suspect that this problem is the rarer one. |
Sorry, something went wrong.
|
Updated. Now we keep the copy behavior for 1.14, to be changed for real in 1.15, hopefully. I added back all the deprecation warning tests. By the way, those people who ran across the view issue of #10409 have quite surely been getting big FutureWarnings from numpy. No excuses! In these latest changes I kept a simplified version of the np.multifield_index_view setting, but made it mostly "secret". See the new documentation section in this PR for details. Test failure is not real, it's due to #10425 |
Sorry, something went wrong.
There was a problem hiding this comment.
Extracted to #10431
Sorry, something went wrong.
|
If there are no objections from devs at this point, later today or tomorrow I'll post to the list about this PR and how we are reverting and pushing the copy->view change to 1.15. I don't expect anyone will object, but maybe users who were affected have extra ideas we could implement. |
Sorry, something went wrong.
|
Disclaimer: I've followed along but didn't have enough time to read all the history in linked issues/threads. Opinions:
So if you still want to make the change in 1.15.0, a clear story about the pros/cons of just that change would be good to see. Also, was introducing np.pack_fields proposed on the mailing list? It may be a useful utility, but doesn't seem to deserve being in the top-level namespace. |
Sorry, something went wrong.
|
Yes, we got rid of the global state (except... I kept it in hidden form for dev purposes), and are planning to revert. We can also move np.pack_fields to the np.rec submodule which has similar methods. I'll incorporate your other points into the email this weekend. |
Sorry, something went wrong.
|
IIRC, I did do a preliminary run at replacing the deprecation with a view several releases ago, but ran into the same problem of filler bytes and a failing test, so never followed through. Another thing we should revisit is the diagonal view replacing a copy. |
Sorry, something went wrong.
|
I changed the PR title, might want to check that. Does this also fix #10409? |
Sorry, something went wrong.
|
Couple of failing tests. |
Sorry, something went wrong.
There was a problem hiding this comment.
The addition of PyArrayEquivTypes here, (the only real change), is so that code in records.py like arr.view((np.record, arr.dtype)) doesn't complain.
That kind of view doesn't change the memory layout so is save to keep in 1.16.
Sorry, something went wrong.
There was a problem hiding this comment.
Why are we using C-style comments again? If we have a good reason, it seems our tests ought to be catching this...
Sorry, something went wrong.
There was a problem hiding this comment.
Yes, no test catches this. But it is in the style guide.
We did release 1.13 with these comments present and no-one complained, so maybe it is harmless. We fixed them in the 1.14 branch though.
Also, a grep shows that there is only one other place in numpy with a C++ comment, in common.c, which was also added by me in 2016. If we want to remove all C++ comments, I could fix that one into this PR too.
Sorry, something went wrong.
There was a problem hiding this comment.
We do it because there used to be compilers that didn't accept the C++ style comments. We can probably drop this when we go to c99, although mixed comment styles can be a bit annoying. We should probably test for that, -ansi might detect that, although it could give us other errors. IIRC, it didn't work (many years ago).
Sorry, something went wrong.
There was a problem hiding this comment.
Right, although given that no-one complained in 1.13 it seems no-one building numpy uses incompatible compilers any more.
In any case, I just made the change in common.c in this PR, so now numpy is totally free of C++ comments.
Sorry, something went wrong.
There was a problem hiding this comment.
"selecting multiple fields" is a better pattern to look for here (possible with leading/trailing .*)
Sorry, something went wrong.
|
@ahaldane Should this be applied before or after the branch? The latter will leave master as is. |
Sorry, something went wrong.
|
Let's do it before the branch. It is easy to remove the unneeded parts when the time comes, and it will make the future update/change more explicit in the commit history. |
Sorry, something went wrong.
|
Thanks Allan. |
Sorry, something went wrong.
| } | ||
|
|
||
| NPY_INLINE static PyObject * | ||
| npy_import(const char *module, const char *attr) |
There was a problem hiding this comment.
Why was this function added?
Sorry, something went wrong.
There was a problem hiding this comment.
Oh... I thought it was used in _multifield_view_to_copy, but I must have removed that. Yes, I think it was related to the config variabel that I removed.
I'll make a followup to remove this.
Sorry, something went wrong.
Numpy attempted to release a feature in 1.14.0, numpy/numpy#6053 which was then reverted in 1.14.1 with numpy/numpy#10411 And then was finally released in 1.16 by numpy/numpy#12447 This also makes a minor enhancement to determines which numpy function should be used at import time instead of run time. The function name was also then updated from _make_sliced_dtype_np_ge_14 to _make_sliced_dtype_np_ge_16 as thats the primary version the feature was released in
Numpy attempted to release a feature in 1.14.0, numpy/numpy#6053 which was then reverted in 1.14.1 with numpy/numpy#10411 And then was finally released in 1.16 by numpy/numpy#12447 This also makes a minor enhancement to determines which numpy function should be used at import time instead of run time. The function name was also then updated from _make_sliced_dtype_np_ge_14 to _make_sliced_dtype_np_ge_16 as thats the primary version the feature was released in
Numpy attempted to release a feature in 1.14.0, numpy/numpy#6053 which was then reverted in 1.14.1 with numpy/numpy#10411 And then was finally released in 1.16 by numpy/numpy#12447 This also makes a minor enhancement to determines which numpy function should be used at import time instead of run time. The function name was also then updated from _make_sliced_dtype_np_ge_14 to _make_sliced_dtype_np_ge_16 as thats the primary version the feature was released in
| Back | FazBrowse Home | New Git URL |
Fixes #10387
Fixes #10344
This is a potential fix to the multifield-indexing bugs in 1.14.0 caused by how easy it is now to get a structured array with padding bytes, which trigger other old bugs like #3176, #8100.
Changed Behavior
This PR reverts the change in 1.14.0 that a multifield-index returns a view instead of a copy, but we plan to make the change in 1.15. That is:
1.13 behavior:
1.14.0 behavior (pushed off to 1.15):
Summary of the problem
Why revert? The problem boils down to padding bytes. Compare the 1.13 to 1.14.0 output above, and note how there are "padding" or missing bytes at offset 4 in the structure in 1.14.0, and how the itemsize is different. The 1.13 behavior essentially returns a copy of the 1.14 output, but with the fields re-packed so that they are contiguous. The two ways users are affected were:
A) Code that attempts to "view" the result, as in:
>>> a[['a', 'c']].view('i8') array([0, 0, 0])In 1.13 this works fine, since the indexed array has an itemsize of 8, but in 1.14.0 this now fails since the itemsize of the view is still 12.
B) Code that attempts to use np.load/np.save to save these arrays, as in:
>>> np.save('file', a[['a', 'c']]) >>> np.load('file')This fails because of another long-standing bug, that currently np.load cannot handle structured arrays with padding bytes, #8100. In 1.13 this bug was not triggered because there were no padding bytes, but in 1.14.0 they now appear often.
Proposed Way Forward:
Revert the copy-> view change, and leave it for 1.15.
That way, we have time to fix #8100 by then, solving problem B).
Problem A) will still cause broken code, but we hope to mitigate this by introducing a new method pack_fields in this PR for 1.14.1, which allows convertsion of the 1.15 output into the 1.13 output:
See comments below for more discussion. Also see the "documentation" updates at the end of the diff for a description of the proposed behavior, under "Accessing Multiple Fields".
(Old outdated summary, for reference)
This PR implements a couple different possible behaviors and makes them user-configurable; we can decide in discussion which one we want, which should be default, or which to remove. You control the behavior by setting the variable np.multifield_index_setting to one of 'view', 'copy' or 'copywarn' (default).
For 'view', the behavior is unchanged from 1.14.0, meaning that multi-field indexing returns a view which will often contain padding bytes.
For 'copy', the behavior reverts back to 1.13 behavior, in which a packed-copy of the array fields is returned. This should solve most of people's bugs.
For 'copywarn', do the same as 'copy' but warn anytime multifield indexing is used. (default)
Is this kind of configuration option a good idea, or will it lead to a dependency mess? (I got the idea from the legacy mode for printing, which also allows the old and new behavior but defaults to the new one, unlike this PR currently).
In this PR I also introduce a new user-visible function np.pack_fields, which removes padding bytes from structured ndarrays and dtypes. Its existence should help any users transition to the new behavior: Doing np.pack_fields(a[['a', 'c']]) in the new behavior ('view' setting) returns what you get in the old ('copy') setting.