Skip to content

Conversation

@mhvk
Copy link
Contributor

@mhvk mhvk commented Jun 13, 2018

This started as a simple fix for #11306, ensuring that as we collect arguments and overrides, we skip those that have the same class as ones collected already. But looking at the code (mostly my own...), I found a reference counting bug (first commit), and also realized that for the ndarray side, where all that is needed is to know whether there are any overrides, the code was needlessly slow. But splitting that out, there was no need any more for much of the code to be in the src/private directory, so I moved it. As a result, this is quite a lot of shuffling, but I think it makes the whole a lot clearer and cleaner.

Left really is the annoyance of not having access to the PyArray API - thus, this should be revisited once multiarray and umath have been merged.

fixes #11306

Copy link
Member

Choose a reason for hiding this comment

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

Would it be better to store types in an array rather than calling PyObject_Type repeatedly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OOPS, this is the wrong function, I don't need a reference to the type at all, I just need Py_TYPE, which is very fast.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is wrong elsewhere in the function too...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I think I got them all.

Copy link
Member

Choose a reason for hiding this comment

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

nit: remove a layer of parens here

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't be comparing with NULL - this returns a boolean

Copy link
Contributor Author

Choose a reason for hiding this comment

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

duh, how could I have missed all but one of those.

Copy link
Member

Choose a reason for hiding this comment

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

has_override shouldn't be an npy_bool if it contains -1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed. Leftover. I do wonder to what extent I should even check that args is a tuple and kwds a dict; one can presumably only get here via python, so this should be OK. What do you think? remove those tests?

Copy link
Member

Choose a reason for hiding this comment

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

Could write them as asserts

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, done in array_ufunc itself.

Copy link
Member

@eric-wieser eric-wieser Jun 13, 2018

Choose a reason for hiding this comment

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

Test might be clearer and more reorderable if you did c.count = c_sub.count = 0 each time (or just recreated the arrays)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, does make more sense. Done.

Copy link
Member

Choose a reason for hiding this comment

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

A comment explaining the purpose of this would be nice

Copy link
Member

@eric-wieser eric-wieser Jun 13, 2018

Choose a reason for hiding this comment

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

Something like /* Like the python `__op__` and `__rop__` overloads, a type is not visited more than once */

@eric-wieser
Copy link
Member

First commit is good to go, only minor nits on the second.

@eric-wieser
Copy link
Member

eric-wieser commented Jun 13, 2018

Would prefer to see the move commit separately - it makes it harder to review (reviewing per-commit results in comments being marked outdated) and rebase with it part of the same PR.

mhvk added 4 commits June 12, 2018 22:41
Overall, it likely doesn't matter much for performance, but it is
more logical and more consistent with what python does: reverse
operators are not called if the forward one of a given class
already returned NotImplemented.
Code was getting too convoluted and both can be optimized
in different ways.
This way, only one simple routine is left.
Where we args is guaranteed to be a tuple, and were out is useful
immediately.
@mhvk mhvk force-pushed the ufunc-override-call-class-only-once branch from d9068e6 to a22b713 Compare June 13, 2018 02:41
goto fail;
}
if (with_override != NULL) {
for (j = 0; j < num_override_args; j++) {
Copy link
Member

Choose a reason for hiding this comment

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

The int j can go on the line above this - there's no need to introduce it 70 lines earlier

@mhvk mhvk force-pushed the ufunc-override-call-class-only-once branch from a22b713 to 16c39af Compare June 13, 2018 02:49
@mhvk
Copy link
Contributor Author

mhvk commented Jun 13, 2018

Makes sense about the review, though perhaps it is not so bad to check what is here directly...
I'll look tomorrow whether I can perhaps organize it better.

@mhvk mhvk force-pushed the ufunc-override-call-class-only-once branch 2 times, most recently from fa2c834 to 2ac7463 Compare June 13, 2018 12:37
Bug since the former increases reference counts, which were not
taken into account.
@mhvk
Copy link
Contributor Author

mhvk commented Jun 14, 2018

Replaced by #11338 - which has the commits better organized (and likely solves the failure due to a poor assert statement).

@mhvk mhvk closed this Jun 14, 2018
@mhvk mhvk deleted the ufunc-override-call-class-only-once branch June 14, 2018 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MAINT/BUG? __array_ufunc__ should try a given type only once

3 participants