Skip to content

Commit ac06d57

Browse files
committed
Implement dpnp.cumsum through dpctl.tensor
1 parent a134bdc commit ac06d57

File tree

5 files changed

+497
-78
lines changed

5 files changed

+497
-78
lines changed

dpnp/dpnp_algo/dpnp_algo_mathematical.pxi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ and the rest of the library
3737

3838
__all__ += [
3939
"dpnp_cumprod",
40-
"dpnp_cumsum",
4140
"dpnp_ediff1d",
4241
"dpnp_fabs",
4342
"dpnp_fmod",

dpnp/dpnp_iface_mathematical.py

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040

4141
import dpctl.tensor as dpt
42+
import dpctl.tensor._accumulation as da
4243
import dpctl.utils as du
4344
import numpy
4445
from numpy.core.numeric import (
@@ -855,42 +856,101 @@ def cumprod(x1, **kwargs):
855856
return call_origin(numpy.cumprod, x1, **kwargs)
856857

857858

858-
def cumsum(x1, **kwargs):
859+
def cumsum(a, axis=None, dtype=None, out=None):
859860
"""
860861
Return the cumulative sum of the elements along a given axis.
861862
862863
For full documentation refer to :obj:`numpy.cumsum`.
863864
864-
Limitations
865-
-----------
866-
Parameter `x` is supported as :obj:`dpnp.ndarray`.
867-
Keyword argument `kwargs` is currently unsupported.
868-
Otherwise the function will be executed sequentially on CPU.
869-
Input array data types are limited by supported DPNP :ref:`Data types`.
865+
Parameters
866+
----------
867+
a : {dpnp.ndarray, usm_ndarray}
868+
Input array.
869+
axis : int, optional
870+
Axis along which the cumulative sum is computed. The default (``None``)
871+
is to compute the cumsum over the flattened array.
872+
dtype : dtype, optional
873+
Type of the returned array and of the accumulator in which the elements
874+
are summed. If `dtype` is not specified, it defaults to the dtype of
875+
`a`, unless `a` has an integer dtype with a precision less than that of
876+
the default platform integer. In that case, the default platform
877+
integer is used.
878+
out : {dpnp.ndarray, usm_ndarray}, optional
879+
Alternative output array in which to place the result. It must have the
880+
same shape and buffer length as the expected output but the type will
881+
be cast if necessary.
882+
883+
Returns
884+
-------
885+
out : dpnp.ndarray
886+
A new array holding the result is returned unless `out` is specified,
887+
in which case a reference to `out` is returned. The result has the same
888+
size as `a`, and the same shape as `a` if `axis` is not ``None`` or `a`
889+
is a 1-d array.
870890
871891
See Also
872892
--------
873-
:obj:`dpnp.diff` : Calculate the n-th discrete difference along the given axis.
893+
:obj:`dpnp.sum` : Sum array elements.
894+
:obj:`dpnp.diff` : Calculate the n-th discrete difference along given axis.
874895
875896
Examples
876897
--------
877898
>>> import dpnp as np
878-
>>> a = np.array([1, 2, 4])
879-
>>> result = np.cumsum(a)
880-
>>> [x for x in result]
881-
[1, 2, 7]
882-
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
883-
>>> result = np.cumsum(b)
884-
>>> [x for x in result]
885-
[1, 2, 6, 10, 15, 21]
899+
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
900+
>>> a
901+
array([[1, 2, 3],
902+
[4, 5, 6]])
903+
>>> np.cumsum(a)
904+
array([ 1, 3, 6, 10, 15, 21])
905+
>>> np.cumsum(a, dtype=float) # specifies type of output value(s)
906+
array([ 1., 3., 6., 10., 15., 21.])
907+
908+
>>> np.cumsum(a, axis=0) # sum over rows for each of the 3 columns
909+
array([[1, 2, 3],
910+
[5, 7, 9]])
911+
>>> np.cumsum(a, axis=1) # sum over columns for each of the 2 rows
912+
array([[ 1, 3, 6],
913+
[ 4, 9, 15]])
914+
915+
``cumsum(b)[-1]`` may not be equal to ``sum(b)``
916+
917+
>>> b = np.array([1, 2e-9, 3e-9] * 10000)
918+
>>> b.cumsum().dtype == b.sum().dtype == np.float64
919+
True
920+
>>> b.cumsum()[-1] == b.sum()
921+
array(False)
886922
887923
"""
888924

889-
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
890-
if x1_desc and not kwargs:
891-
return dpnp_cumsum(x1_desc).get_pyobj()
925+
dpnp.check_supported_arrays_type(a)
926+
if a.ndim > 1 and axis is None:
927+
usm_a = dpnp.ravel(a).get_array()
928+
else:
929+
usm_a = dpnp.get_usm_ndarray(a)
930+
931+
input_out = out
932+
if out is None:
933+
usm_out = None
934+
else:
935+
dpnp.check_supported_arrays_type(out)
936+
if dpnp.issubdtype(out.dtype, dpnp.integer):
937+
int_dt = da._default_accumulation_dtype(out.dtype, out.sycl_queue)
938+
939+
# create a copy if dtype mismatches default integer type
940+
out = dpnp.astype(out, dtype=int_dt, copy=False)
892941

893-
return call_origin(numpy.cumsum, x1, **kwargs)
942+
usm_out = dpnp.get_usm_ndarray(out)
943+
944+
res_usm = dpt.cumulative_sum(usm_a, axis=axis, dtype=dtype, out=usm_out)
945+
if out is None:
946+
return dpnp_array._create_from_usm_ndarray(res_usm)
947+
elif input_out is not out:
948+
dpnp.copyto(input_out, out, casting="unsafe")
949+
950+
if not isinstance(input_out, dpnp_array):
951+
return dpnp_array._create_from_usm_ndarray(input_out)
952+
else:
953+
return out
894954

895955

896956
def diff(a, n=1, axis=-1, prepend=None, append=None):

tests/skipped_tests.tbl

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -502,21 +502,6 @@ tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff
502502

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

505-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_ndarray_cumprod_2dim_with_axis
506-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_arraylike
507-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_huge_array
508-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_numpy_array
509-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_out_noncontiguous
510-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_1dim
511-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_2dim_without_axis
512-
513-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_0_{axis=0}]
514-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_1_{axis=1}]
515-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_2_{axis=2}]
516-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_0_{axis=0}]
517-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_1_{axis=1}]
518-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_2_{axis=2}]
519-
520505
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
521506
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
522507
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period

tests/skipped_tests_gpu.tbl

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -599,28 +599,6 @@ tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff
599599

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

602-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_ndarray_cumprod_2dim_with_axis
603-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_arraylike
604-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_huge_array
605-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_numpy_array
606-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_out_noncontiguous
607-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_1dim
608-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_2dim_without_axis
609-
610-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_0_{axis=0}]
611-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_1_{axis=1}]
612-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum[_param_2_{axis=2}]
613-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_0_{axis=0}]
614-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_1_{axis=1}]
615-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_2dim[_param_2_{axis=2}]
616-
617-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_0_{axis=0}]
618-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_1_{axis=1}]
619-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_arraylike[_param_2_{axis=2}]
620-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_0_{axis=0}]
621-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_1_{axis=1}]
622-
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum::test_cumsum_numpy_array[_param_2_{axis=2}]
623-
624602
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
625603
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
626604
tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period

0 commit comments

Comments
 (0)