Repository: scikit-hep/awkward

Issue:
CUDA backend broken
### Version of Awkward Array

'2.0.0rc1'

### Description and code to reproduce

To reproduce:
`python localbuild.py --pytest tests-cuda`

There are 5 failing tests:
```python
_________________________________________________________ test_cupy_interop __________________________________________________________

    def test_cupy_interop():
        c = cp.arange(10)
        n = np.arange(10)
>       cupy_index_arr = ak.index.Index64(c)

c          = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
n          = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

tests-cuda/test_1276-cupy-interop.py:13: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
awkward/index.py:28: in __init__
    self._data = self._nplike.index_nplike.asarray(
        data       = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        metadata   = None
        nplike     = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        self       = <[AttributeError("'Index64' object has no attribute '_data'") raised in repr()] Index64 object at 0x7f9c345d4970>
awkward/nplike.py:98: in asarray
    return self._module.asarray(*args, **kwargs)
        args       = (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
        kwargs     = {'dtype': dtype('int64'), 'order': 'C'}
        self       = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   ???
E   TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.


cupy/_core/core.pyx:1473: TypeError
___________________________________________________________ test_from_cupy ___________________________________________________________

    def test_from_cupy():
        cupy_array_1d = cp.arange(10)
        cupy_array_2d = cp.array([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6], [7.7, 8.8]])
    
>       ak_cupy_array_1d = ak.from_cupy(cupy_array_1d)

cupy_array_1d = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
cupy_array_2d = array([[1.1, 2.2],
       [3.3, 4.4],
       [5.5, 6.6],
       [7.7, 8.8]])

tests-cuda/test_1276-from-cupy.py:14: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
awkward/operations/ak_from_cupy.py:39: in from_cupy
    return ak._util.from_arraylib(array, regulararray, False, highlevel, behavior)
        array      = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        behavior   = None
        highlevel  = True
        regulararray = False
awkward/_util.py:1014: in from_arraylib
    layout = recurse(array, mask)
        array      = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        behavior   = None
        highlevel  = True
        mask       = None
        np         = <awkward.nplike.NumpyMetadata object at 0x7f9c34b11900>
        numpy      = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        recordarray = False
        recurse    = <function from_arraylib.<locals>.recurse at 0x7f9c2c936200>
        regulararray = False
awkward/_util.py:975: in recurse
    data = ak.contents.NumpyArray(array)
        array      = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        mask       = None
        np         = <awkward.nplike.NumpyMetadata object at 0x7f9c34b11900>
        numpy      = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        recurse    = <function from_arraylib.<locals>.recurse at 0x7f9c2c936200>
        regulararray = False
awkward/contents/numpyarray.py:46: in __init__
    self._data = nplike.asarray(data)
        data       = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        identifier = None
        nplike     = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        parameters = None
        self       = <[AttributeError("'NumpyArray' object has no attribute '_data'") raised in repr()] NumpyArray object at 0x7f9c347cc220>
awkward/nplike.py:98: in asarray
    return self._module.asarray(*args, **kwargs)
        args       = (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
        kwargs     = {}
        self       = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   ???
E   TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.


cupy/_core/core.pyx:1473: TypeError
_______________________________________________________ test_from_cupy_tolist ________________________________________________________

    def test_from_cupy_tolist():
        cupy_array_1d = cp.array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
    
>       ak_cupy_array_1d = ak.from_cupy(cupy_array_1d)

cupy_array_1d = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

tests-cuda/test_1276-from-cupy.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
awkward/operations/ak_from_cupy.py:39: in from_cupy
    return ak._util.from_arraylib(array, regulararray, False, highlevel, behavior)
        array      = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
        behavior   = None
        highlevel  = True
        regulararray = False
awkward/_util.py:1014: in from_arraylib
    layout = recurse(array, mask)
        array      = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
        behavior   = None
        highlevel  = True
        mask       = None
        np         = <awkward.nplike.NumpyMetadata object at 0x7f9c34b11900>
        numpy      = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        recordarray = False
        recurse    = <function from_arraylib.<locals>.recurse at 0x7f9c2c937520>
        regulararray = False
awkward/_util.py:975: in recurse
    data = ak.contents.NumpyArray(array)
        array      = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
        mask       = None
        np         = <awkward.nplike.NumpyMetadata object at 0x7f9c34b11900>
        numpy      = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        recurse    = <function from_arraylib.<locals>.recurse at 0x7f9c2c937520>
        regulararray = False
awkward/contents/numpyarray.py:46: in __init__
    self._data = nplike.asarray(data)
        data       = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
        identifier = None
        nplike     = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        parameters = None
        self       = <[AttributeError("'NumpyArray' object has no attribute '_data'") raised in repr()] NumpyArray object at 0x7f9c347cd7b0>
awkward/nplike.py:98: in asarray
    return self._module.asarray(*args, **kwargs)
        args       = (array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]),)
        kwargs     = {}
        self       = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   ???
E   TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.


cupy/_core/core.pyx:1473: TypeError
____________________________________________________ test_NumpyArray_constructor _____________________________________________________

    def test_NumpyArray_constructor():
        assert ak.backend(ak.contents.NumpyArray(np.array([1, 2, 3]))) == "cpu"
>       assert ak.backend(ak.contents.NumpyArray(cp.array([1, 2, 3]))) == "cuda"


tests-cuda/test_1276-from-cupy.py:35: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
awkward/contents/numpyarray.py:46: in __init__
    self._data = nplike.asarray(data)
        data       = array([1, 2, 3])
        identifier = None
        nplike     = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
        parameters = None
        self       = <[AttributeError("'NumpyArray' object has no attribute '_data'") raised in repr()] NumpyArray object at 0x7f9c347ce290>
awkward/nplike.py:98: in asarray
    return self._module.asarray(*args, **kwargs)
        args       = (array([1, 2, 3]),)
        kwargs     = {}
        self       = <awkward.nplike.Numpy object at 0x7f9c3479dba0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   ???
E   TypeError: Implicit conversion to a NumPy array is not allowed. Please use `.get()` to construct a NumPy array explicitly.


cupy/_core/core.pyx:1473: TypeError
_____________________________________________________________ test_add_2 _____________________________________________________________

    def test_add_2():
        one = ak.Array([[1.1, 2.2, 3.3], [], [4.4, 5.5]], backend="cuda")
        two = 100
>       assert ak.backend(one) == "cuda"

one        = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
two        = 100

tests-cuda/test_1276-from-cupy.py:54: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
awkward/operations/ak_backend.py:35: in backend
    with ak._util.OperationErrorContext(
        arrays     = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] tuple object at 0x7f9c347b2770>
awkward/_util.py:224: in __init__
    string_arguments[key] = self.format_argument(width, value)
        __class__  = <class 'awkward._util.OperationErrorContext'>
        arguments  = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] dict object at 0x7f9c345e8640>
        key        = '*arrays'
        name       = 'ak.backend'
        self       = <awkward._util.OperationErrorContext object at 0x7f9c345f4e80>
        string_arguments = {}
        value      = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] tuple object at 0x7f9c347b2770>
        width      = 62
awkward/_util.py:205: in format_argument
    valuestr = repr(value)
        self       = <awkward._util.OperationErrorContext object at 0x7f9c345f4e80>
        value      = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] tuple object at 0x7f9c347b2770>
        valuestr   = None
        width      = 62
awkward/highlevel.py:1166: in __repr__
    return self._repr(80)
        self       = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
awkward/highlevel.py:1190: in _repr
    valuestr = " " + awkward._prettyprint.valuestr(self, 1, strwidth)
        __class__  = <class 'awkward.highlevel.Array'>
        awkward    = <module 'awkward' from '/eos/home-y/yana/Projects/Numba.20.09.2022/numba/Awkward/awkward/awkward/__init__.py'>
        limit_cols = 80
        pytype     = 'Array'
        self       = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
        strwidth   = 47
        typestr    = '3 * var * float64'
awkward/_prettyprint.py:209: in valuestr
    _, strs = valuestr_horiz(data, limit_cols)
        data       = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
        limit_cols = 47
        limit_rows = 1
awkward/_prettyprint.py:87: in valuestr_horiz
    current = get_at(data, index)
        back       = [']']
        data       = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
        forward    = True
        front      = ['[']
        index      = 0
        limit_cols = 40
        original_limit_cols = 47
        which      = 0
awkward/_prettyprint.py:42: in get_at
    out = data._layout._getitem_at(index)
        data       = <[TypeError('slice indices must be integers or None or have an __index__ method') raised in repr()] Array object at 0x7f9c345f5180>
        index      = 0
awkward/contents/listoffsetarray.py:227: in _getitem_at
    return self._content._getitem_range(slice(start, stop))
        self       = <ListOffsetArray len='3'>
    <offsets><Index dtype='int64' len='4'>
        [0 3 3 5]
    </Index></offsets>
    <content><NumpyArray dtype='float64' len='5'>[1.1 2.2 3.3 4.4 5.5]</NumpyArray></content>
</ListOffsetArray>
        start      = array(0)
        stop       = array(3)
        where      = 0
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <NumpyArray dtype='float64' len='5'>[1.1 2.2 3.3 4.4 5.5]</NumpyArray>, where = slice(array(0), array(3), None)

    def _getitem_range(self, where):
        if not self._nplike.known_shape:
            return self
    
>       start, stop, step = where.indices(self.length)
E       TypeError: slice indices must be integers or None or have an __index__ method

self       = <NumpyArray dtype='float64' len='5'>[1.1 2.2 3.3 4.4 5.5]</NumpyArray>
where      = slice(array(0), array(3), None)

awkward/contents/numpyarray.py:233: TypeError

```



Discussion:
I think my CUDA environment's been subtly broken, thanks for catching this @ianna. I'm reinstalling it now, and then I can take a look.
@jpivarski - I see that @swishdiff has implemented it for v1, not v2: https://github.com/scikit-hep/awkward/commit/90bc28bf49f8b7700b2217e84f2873722acc5bb6
> I think my CUDA environment's been subtly broken, thanks for catching this @ianna. I'm reinstalling it now, and then I can take a look.

we should also check jax tests
have we deleted `dlpack`?
Yes, we don't need it now that we handle everything in Python / CuPY

Resolving patch:
diff --git a/src/awkward/nplikes.py b/src/awkward/nplikes.py
--- a/src/awkward/nplikes.py
+++ b/src/awkward/nplikes.py
@@ -850,20 +850,51 @@ def argmax(self, *args, **kwargs):
         return out
 
 
-def is_numpy_buffer(array):
-    return isinstance(array, numpy.ndarray)
+def is_numpy_buffer(obj) -> bool:
+    """
+    Args:
+        obj: object to test
+
+    Return `True` if the given object is a numpy buffer, otherwise `False`.
+
+    """
+    return isinstance(obj, numpy.ndarray)
+
+
+def is_cupy_buffer(obj) -> bool:
+    """
+    Args:
+        obj: object to test
+
+    Return `True` if the given object is a cupy buffer, otherwise `False`.
 
+    """
+    module, _, suffix = type(obj).__module__.partition(".")
+    return module == "cupy"
+
+
+def is_jax_buffer(obj) -> bool:
+    """
+    Args:
+        obj: object to test
 
-def is_cupy_buffer(array):
-    return type(array).__module__.startswith("cupy.")
+    Return `True` if the given object is a jax buffer, otherwise `False`.
 
+    """
+    module, _, suffix = type(obj).__module__.partition(".")
+    return module == "jaxlib"
 
-def is_jax_buffer(array):
-    return type(array).__module__.startswith("jaxlib.")
 
+def is_jax_tracer(obj) -> bool:
+    """
+    Args:
+        obj: object to test
 
-def is_jax_tracer(tracer):
-    return type(tracer).__module__.startswith("jax.")
+    Return `True` if the given object is a jax tracer, otherwise `False`.
+
+    """
+    module, _, suffix = type(obj).__module__.partition(".")
+    return module == "jax"
 
 
 def nplike_of(*arrays, default_cls=Numpy):


Test patch: