<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hello NumPy-ers!<div class=""><br class=""></div><div class="">The __array__ method is a great little tool to allow interoperability with NumPy. Briefly, calling `np.array()` or `np.asarray()` on an object with an `__array__` method, one can get a NumPy representation of that object, which may or may not involve data copying (this is up to the object’s implementation of `__array__`). Some references:</div><div class=""><br class=""></div><div class=""><a href="https://numpy.org/devdocs/user/basics.dispatch.html" class="">https://numpy.org/devdocs/user/basics.dispatch.html</a></div><div class=""><br class=""></div><div class=""><a href="https://docs.scipy.org/doc/numpy/reference/arrays.classes.html#numpy.class.__array__" class="">https://docs.scipy.org/doc/numpy/reference/arrays.classes.html#numpy.class.__array__</a></div><div class=""><a href="https://numpy.org/devdocs/reference/generated/numpy.array.html" class="">https://numpy.org/devdocs/reference/generated/numpy.array.html</a></div><div class=""><a href="https://numpy.org/devdocs/reference/generated/numpy.asarray.html" class="">https://numpy.org/devdocs/reference/generated/numpy.asarray.html</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">(I couldn’t find an authoritative guide on good and bad practices with `__array__`, btw.)</div><div class=""><br class=""></div><div class="">For people writing e.g. visualisation libraries, this is a wonderful thing, because if we know how to visualise NumPy arrays, we can suddenly visualise anything with an `__array__` method. As an example, napari, while not being aware of dask, can visualise large dask arrays out of the box, which allows us to view 100GB out-of-core datasets easily.</div><div class=""><br class=""></div><div class="">However, in many cases, instantiating a NumPy array is an expensive operation, for example copying an array from GPU to CPU memory, or involves substantial loss of information. Some library authors are reluctant to allow implicit execution of such an operation, such as PyOpenCL [1], PyTorch [2], or even scipy.sparse.</div><div class=""><br class=""></div><div class="">My proposal is to add an optional argument to `__array__` that would signal to the downstream library that we *really* want a NumPy array and are willing to wait for it. In the PyTorch issue I proposed `force=True`, and they are somewhat receptive of this, but, reading more about the existing NumPy APIs, I think `copy=True` would be a nice alternative:</div><div class=""><br class=""></div><div class="">- np.array already has a copy= keyword argument. Under this proposal, it would attempt to pass it to the downstream library, and, if that failed, it would try again without it and run its own copy.</div><div class="">- np.asarray could get a new copy= keyword argument that would match np.array’s.</div><div class="">- It would neatly express the idea that the array is going to e.g. get passed around between devices.</div><div class=""><br class=""></div><div class="">Or, we could just go with `force=`.</div><div class=""><br class=""></div><div class="">One bit of expressivity we would miss is “copy if necessary, but otherwise don’t bother”, but there are workarounds to this.</div><div class=""><br class=""></div><div class="">What do people think? I would be happy to write a PR and/or NEP for this if there is general consensus that this would be useful.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class=""><br class=""></div><div class="">Juan.</div><div class=""><br class=""></div><div class="">Refs:</div><div class=""><br class=""></div><div class="">[1]: <a href="https://github.com/inducer/pyopencl/pull/301" class="">https://github.com/inducer/pyopencl/pull/301</a></div><div class="">[2]: <a href="https://github.com/pytorch/pytorch/issues/36560" class="">https://github.com/pytorch/pytorch/issues/36560</a></div></body></html>