Skip to content

MAINT: Implement new style promotion for np.result_type, etc. #18676

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 10 commits into from
May 19, 2021

Conversation

seberg
Copy link
Member

@seberg seberg commented Mar 24, 2021

This implements a new style promotion scheme for mutiple inputs
as are passed to np.result_type. It should be noted that
result-type heavily relies on "value-based casting" logic/promotion
logic.
This fact is inherited to many places. When user DTypes are introduced
some of these places should potentially use "weak DType" logic instead
if the input is a Python scalar.
This is not yet implemented. It would be necessary to mark these
the same way as is currently done for np.result_type.

This type of "marking" will generally be necessary in a few places,
even if may get away with just switching the logic everywhere.


Marking as draft, since I am planning to probably write some small tests (there are some exceedingly rare changes in behaviour). Also, probably moving some of the new code to the new common_dtype.c file. But I don't expect any larger changes right now, so putting it out there.

I expect the doc-tests will fail, this is OK, the doctests need to be adapted. There is a very mild slowdown in ufunc loop lookup due to this. That seems OK, it probably is around the same or less than the general speedup in gh-15271. Eventually it would largely go away again in the ufunc refactor (although the exact speed impact of that is unknown, we are talking about overheads of at most 10-20% of the cheapest possible ufunc calls...).

@seberg seberg marked this pull request as draft March 24, 2021 16:46
@seberg seberg force-pushed the new-promotion-partial-weak-scalars branch from f3979d0 to e55b000 Compare March 24, 2021 17:17
Copy link
Contributor

@tylerjereddy tylerjereddy left a comment

Choose a reason for hiding this comment

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

Was just reading through out of curiosity and added a few minor comments for typos and stuff.

if ((PyArray_NDIM(self) != PyArray_NDIM(ret)) &&
DEPRECATE_FUTUREWARNING(
"casting an array to a subarray dtype "
"will not using broadcasting in the future, but cast each "
Copy link
Contributor

Choose a reason for hiding this comment

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

using -> use?

/*
* The following functions define the "common DType" for the abstract dtypes.
*
* Note that the logic with resupt to the "higher" dtypes such as floats
Copy link
Contributor

Choose a reason for hiding this comment

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

resupt -> respect?

* python float, int, or complex.
* An array using this flag must be a temporary array that can never
* leave the C internals of NumPy. Even if it does, ENSUREARRAY is
* absolutely safe to abuse, since it alraedy is be a base class array :).
Copy link
Contributor

Choose a reason for hiding this comment

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

alraedy -> already?

is be a base class -> is a base class?

@seberg seberg force-pushed the new-promotion-partial-weak-scalars branch from e55b000 to 40f2cc4 Compare April 12, 2021 17:48
@seberg
Copy link
Member Author

seberg commented Apr 12, 2021

Thanks Tyler, let me know if you have any comments. I should round this off (mainly add tests, and scan through this). Although, I will read through the NEP 43 draft first now, since promotion in ufuncs is also confusing me again and that document also needs to settle soon.

@seberg seberg marked this pull request as ready for review April 19, 2021 20:20
@seberg seberg changed the title WIP,MAINT: Implement new style promotion for np.result_type, etc. MAINT: Implement new style promotion for np.result_type, etc. Apr 20, 2021
@seberg
Copy link
Member Author

seberg commented Apr 21, 2021

Ping @mattip if you have some time please have a look at this.

Copy link
Member

@mattip mattip left a comment

Choose a reason for hiding this comment

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

There are a few bits with complex dtypes that coverage says are not hit. Otherwise it all looks good to me.

@@ -15,6 +15,8 @@ typedef struct coercion_cache_obj {
int depth; /* the dimension at which this object was found. */
} coercion_cache_obj;

NPY_NO_EXPORT PyArray_DTypeMeta *
npy_discover_dtype_from_pytype(PyTypeObject *pytype);
Copy link
Member

Choose a reason for hiding this comment

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

Where is this used outside of array_coercion.c?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, must have been some transitionary thing.

Copy link
Member

Choose a reason for hiding this comment

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

Can we delete these lines if they are not needed?

seberg added 5 commits May 12, 2021 15:33
This implements a new style promotion scheme for mutiple inputs
as are passed to `np.result_type`. It should be noted that
result-type heavily relies on "value-based casting" logic/promotion
logic.
This fact is inherited to many places.  When user DTypes are introduced
some of these places should potentially use "weak DType" logic instead
if the input is a Python scalar.
This is *not* yet implemented. It would be necessary to mark these
the same way as is currently done for `np.result_type`.

This type of "marking" will generally be necessary in a few places,
even if may get away with just switching the logic everywhere.
This doesn't serve any purpose anymore. The new code is now always
used.  (In very few cases this may lead to small slowdowns, this
should only matter in ufuncs where it doesn't seem to matter enough
to worry about it.)
@seberg seberg force-pushed the new-promotion-partial-weak-scalars branch 2 times, most recently from 9ec2f60 to c5a08e7 Compare May 13, 2021 01:41
Base the "magic" value of the double, and use nextafter even for the
equal condition to avoid rounding during the cast to longdouble.
This might further be necessary because the code uses double constants
and not longdouble ones (not sure about this).

Using nextafter on the double value should put us firmly on the right
side and nobody should care about the few ulps in between those values.
@seberg seberg force-pushed the new-promotion-partial-weak-scalars branch from c5a08e7 to 1d3b9b2 Compare May 13, 2021 01:46
@seberg
Copy link
Member Author

seberg commented May 14, 2021

Sorry for missing to update this more earlier. I added some new tests parametrizations, hopefully that will clear out the missed coverage.

Copy link
Member

@mattip mattip left a comment

Choose a reason for hiding this comment

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

I think this makes sense. There are many new codecov messages about code not hit, are they correct?

@seberg seberg force-pushed the new-promotion-partial-weak-scalars branch from 81ea7ba to 2b7b256 Compare May 16, 2021 23:15
@charris charris merged commit e108c76 into numpy:main May 19, 2021
@charris
Copy link
Member

charris commented May 19, 2021

Thanks Sebastian.

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.

4 participants