Skip to content
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

MAINT: Align masked with normal ufunc loops #19259

Merged
merged 3 commits into from Jun 27, 2021

Conversation

seberg
Copy link
Member

@seberg seberg commented Jun 16, 2021

This removes the ability to specialize masked inner loops (for now)
as was already noted in NEP 41 and NEP 43.

The masked array is now passed in as the last argument to use the
identical signature and avoid duplicating the code unnecessary.

This is part of the longer process to refactor ufuncs to NEP 43
and split out, to keep the diff's shorter (or at least easier
to read).

EDIT: In case anyone wonders about moving the place where the inner-loop is selected. This is necessary, because in the future we want to do what the masked version currently pretends: use the fixed-strides array, which is only available after setting up the iterator.


This is based of gh-19258 and will have a conflict with gh-19257 (The masked+__array_prepare__ limitation in the tests there is unnecessary, by merging the two loops the tests added there should fail and need simplification/updating).

@seberg seberg force-pushed the maint-ufunc-refactor-masked-not-duplicate branch from d9d60a7 to 11ddb3f Compare June 16, 2021 15:34
@seberg seberg added this to Pull Requests in NEP 41: New DType System Jun 16, 2021
@seberg seberg force-pushed the maint-ufunc-refactor-masked-not-duplicate branch 4 times, most recently from a9719ca to 380b83f Compare June 17, 2021 23:09
return -1;
}
char **dataptr = NpyIter_GetDataPtrArray(iter);
npy_intp *strides = NpyIter_GetInnerStrideArray(iter);
npy_intp *countptr = NpyIter_GetInnerLoopSizePtr(iter);
int needs_api = NpyIter_IterationNeedsAPI(iter);
needs_api |= NpyIter_IterationNeedsAPI(iter);
Copy link
Member Author

Choose a reason for hiding this comment

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

In case anyone wonders: Currently at this point needs_api is never set (passing it earlier is a well intentioned no-op). But the future can see that happening, the concept is good. (Except that NpyIter_IterationNeedsAPI is not perfect either right now.)

@seberg seberg force-pushed the maint-ufunc-refactor-masked-not-duplicate branch from 380b83f to fa4a2cc Compare June 17, 2021 23:14
This removes the ability to specialize masked inner loops (for now)
as was already noted in NEP 41 and NEP 43.

The masked array is now passed in as the last argument to use the
identical signature and avoid duplicating the code unnecessary.

This is part of the longer process to refactor ufuncs to NEP 43
and split out, to keep the diff's shorter (or at least easier
to read).
@seberg seberg force-pushed the maint-ufunc-refactor-masked-not-duplicate branch from fa4a2cc to 9c6081e Compare June 21, 2021 14:14
@seberg seberg marked this pull request as ready for review June 21, 2021 14:14
@seberg
Copy link
Member Author

seberg commented Jun 26, 2021

I know I started pushing two things at once a bit right now (ufuncs and the result-type/ensure-nbo with voids thing). But @mattip and @mhvk if you have time: This PR and the ones listed in the ufunc project are actually more important, in the sense that pushing ufuncs will unblock/make other things easier to grok.

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

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

This makes a lot of sense - the code is becoming so much more understandable. Hurray! All my comments are totally minor.

will be given in the unlikely event that it was customized.

We do not expect that any code uses this. If you do use it,
you must unset unset the selector on newer NumPy version.
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove one of the duplicate "unset"

*
* ufunc: The ufunc object.
* dtypes: An array which has been populated with dtypes,
* in most cases by the type resolution function
* for the same ufunc.
* fixed_strides: For each input/output, either the stride that
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting that this was there and not an argument...

numpy/core/src/umath/ufunc_type_resolution.c Show resolved Hide resolved
} while (loopsize > 0);
N -= subloopsize;

/* Process unmasked values */
Copy link
Contributor

@mhvk mhvk Jun 27, 2021

Choose a reason for hiding this comment

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

Gosh, never knew about this memchr stuff; should have used it for the reductions too -

while (n < count && mask == *maskptr) {
n++;
maskptr += mask_stride;
}

Though if I look at source code of the glibc version, I have no idea why one would roll one's own - that is one heck of an optimized function! EDIT: though obviously we need to deal with strides...

Copy link
Member Author

Choose a reason for hiding this comment

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

The followup deletes the whole chunk from the reductions to re-use this. It might make sense to re-add a broadcasted special case eventually though. Your reduce code has such a special case, the normal ufunc code does not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! Quite happy to go for simpler first and then see whether speed can be improved for special cases.

@mattip mattip merged commit f8a3047 into numpy:main Jun 27, 2021
@mattip
Copy link
Member

mattip commented Jun 27, 2021

Thanks @seberg

@seberg seberg deleted the maint-ufunc-refactor-masked-not-duplicate branch June 27, 2021 23:43
@seberg seberg moved this from Pull Requests to Done in NEP 41: New DType System Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

3 participants