Skip to content
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

cupy.ndarray cannot be compared with ellipsis #5715

Closed
leofang opened this issue Sep 8, 2021 · 8 comments · Fixed by #6222
Closed

cupy.ndarray cannot be compared with ellipsis #5715

leofang opened this issue Sep 8, 2021 · 8 comments · Fixed by #6222
Assignees
Labels
array-api Topic: Array API Standard cat:bug Bugs prio:high

Comments

@leofang
Copy link
Member

leofang commented Sep 8, 2021

Not sure if it's due to #4198. The __richcmp__ method does not handle trivial comparison with Python objects correctly:

>>> np.empty(3) == ...
array([False, False, False])
>>>
>>> cp.empty(3) == ...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "cupy/_core/core.pyx", line 1094, in cupy._core.core.ndarray.__richcmp__
    return numpy.equal(self, other)
TypeError: operand type(s) all returned NotImplemented from __array_ufunc__(<ufunc 'equal'>, '__call__', array([0., 0., 0.]), Ellipsis): 'ndarray', 'ellipsis'

It seems NumPy internally calls PyObject_RichCompare to handle this. Perhaps before delegating to numpy.equal() (and friends) we should handle this edge case first?

@leofang
Copy link
Member Author

leofang commented Sep 8, 2021

Note: this relates to the test_indexing.py failure seen in #5698 (comment).

@toslunar
Copy link
Member

toslunar commented Sep 8, 2021

#1989 discusses comparison with None.

@asmeurer
Copy link
Contributor

asmeurer commented Sep 9, 2021

Can you post the traceback from the test failure? We should probably make the array API tests not use == for comparing arrays and use is to compare against Ellipsis.

@takagi takagi added the array-api Topic: Array API Standard label Dec 2, 2021
@github-actions
Copy link

github-actions bot commented Dec 2, 2021

cc/ @asmeurer @leofang

@takagi
Copy link
Member

takagi commented Dec 3, 2021

This line brings the error, where key is a tuple that contains array indices and they are compared to an ellipsis. When an index is a ndarray, the error above occurs. I think we should count using is here.

n_ellipsis = key.count(...)

@toslunar
Copy link
Member

toslunar commented Dec 4, 2021

n_ellipsis = key.count(...)

To be precise, each array index in key must have _.size <= 1, or key.count(...) will raise ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). The line works fine because indexing with integer arrays is unspecified in Array API. https://data-apis.org/array-api/latest/API_specification/indexing.html

elif isinstance(key, Array):
if key.dtype in _integer_dtypes:
if key.ndim != 0:
raise IndexError(
"Non-zero dimensional integer array indices are not allowed in the array API namespace"
)

@asmeurer
Copy link
Contributor

Do you know if this code leads to a problem in the NumPY implementation? I think something like this would be more robust.

diff --git a/numpy/array_api/_array_object.py b/numpy/array_api/_array_object.py
index ead061882d..e7ddcf033b 100644
--- a/numpy/array_api/_array_object.py
+++ b/numpy/array_api/_array_object.py
@@ -325,10 +325,13 @@ def _validate_index(key, shape):

             if shape is None:
                 return key
-            n_ellipsis = key.count(...)
+            # Use 'is' to compare against ellipsis to avoid performing == on
+            # an array.
+            ellipses = [i for i, k in enumerate(key) if k is ...]
+            n_ellipsis = len(ellipses)
             if n_ellipsis > 1:
                 return key
-            ellipsis_i = key.index(...) if n_ellipsis else len(key)
+            ellipsis_i = ellipses[0] if ellipses else len(key)

             for idx, size in list(zip(key[:ellipsis_i], shape)) + list(
                 zip(key[:ellipsis_i:-1], shape[:ellipsis_i:-1])

@takagi
Copy link
Member

takagi commented Dec 17, 2021

As @toslunar mentioned in #5715 (comment), I think NumPy's current code works without any problem. But, yes, your diff would be exactly what we want to do there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
array-api Topic: Array API Standard cat:bug Bugs prio:high
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants