array-api icon indicating copy to clipboard operation
array-api copied to clipboard

Boolean indexing when elements of mask shape are zero?

Open mdhaber opened this issue 10 months ago • 1 comments

The standard seems to allow elements of a boolean index's shape to be zero.

The size of each dimension in B must equal the size of the corresponding dimension in A or be 0,

But I have read a few times, and I don't think it specifies what should happen in this case.

This returns an empty array in NumPy, CuPy, array_api_strict, and jax.numpy.

import array_api_strict as xp
x = xp.asarray([1, 2, 3])
i = xp.asarray([], dtype=xp.bool)
x[i]  # array([], dtype=int64)

The behavior would follow from the usual rules if the index were integral, but it's not obvious to me that this should work for a boolean index of zero size. Indeed, PyTorch fails with:

IndexError: The shape of the mask [0] at index 0 does not match the shape of the indexed tensor [3] at index 0

and dask.array fails with:

ValueError: operands could not be broadcast together with shapes (3,) (0,)

If the NumPy behavior is desired, does it follow from the usual rule, or is it a special case? Either way, it would help to spell out the desired behavior to ensure consistency among backends.

mdhaber avatar Apr 18 '25 05:04 mdhaber

Not sure where the zero rule comes from, although maybe I am forgetting somthing? I suspect it drops out of the special case to make empty lists work and is strictly incorrect for boolean arrays.

FWIW, I consider it a NumPy bug to allow this, although it may make sense to deprecate rather than just remove it. (Length 0 simply isn't special.) It has certainly no reason to exist here.

seberg avatar Apr 22 '25 11:04 seberg