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

Leverage dpnp.cumsum through dpctl.tensor implementation #1772

Merged
merged 8 commits into from
Apr 9, 2024
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
1 change: 0 additions & 1 deletion dpnp/dpnp_algo/dpnp_algo_mathematical.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ and the rest of the library

__all__ += [
"dpnp_cumprod",
"dpnp_cumsum",
"dpnp_ediff1d",
"dpnp_fabs",
"dpnp_fmod",
Expand Down
42 changes: 21 additions & 21 deletions dpnp/dpnp_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ def astype(self, dtype, order="K", casting="unsafe", subok=True, copy=True):
"""
Copy the array with data type casting.

For full documentation refer to :obj:`numpy.ndarray.astype`.
Refer to :obj:`dpnp.astype` for full documentation.

Parameters
----------
Expand Down Expand Up @@ -593,7 +593,12 @@ def astype(self, dtype, order="K", casting="unsafe", subok=True, copy=True):
# 'byteswap',

def choose(input, choices, out=None, mode="raise"):
"""Construct an array from an index array and a set of arrays to choose from."""
"""
Construct an array from an index array and a set of arrays to choose from.

Refer to :obj:`dpnp.choose` for full documentation.

"""

return dpnp.choose(input, choices, out, mode)

Expand All @@ -613,7 +618,7 @@ def conj(self):
"""
Complex-conjugate all elements.

For full documentation refer to :obj:`numpy.ndarray.conj`.
Refer to :obj:`dpnp.conjugate` for full documentation.

"""

Expand All @@ -626,7 +631,7 @@ def conjugate(self):
"""
Return the complex conjugate, element-wise.

For full documentation refer to :obj:`numpy.ndarray.conjugate`.
Refer to :obj:`dpnp.conjugate` for full documentation.

"""

Expand Down Expand Up @@ -683,9 +688,7 @@ def cumsum(self, axis=None, dtype=None, out=None):
"""
Return the cumulative sum of the elements along the given axis.

See Also
--------
:obj:`dpnp.cumsum`
Refer to :obj:`dpnp.cumsum` for full documentation.

"""

Expand All @@ -697,9 +700,7 @@ def diagonal(input, offset=0, axis1=0, axis2=1):
"""
Return specified diagonals.

See Also
--------
:obj:`dpnp.diagonal`
Refer to :obj:`dpnp.diagonal` for full documentation.

"""

Expand All @@ -709,7 +710,7 @@ def dot(self, b, out=None):
"""
Dot product of two arrays.

For full documentation refer to :obj:`dpnp.dot`.
Refer to :obj:`dpnp.dot` for full documentation.

Examples
--------
Expand Down Expand Up @@ -1013,7 +1014,7 @@ def prod(
"""
Returns the prod along a given axis.

For full documentation refer to :obj:`dpnp.prod`.
Refer to :obj:`dpnp.prod` for full documentation.

"""

Expand All @@ -1023,7 +1024,7 @@ def put(self, indices, vals, /, *, axis=None, mode="wrap"):
"""
Puts values of an array into another array along a given axis.

For full documentation refer to :obj:`numpy.put`.
Refer to :obj:`dpnp.put` for full documentation.

"""

Expand All @@ -1033,7 +1034,7 @@ def ravel(self, order="C"):
"""
Return a contiguous flattened array.

For full documentation refer to :obj:`dpnp.ravel`.
Refer to :obj:`dpnp.ravel` for full documentation.

"""

Expand Down Expand Up @@ -1083,7 +1084,7 @@ def repeat(self, repeats, axis=None):
"""
Repeat elements of an array.

For full documentation refer to :obj:`dpnp.repeat`.
Refer to :obj:`dpnp.repeat` for full documentation.

"""

Expand All @@ -1093,7 +1094,7 @@ def reshape(self, *sh, **kwargs):
"""
Returns an array containing the same data with a new shape.

For full documentation refer to :obj:`numpy.ndarray.reshape`.
Refer to :obj:`dpnp.reshape` for full documentation.

Returns
-------
Expand Down Expand Up @@ -1124,8 +1125,7 @@ def round(self, decimals=0, out=None):
"""
Return array with each element rounded to the given number of decimals.

.. seealso::
:obj:`dpnp.around` for full documentation.
Refer to :obj:`dpnp.round` for full documentation.

"""

Expand Down Expand Up @@ -1271,7 +1271,7 @@ def sum(
"""
Returns the sum along a given axis.

For full documentation refer to :obj:`dpnp.sum`.
Refer to :obj:`dpnp.sum` for full documentation.

"""

Expand All @@ -1289,7 +1289,7 @@ def swapaxes(self, axis1, axis2):
"""
Interchange two axes of an array.

For full documentation refer to :obj:`numpy.swapaxes`.
Refer to :obj:`dpnp.swapaxes` for full documentation.

"""

Expand All @@ -1299,7 +1299,7 @@ def take(self, indices, /, *, axis=None, out=None, mode="wrap"):
"""
Take elements from an array along an axis.

For full documentation refer to :obj:`numpy.take`.
Refer to :obj:`dpnp.take` for full documentation.

"""

Expand Down
98 changes: 78 additions & 20 deletions dpnp/dpnp_iface_mathematical.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,42 +855,100 @@ def cumprod(x1, **kwargs):
return call_origin(numpy.cumprod, x1, **kwargs)


def cumsum(x1, **kwargs):
def cumsum(a, axis=None, dtype=None, out=None):
"""
Return the cumulative sum of the elements along a given axis.

For full documentation refer to :obj:`numpy.cumsum`.

Limitations
-----------
Parameter `x` is supported as :obj:`dpnp.ndarray`.
Keyword argument `kwargs` is currently unsupported.
Otherwise the function will be executed sequentially on CPU.
Input array data types are limited by supported DPNP :ref:`Data types`.
Parameters
----------
a : {dpnp.ndarray, usm_ndarray}
Input array.
axis : int, optional
Axis along which the cumulative sum is computed. The default (``None``)
is to compute the cumsum over the flattened array.
dtype : dtype, optional
Type of the returned array and of the accumulator in which the elements
are summed. If `dtype` is not specified, it defaults to the dtype of
`a`, unless `a` has an integer dtype with a precision less than that of
the default platform integer. In that case, the default platform
integer is used.
out : {dpnp.ndarray, usm_ndarray}, optional
Alternative output array in which to place the result. It must have the
same shape and buffer length as the expected output but the type will
be cast if necessary.

Returns
-------
out : dpnp.ndarray
A new array holding the result is returned unless `out` is specified as
:class:`dpnp.ndarray`, in which case a reference to `out` is returned.
The result has the same size as `a`, and the same shape as `a` if `axis`
is not ``None`` or `a` is a 1-d array.

See Also
--------
:obj:`dpnp.diff` : Calculate the n-th discrete difference along the given axis.
:obj:`dpnp.sum` : Sum array elements.
:obj:`dpnp.diff` : Calculate the n-th discrete difference along given axis.

Examples
--------
>>> import dpnp as np
>>> a = np.array([1, 2, 4])
>>> result = np.cumsum(a)
>>> [x for x in result]
[1, 2, 7]
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> result = np.cumsum(b)
>>> [x for x in result]
[1, 2, 6, 10, 15, 21]
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> a
array([[1, 2, 3],
[4, 5, 6]])
>>> np.cumsum(a)
array([ 1, 3, 6, 10, 15, 21])
>>> np.cumsum(a, dtype=float) # specifies type of output value(s)
array([ 1., 3., 6., 10., 15., 21.])

>>> np.cumsum(a, axis=0) # sum over rows for each of the 3 columns
array([[1, 2, 3],
[5, 7, 9]])
>>> np.cumsum(a, axis=1) # sum over columns for each of the 2 rows
array([[ 1, 3, 6],
[ 4, 9, 15]])

``cumsum(b)[-1]`` may not be equal to ``sum(b)``

>>> b = np.array([1, 2e-9, 3e-9] * 10000)
>>> b.cumsum().dtype == b.sum().dtype == np.float64
True
>>> b.cumsum()[-1] == b.sum()
array(False)

"""

x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
if x1_desc and not kwargs:
return dpnp_cumsum(x1_desc).get_pyobj()
dpnp.check_supported_arrays_type(a)
if a.ndim > 1 and axis is None:
usm_a = dpnp.ravel(a).get_array()
else:
usm_a = dpnp.get_usm_ndarray(a)

input_out = out
if out is None:
usm_out = None
else:
dpnp.check_supported_arrays_type(out)

# get dtype used by dpctl for result array in cumulative_sum
if dtype is None:
res_dt = dtu._default_accumulation_dtype(a.dtype, a.sycl_queue)
else:
res_dt = dpnp.dtype(dtype)
res_dt = dtu._to_device_supported_dtype(res_dt, a.sycl_device)

# dpctl requires strict data type matching of out array with the result
if out.dtype != res_dt:
out = dpnp.astype(out, dtype=res_dt, copy=False)

usm_out = dpnp.get_usm_ndarray(out)

return call_origin(numpy.cumsum, x1, **kwargs)
res_usm = dpt.cumulative_sum(usm_a, axis=axis, dtype=dtype, out=usm_out)
res = dpnp_array._create_from_usm_ndarray(res_usm)
return dpnp.get_result_array(res, input_out, casting="unsafe")


def diff(a, n=1, axis=-1, prepend=None, append=None):
Expand Down
7 changes: 5 additions & 2 deletions tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ def assert_dtype_allclose(
"""

list_64bit_types = [numpy.float64, numpy.complex128]
is_inexact = lambda x: dpnp.issubdtype(x.dtype, dpnp.inexact)
is_inexact = lambda x: hasattr(x, "dtype") and dpnp.issubdtype(
x.dtype, dpnp.inexact
)

if is_inexact(dpnp_arr) or is_inexact(numpy_arr):
tol_dpnp = (
dpnp.finfo(dpnp_arr).resolution
Expand Down Expand Up @@ -73,7 +76,7 @@ def assert_dtype_allclose(
assert dpnp_arr_dtype.kind == numpy_arr_dtype.kind
else:
assert_array_equal(dpnp_arr.asnumpy(), numpy_arr)
if check_type:
if check_type and hasattr(numpy_arr, "dtype"):
if check_only_type_kind:
assert dpnp_arr.dtype.kind == numpy_arr.dtype.kind
else:
Expand Down
15 changes: 0 additions & 15 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -479,21 +479,6 @@ tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff

tests/third_party/cupy/math_tests/test_rounding.py::TestRounding::test_fix

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_ndarray_cumprod_2dim_with_axis
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_arraylike
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_huge_array
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_numpy_array
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_out_noncontiguous
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_1dim
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_2dim_without_axis

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_2_{axis=2}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_2_{axis=2}]

tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period
Expand Down
22 changes: 0 additions & 22 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -586,28 +586,6 @@ tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff

tests/third_party/cupy/math_tests/test_rounding.py::TestRounding::test_fix

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_ndarray_cumprod_2dim_with_axis
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_arraylike
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_huge_array
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_numpy_array
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_out_noncontiguous
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_1dim
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_2dim_without_axis

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_2_{axis=2}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_2_{axis=2}]

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_2_{axis=2}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_0_{axis=0}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_1_{axis=1}]
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_2_{axis=2}]

tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period
Expand Down
Loading
Loading