-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Support for NEP-35 #6738
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
Support for NEP-35 #6738
Conversation
Yay tests pass 🎉 Thank you for continuing to push here @pentschev! Is it fair to characterize most of the changes here as moving the type checks from
I think this is a large enough change that we should ask for an external reviewer if folks have time. Ideally we could merge in tomorrow but that might not be enough lead time. If we don't hear back I think planning for early next week makes sense. |
For the first part, no. Take for example https://github.com/dask/dask/pull/6738/files#diff-cc8bb1c7ea02a9582c31ac1580f3ab0674c35e0b6af060513ba9932ceb07a600R227, that's a place where support for non-arraylike is still necessary, thus that has to be verified on a per-case basis. For the second part, yes. The intent is that |
dask/array/tests/test_cupy.py
Outdated
assert_eq(result, np.array([1], dtype=d.dtype)) | ||
|
||
|
||
@pytest.mark.skipif(np.__version__ < "1.20", reason="NEP-35 is not available") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this into a global variable, perhaps in a settings-like module. That way it's easy to change the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically, create a variable named NEP35_AVAILABLE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, this exists already in
dask/dask/array/numpy_compat.py
Line 11 in ac2e582
_numpy_120 = LooseVersion(np.__version__) >= "1.20.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in bae0dd6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest testing the protocol rather than the version. Something like:
def _test_nep35():
class MyClass:
def __array_function__(self, func, args, kwargs):
return True
try:
return np.asarray([], like=MyClass())
except TypeError:
return False
NEP35_AVAILABLE = _test_nep35()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would personally prefer they fail to force us to update the tests should anything change, rather than having tests getting skipped. Happy to change my mindset should there be compelling arguments in favor of skipping. 🙂
I think @crusaderky may take a look at this -- if not, I'll plan to merge tomorrow morning |
I’ve been meaning to take a look at this as well. Will carve out some time tomorrow |
I'm going to merge now. If there are additional concerns I'm sure @pentschev would be happy to follow up with PRs/comments/etc. |
Small heads-up: we missed some small memory leaks in |
Sorry for the delay. Skimmed over the changes. These seem reasonable. No additional comments |
Would it makes sense to do a blogpost on this? Like a short follow on/update of the NEP 18 one? |
Thanks @seberg , is numpy/numpy@e907085 the fix you mentioned? |
Yeah, it just leaks "shape" information, so thats a couple a few dozen bytes each call (don't worry about the dtype, in the vast majority of cases those are singletons anyway). |
Thanks @seberg for catching and fixing that, it's my fault to have missed it! 🙁 |
I'm not sure, possibly? This change is generally more transparent to users than NEP-18 was, so I'm not exactly sure how to approach it in a manner that anybody who's not involved in library development would be compelled to read. No objections in discussing it, I just don't see a good way to write it right now. |
Fixes #4842 , #6117 , #6169 , #6942.
This PR adds support for NEP-35. To describe the NEP briefly, it proposes the inclusion of a new keyword argument
like
to NumPy array creation functions, such asnp.array
, allowing NumPy to dispatch the array creation downstream to other libraries, such as CuPy and Dask itself. To demonstrate this, consider the following example:NEP-35 is still experimental and requires NumPy 1.20.0+.
The changes here attempt to cover a large portion of Dask, adding some new tests that wouldn't pass before. This change is mostly beneficial for downstream libraries such as CuPy and Sparse, that implement the
__array_function__
protocol, allowing Dask to continue working with, for example, Dask arrays backed by CuPy in functions such aspad(..., mode="constant")
, which wasn't possible before because of the call tonp.asarray
that wasn't able to create a new array in a type other than NumPy.Things that are not yet supported include (but not limited to):
da.random.choice
: it's a bit of complex function which will take some time to get right, but doesn't seem to have any technical limitations;linalg
functions: requiressolve_triangular
which is a SciPy function and can't be dispatched with__array_function__
, thus will probably require special casing;cc @quasiben @jakirkham @mrocklin @seberg @shoyer @rgommers @hameerabbasi @leofang