Support buffer protocol objects as advanced index keys#2889
Support buffer protocol objects as advanced index keys#2889vlad-perevezentsev wants to merge 15 commits intomasterfrom
Conversation
|
Array API standard conformance tests for dpnp=0.21.0dev0=py313h509198e_25 ran successfully. |
| return arr | ||
| if isinstance(x, numpy.ndarray): | ||
| return x | ||
| # convert buffer protocol objects (array.array, memoryview, etc.) |
There was a problem hiding this comment.
Can all that use cases covered converting x to numpy.ndarray?
Do we need so complicated if-logic?
There was a problem hiding this comment.
here is CuPy implementation of a similar idea for a reference:
https://github.com/cupy/cupy/blob/main/cupy/_core/_routines_indexing.pyx#L247
can take a similar approach too in some cases (best to leave converting to usm_ndarray to the tensor layer, though, for queue propagation reasons)
There was a problem hiding this comment.
I don't think we need to fully follow the same CuPy implementation in _prepare_slice_list, because it seems CuPy mimics faulty NumPy behavior sometimes.
Not sure if I got the comment fully correctly, but in general I meant something like:
if x is None or x is Ellipsis or isinstance(x, (dpt.usm_ndarray, slice, numpy.ndarray)):
return x
if isinstance(x, dpnp_array):
return x.get_array()
try:
x = numpy.asarray(x)
except ... :
...
raise ...
...
return xThere was a problem hiding this comment.
yep, agreed mostly, though problem is, we don't really want to send integers or boolean Python scalars to numpy arrays, which is why we may need something like:
elif numpy.isscalar(s):
if not isinstance(s, (bool, numpy.bool_)):
# keep scalar int
continue
which is in cupy implementation. We could handle range, list, tuple through numpy though
There was a problem hiding this comment.
I don not think try/except around numpy.asarray is necessary because invalid index types either raise naturally or produce arrays with unsupported dtypes that the tensor layer rejects with IndexError
Regarding elif numpy.isscalar(s) I replaced it with isinstance(x, (int, numpy.generic)) because np.isscalar(memoryview(array.array("l", [0, 1, 2]))) returns True
bool check is not needed since bool is subclass of int
|
View rendered docs @ https://intelpython.github.io/dpnp/pull/2889/index.html |
| arr = numpy.asarray(x) | ||
| # cast empty arrays (float64 in NumPy) to intp | ||
| # for correct tensor indexing | ||
| if arr.size == 0 and arr.dtype.kind == "f": |
There was a problem hiding this comment.
Why do we need to explicitly check arr.dtype.kind == "f"?
This PR proposes by adding support for buffer protocol objects (
array.array,memoryviewetc.) as advanced index keysThese changes were proposed in #2872 as an extension to the advanced indexing support.