Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions dpnp/tests/third_party/cupy/core_tests/test_ndarray_indexing.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import unittest
import warnings

Expand All @@ -6,6 +8,10 @@

import dpnp as cupy
from dpnp.tests.third_party.cupy import testing
from dpnp.tests.third_party.cupy.testing._protocol_helpers import (
DummyObjectWithCudaArrayInterface,
DummyObjectWithCuPyGetNDArray,
)

if numpy.lib.NumpyVersion(numpy.__version__) >= "2.0.0b1":
from numpy.exceptions import ComplexWarning
Expand Down Expand Up @@ -130,9 +136,30 @@
)
class TestArrayIndexingParameterized(unittest.TestCase):

_getitem_hip_skip_condition = [
((1, 0, 2), (2, 3, 4), None),
((-1, 0, -2), (2, 3, 4), None),
((1, 0, 2), (2, 3, 4), (2, 0, 1)),
((-1, 0, -2), (2, 3, 4), (2, 0, 1)),
((slice(None, None, None), None), (2,), None),
((slice(-9, -10, -1),), (10,), None),
((slice(-4, -5, -1),), (10,), None),
((slice(-5, -6, -1),), (10,), None),
]

def _check_getitem_hip_skip_condition(self):
return (
self.indexes,
self.shape,
self.transpose,
) in self._getitem_hip_skip_condition

@testing.for_all_dtypes()
@testing.numpy_cupy_array_equal()
def test_getitem(self, xp, dtype):
# if cupy.cuda.runtime.is_hip:
# if self._check_getitem_hip_skip_condition():
# pytest.xfail("HIP may have a bug")
a = testing.shaped_arange(self.shape, xp, dtype)
if self.transpose:
a = a.transpose(self.transpose)
Expand Down Expand Up @@ -261,3 +288,18 @@ def test_remain0d(self, xp):
a = xp.zeros((2, 3, 4), dtype=dtype)
a[0, 1, 2] = testing.shaped_arange((), xp, dtype)
return a


@pytest.mark.skip("CUDA array interface is not supported")
@pytest.mark.parametrize(
"cupy_like",
[
DummyObjectWithCuPyGetNDArray,
DummyObjectWithCudaArrayInterface,
],
)
def test_setitem_with_cupy_like(cupy_like):
# Test that normal assignment supports interfaces
a = cupy.zeros(10)
a[...] = cupy_like(cupy.arange(10))
testing.assert_array_equal(a, cupy.arange(10))
36 changes: 31 additions & 5 deletions dpnp/tests/third_party/cupy/core_tests/test_reduction.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
from __future__ import annotations

import unittest

import numpy
import pytest
from dpctl.tensor._numpy_helper import AxisError

import dpnp as cupy

# import cupy._core._accelerator as _acc
# from cupy import _core
from dpnp.tests.third_party.cupy import testing
from dpnp.tests.third_party.cupy.testing._protocol_helpers import (
DummyObjectWithCudaArrayInterface,
DummyObjectWithCuPyGetNDArray,
)

# from cupy.exceptions import ComplexWarning, AxisError

if numpy.lib.NumpyVersion(numpy.__version__) >= "2.0.0b1":
from numpy.exceptions import ComplexWarning
else:
from numpy import ComplexWarning

pytest.skip(
"create/get_reduction_func() and ReductionKernel are not supported",
Expand Down Expand Up @@ -258,3 +261,26 @@ def test_large_dims_keep_kernels(self):
shape = (4, 3, 2, 4, 3, 2, 2)
axis = (1, 4, 3, 6)
self.check_int8_sum(shape, axis=axis, keepdims=True)


class TestArgumentTypes:
kernel = _core.create_reduction_func(
"my_sum", ("f->f",), ("in0", "a + b", "out0 = a", None), 0
)

@pytest.mark.parametrize(
"cupy_like",
[
DummyObjectWithCuPyGetNDArray,
DummyObjectWithCudaArrayInterface,
],
)
def test_cupy_like_protocols(self, cupy_like):
# Check that reduction kernels work on the cupy like protocols
x = cupy_like(cupy.arange(10, dtype=cupy.float32))
res = self.kernel(x)
assert res == 45

def test_bad_argument(self):
with pytest.raises(TypeError, match="Argument 'a' has incorrect type"):
self.kernel(numpy.array([1, 2, 3]))
100 changes: 35 additions & 65 deletions dpnp/tests/third_party/cupy/creation_tests/test_from_data.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import annotations

import os
import tempfile
import unittest

Expand All @@ -8,6 +11,10 @@
import dpnp as cupy
from dpnp.tests.helper import has_support_aspect64, is_cuda_device
from dpnp.tests.third_party.cupy import testing
from dpnp.tests.third_party.cupy.testing._protocol_helpers import (
DummyObjectWithCudaArrayInterface,
DummyObjectWithCuPyGetNDArray,
)


class TestFromData(unittest.TestCase):
Expand Down Expand Up @@ -37,6 +44,11 @@ def test_array_from_numpy(self, xp, dtype, order):
a = testing.shaped_arange((2, 3, 4), numpy, dtype)
return xp.array(a, order=order)

@pytest.mark.skip("no blocking keyword")
def test_array_from_numpy_blocking(self):
a = testing.shaped_arange((2, 3, 4), numpy, numpy.float32)
testing.assert_array_equal(cupy.array(a, blocking=True), a)

@testing.for_orders("CFAK")
@testing.for_all_dtypes()
@testing.numpy_cupy_array_equal()
Expand Down Expand Up @@ -242,7 +254,7 @@ def test_array_copy_with_dtype_being_none(self, xp, order):
@testing.for_orders("CFAK", name="dst_order")
@testing.for_all_dtypes(name="dtype1", no_complex=True)
@testing.for_all_dtypes(name="dtype2")
@testing.numpy_cupy_array_equal()
@testing.numpy_cupy_array_equal(strides_check=True)
def test_array_copy_list_of_numpy_with_dtype(
self, xp, dtype1, dtype2, src_order, dst_order
):
Expand All @@ -258,7 +270,7 @@ def test_array_copy_list_of_numpy_with_dtype(
@testing.for_orders("CFAK", name="dst_order")
@testing.for_all_dtypes(name="dtype1", no_complex=True)
@testing.for_all_dtypes(name="dtype2")
@testing.numpy_cupy_array_equal()
@testing.numpy_cupy_array_equal(strides_check=True)
def test_array_copy_list_of_numpy_with_dtype_char(
self, xp, dtype1, dtype2, src_order, dst_order
):
Expand All @@ -274,7 +286,7 @@ def test_array_copy_list_of_numpy_with_dtype_char(
@testing.for_orders("CFAK", name="dst_order")
@testing.for_all_dtypes(name="dtype1", no_complex=True)
@testing.for_all_dtypes(name="dtype2")
@testing.numpy_cupy_array_equal()
@testing.numpy_cupy_array_equal(strides_check=True)
def test_array_copy_list_of_cupy_with_dtype(
self, xp, dtype1, dtype2, src_order, dst_order
):
Expand All @@ -290,7 +302,7 @@ def test_array_copy_list_of_cupy_with_dtype(
@testing.for_orders("CFAK", name="dst_order")
@testing.for_all_dtypes(name="dtype1", no_complex=True)
@testing.for_all_dtypes(name="dtype2")
@testing.numpy_cupy_array_equal()
@testing.numpy_cupy_array_equal(strides_check=True)
def test_array_copy_list_of_cupy_with_dtype_char(
self, xp, dtype1, dtype2, src_order, dst_order
):
Expand Down Expand Up @@ -401,6 +413,11 @@ def test_asarray(self, xp, dtype):
a = testing.shaped_arange((2, 3, 4), xp, dtype)
return xp.asarray(a)

@pytest.mark.skip("no blocking keyword")
def test_asarray_blocking(self):
a = testing.shaped_arange((2, 3, 4), numpy, numpy.float32)
testing.assert_array_equal(cupy.asarray(a, blocking=True), a)

@testing.for_all_dtypes()
@testing.numpy_cupy_array_equal()
def test_asarray_is_not_copied(self, xp, dtype):
Expand Down Expand Up @@ -454,6 +471,11 @@ def test_asanyarray_from_big_endian(self, xp, dtype):
# happens to work before the change in #5828
return b + b

@pytest.mark.skip("no blocking keyword")
def test_asanyarray_blocking(self):
a = testing.shaped_arange((2, 3, 4), numpy, numpy.float32)
testing.assert_array_equal(cupy.asanyarray(a, blocking=True), a)

@testing.for_CF_orders()
@testing.for_all_dtypes()
@testing.numpy_cupy_array_equal()
Expand Down Expand Up @@ -727,67 +749,6 @@ def test_with_over_size_array(self):
testing.assert_array_equal(a, b)


class DummyObjectWithCudaArrayInterface:
def __init__(self, a, ver, include_strides=False, mask=None, stream=None):
assert ver in tuple(range(max_cuda_array_interface_version + 1))
self.a = None
if isinstance(a, cupy.ndarray):
self.a = a
else:
self.shape, self.strides, self.typestr, self.descr, self.data = a
self.ver = ver
self.include_strides = include_strides
self.mask = mask
self.stream = stream

@property
def __cuda_array_interface__(self):
if self.a is not None:
desc = {
"shape": self.a.shape,
"typestr": self.a.dtype.str,
"descr": self.a.dtype.descr,
"data": (self.a.data.ptr, False),
"version": self.ver,
}
if self.a.flags.c_contiguous:
if self.include_strides is True:
desc["strides"] = self.a.strides
elif self.include_strides is None:
desc["strides"] = None
else: # self.include_strides is False
pass
else: # F contiguous or neither
desc["strides"] = self.a.strides
else:
desc = {
"shape": self.shape,
"typestr": self.typestr,
"descr": self.descr,
"data": (self.data, False),
"version": self.ver,
}
if self.include_strides is True:
desc["strides"] = self.strides
elif self.include_strides is None:
desc["strides"] = None
else: # self.include_strides is False
pass
if self.mask is not None:
desc["mask"] = self.mask
# The stream field is kept here for compliance. However, since the
# synchronization is done via calling a cpdef function, which cannot
# be mock-tested.
if self.stream is not None:
if self.stream is cuda.Stream.null:
desc["stream"] = cuda.runtime.streamLegacy
elif (not cuda.runtime.is_hip) and self.stream is cuda.Stream.ptds:
desc["stream"] = cuda.runtime.streamPerThread
else:
desc["stream"] = self.stream.ptr
return desc


@testing.parameterize(
*testing.product(
{
Expand Down Expand Up @@ -848,3 +809,12 @@ def test_invalid_type(self):
a = numpy.array([1, 2, 3], dtype=object)
with self.assertRaises(TypeError):
cupy.array(a)


@pytest.mark.skip("CUDA array interface is not supported")
class TestArrayCuPyGetNDArray(unittest.TestCase):
def test_cupy_get_ndarray(self):
a = cupy.array([1, 2, 3])
dummy = DummyObjectWithCuPyGetNDArray(a)
res = cupy.asarray(dummy)
assert a is res # OK if it was a view
6 changes: 5 additions & 1 deletion dpnp/tests/third_party/cupy/testing/_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,11 @@ def assert_array_equal(
)

if strides_check:
strides = tuple(el // desired.itemsize for el in desired.strides)
strides = desired.strides
if isinstance(actual, cupy.ndarray):
# need to agreed the strides with numpy.ndarray
strides = tuple(el // desired.itemsize for el in desired.strides)

if actual.strides != strides:
msg = ["Strides are not equal:"]
if err_msg:
Expand Down
79 changes: 79 additions & 0 deletions dpnp/tests/third_party/cupy/testing/_protocol_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from __future__ import annotations

import dpnp as cupy

# from cupy import cuda


max_cuda_array_interface_version = 3


class DummyObjectWithCudaArrayInterface:
# Private helper used for testing cuda array interface support.
def __init__(self, a, ver=3, include_strides=False, mask=None, stream=None):
assert ver in tuple(range(max_cuda_array_interface_version + 1))
self.a = None
if isinstance(a, cupy.ndarray):
self.a = a
else:
self.shape, self.strides, self.typestr, self.descr, self.data = a
self.ver = ver
self.include_strides = include_strides
self.mask = mask
self.stream = stream

@property
def __cuda_array_interface__(self):
if self.a is not None:
desc = {
"shape": self.a.shape,
"typestr": self.a.dtype.str,
"descr": self.a.dtype.descr,
"data": (self.a.data.ptr, False),
"version": self.ver,
}
if self.a.flags.c_contiguous:
if self.include_strides is True:
desc["strides"] = self.a.strides
elif self.include_strides is None:
desc["strides"] = None
else: # self.include_strides is False
pass
else: # F contiguous or neither
desc["strides"] = self.a.strides
else:
desc = {
"shape": self.shape,
"typestr": self.typestr,
"descr": self.descr,
"data": (self.data, False),
"version": self.ver,
}
if self.include_strides is True:
desc["strides"] = self.strides
elif self.include_strides is None:
desc["strides"] = None
else: # self.include_strides is False
pass
if self.mask is not None:
desc["mask"] = self.mask
# The stream field is kept here for compliance. However, since the
# synchronization is done via calling a cpdef function, which cannot
# be mock-tested.
if self.stream is not None:
if self.stream is cuda.Stream.null:
desc["stream"] = cuda.runtime.streamLegacy
elif (not cuda.runtime.is_hip) and self.stream is cuda.Stream.ptds:
desc["stream"] = cuda.runtime.streamPerThread
else:
desc["stream"] = self.stream.ptr
return desc


class DummyObjectWithCuPyGetNDArray:
# Private helper used for testing `__cupy_get_ndarray__` support.
def __init__(self, a):
self.a = a

def __cupy_get_ndarray__(self):
return self.a
Loading