8000 ENH: Allow ufunc.identity to be any python object by eric-wieser · Pull Request #8955 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Allow ufunc.identity to be any python object #8955

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

Merged
merged 3 commits into from
Nov 12, 2018

Conversation

eric-wieser
Copy link
Member
@eric-wieser eric-wieser commented Apr 17, 2017

The first commit in this PR is #8952, which probably ought to be merged first (done)

Fixes #7702 and #4599, and also a related issue to #8860

{nin}, {nout}, {identity}, "{name}",
"{doc}", 0, NULL, identity
);
if (f == NULL) {{
Copy link
Member Author

Choose a reason for hiding this comment

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

Previously we never did any error checking here, which seems wrong

docstrings.get('numpy.core.umath.logical_or'),
'PyUFunc_SimpleBinaryComparisonTypeResolver',
TD(nodatetime_or_obj, out='?', simd=[('avx2', ints)]),
TD(O, f='npy_ObjectLogicalOr'),
),
'logical_xor':
Ufunc(2, 1, Zero,
Ufunc(2, 1, False_,
Copy link
Member Author

Choose a reason for hiding this comment

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

Zero wasn't really correct, but there was previously no way to specify False

@homu
Copy link
Contributor
homu commented May 1, 2017

☔ The latest upstream changes (presumably #8876) made this pull request unmergeable. Please resolve the merge conflicts.

@eric-wieser eric-wieser force-pushed the obj-identity branch 2 times, most recently from 907dc3e to 8cea62b Compare May 1, 2017 10:47
@charris
Copy link
Member
charris commented Oct 2, 2017

Needs rebase. There seem to be several PRs in this series that should go in together.

@eric-wieser
Copy link
Member Author

Updated

@hameerabbasi
Copy link
Contributor
hameerabbasi commented Feb 19, 2018

I would suggest adding identities to np.minimum and np.maximum, which would be +inf and -inf respectively. This is intuitively and logically true, as max(a, -inf) = a and min(a, +inf) = a.

xref #5032

@eric-wieser
Copy link
Member Author

@hameerabbasi: I think that's a bad idea (think integer types, max(abs(x)), ...), but let's have that discussion at the linked issue, not here.

@eric-wieser eric-wieser changed the base branch from master to maintenance/1.14.x February 20, 2018 08:11
@eric-wieser eric-wieser changed the base branch from maintenance/1.14.x to master February 20, 2018 08:12
@eric-wieser
Copy link
Member Author

(base changed to make github recompute the diff)

@mhvk
Copy link
Contributor
mhvk commented Mar 21, 2018

From https://github.com/numpy/numpy/pull/10635/files#r170466944 - once #10635 is merged, we should be sure to correct the code such that the initializer is also used as one of the elements over which reductions are done for object dtype (in #10635, it is only used for empty slices).

@eric-wieser
Copy link
Member Author

This might make sense to get into 1.16, while we're adding members to ufuncs

@mhvk
Copy link
Contributor
mhvk commented Nov 5, 2018

Indeed, I can review again if rebased.

@eric-wieser
Copy link
Member Author
eric-wieser commented Nov 6, 2018

Rebased, with some more docs

The identity for the new gufunc. Must be passed as ``NULL`` unless the
``identity`` argument is ``PyUFunc_IdentityValue``. Setting it to NULL
is equivalent to calling PyUFunc_FromFuncAndDataAndSignature.
The reference is stolen.
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not really experienced enough with C apis to know whether this is a good idea - does CPython provide any guidelines on when to steal and not to steal references?

Copy link
Contributor

Choose a reason for hiding this comment

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

Generally, it seems to be stolen only when the reference can reasonably expected to be stored elsewhere (as in setting an element of a list). That does seem to be the case here. That said, the case is less clear than for a list, and the documentation [1] explicitly states that reference stealing functions are exceptions. So, my sense would be not to steal the reference.

[1] https://docs.python.org/3/c-api/intro.html#reference-count-details

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.

The code looks good (modulo the discussion about reference stealing, where I think we perhaps better not).

But there should be a test case...

The identity for the new gufunc. Must be passed as ``NULL`` unless the
``identity`` argument is ``PyUFunc_IdentityValue``. Setting it to NULL
is equivalent to calling PyUFunc_FromFuncAndDataAndSignature.
The reference is stolen.
Copy link
Contributor

Choose a reason for hiding this comment

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

Generally, it seems to be stolen only when the reference can reasonably expected to be stored elsewhere (as in setting an element of a list). That does seem to be the case here. That said, the case is less clear than for a list, and the documentation [1] explicitly states that reference stealing functions are exceptions. So, my sense would be not to steal the reference.

[1] https://docs.python.org/3/c-api/intro.html#reference-count-details

@eric-wieser eric-wieser force-pushed the obj-identity branch 2 times, most recently from 08204dd to 77347a3 Compare November 10, 2018 20:25
@@ -685,6 +685,10 @@ def test_nan(self):
assert_(np.isnan(np.logaddexp(0, np.nan)))
assert_(np.isnan(np.logaddexp(np.nan, np.nan)))

def test_reduce(self):
assert_equal(np.logaddexp.identity, -np.inf)
assert_equal(np.logaddexp.reduce([]), -np.inf)
Copy link
Member Author

Choose a reason for hiding this comment

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

@mhvk: Updated with a slightly longer testcase

@eric-wieser
Copy link
Member Author

Note: This will need a rebase if #11977 goes in first, even though github won't show conflicts.

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.

Looks all OK to me

@mhvk
Copy link
Contributor
mhvk commented Nov 10, 2018

Shall we merge now to avoid the need for a rebase? I think this is all OK.

@eric-wieser
Copy link
Member Author

Yeah, why not. Updated with release notes.

@eric-wieser
Copy link
Member Author

@mattip has said he'll hold off on #11977 until this goes in

@@ -402,6 +402,9 @@
# End 1.7 API
'PyUFunc_RegisterLoopForDescr': (41,),
# End 1.8 API
'PyUFunc_FromFuncAndDataAndSignatureAndIdentity':
(42,)
# End 1.15 API
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 this be 1.16 API?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, good catch

@mattip mattip merged commit e34f5bb into numpy:master Nov 12, 2018
@mattip
Copy link
Member
mattip commented Nov 12, 2018

Thanks Eric

eriknw added a commit to eriknw/numpy that referenced this pull request Apr 28, 2020
The lack of identity for `logaddexp2` was first identitifed in numpy#4599.
The implementation in numpy#8955 added -inf as identity for `logaddexp`,
but missed adding it for `logaddexp2`.
eriknw added a commit to eriknw/numpy that referenced this pull request Apr 28, 2020
The lack of identity for `logaddexp2` was first identitifed in numpy#4599.
The implementation in numpy#8955 added -inf as identity for `logaddexp`,
but missed adding it for `logaddexp2`.
seberg added a commit that referenced this pull request May 13, 2020
The lack of identity for `logaddexp2` was first identitifed in #4599.
The implementation in #8955 added -inf as identity for `logaddexp`,
but missed adding it for `logaddexp2`.

Co-Authored-By: Eric Wieser <wieser.eric@gmail.com>
Co-authored-by: Sebastian Berg <sebastian@sipsolutions.net>
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.

6 participants
0