Skip to content

Commit 6635c36

Browse files
authored
Merge branch 'master' into std_var
2 parents 34135eb + 28d3348 commit 6635c36

18 files changed

+416
-206
lines changed

.github/workflows/build-sphinx.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
9898
- name: Install dpnp dependencies
9999
run: |
100-
conda install numpy"<1.24" dpctl">=0.15.1dev2" mkl-devel-dpcpp onedpl-devel tbb-devel dpcpp_linux-64 \
100+
conda install numpy"<1.24" dpctl">=0.15.1dev2" mkl-devel-dpcpp onedpl-devel tbb-devel dpcpp_linux-64"<2024.0.1" \
101101
cmake cython pytest ninja scikit-build sysroot_linux-64">=2.28" ${{ env.CHANNELS }}
102102
103103
- name: Install cuPy dependencies

.github/workflows/conda-package.yml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,7 @@ env:
3838
third_party/cupy/manipulation_tests/test_join.py
3939
third_party/cupy/manipulation_tests/test_rearrange.py
4040
third_party/cupy/manipulation_tests/test_transpose.py
41-
third_party/cupy/math_tests/test_arithmetic.py
42-
third_party/cupy/math_tests/test_explog.py
43-
third_party/cupy/math_tests/test_floating.py
44-
third_party/cupy/math_tests/test_hyperbolic.py
45-
third_party/cupy/math_tests/test_matmul.py
46-
third_party/cupy/math_tests/test_misc.py
47-
third_party/cupy/math_tests/test_rounding.py
48-
third_party/cupy/math_tests/test_trigonometric.py
41+
third_party/cupy/math_tests
4942
third_party/cupy/sorting_tests/test_sort.py
5043
third_party/cupy/sorting_tests/test_count.py
5144
third_party/cupy/statistics_tests/test_meanvar.py

.github/workflows/generate_coverage.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,22 @@ jobs:
5353
conda list
5454
5555
- name: Build dpnp with coverage
56+
id: build_coverage
57+
uses: nick-fields/retry@v2.9.0
58+
with:
59+
shell: bash
60+
timeout_minutes: 60
61+
max_attempts: 5
62+
retry_on: error
63+
command: |
64+
. $CONDA/etc/profile.d/conda.sh
65+
conda activate coverage
66+
git clean -fxd
67+
python scripts/gen_coverage.py --pytest-opts="--ignore tests/test_random.py"
68+
69+
- name: Total number of coverage attempts
5670
run: |
57-
python scripts/gen_coverage.py --pytest-opts="--ignore tests/test_random.py"
71+
echo "Total number of coverage attempts made: ${{ steps.build_coverage.outputs.total_attempts }}"
5872
5973
- name: Install coverall dependencies
6074
run: |

conda-recipe/meta.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{% set required_compiler_and_mkl_version = "2024.0" %}
2+
{% set max_compiler_version = "2024.0.1" %}
23
{% set required_dpctl_version = "0.15.1dev2" %}
34

45
package:
@@ -24,7 +25,7 @@ requirements:
2425
- scikit-build
2526
build:
2627
- {{ compiler('cxx') }}
27-
- {{ compiler('dpcpp') }} >={{ required_compiler_and_mkl_version }} # [not osx]
28+
- {{ compiler('dpcpp') }} >={{ required_compiler_and_mkl_version }},<{{ max_compiler_version }} # [not osx]
2829
- sysroot_linux-64 >=2.28 # [linux]
2930
run:
3031
- python

dpnp/dpnp_algo/dpnp_algo_mathematical.pxi

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ __all__ += [
3939
"dpnp_cross",
4040
"dpnp_cumprod",
4141
"dpnp_cumsum",
42-
"dpnp_diff",
4342
"dpnp_ediff1d",
4443
"dpnp_fabs",
4544
"dpnp_fmod",
@@ -95,35 +94,6 @@ cpdef utils.dpnp_descriptor dpnp_cumsum(utils.dpnp_descriptor x1):
9594
return call_fptr_1in_1out(DPNP_FN_CUMSUM_EXT, x1, (x1.size,))
9695

9796

98-
cpdef utils.dpnp_descriptor dpnp_diff(utils.dpnp_descriptor x1, int n):
99-
cdef utils.dpnp_descriptor res
100-
101-
x1_obj = x1.get_array()
102-
103-
if x1.size - n < 1:
104-
res_obj = dpnp_container.empty(0,
105-
dtype=x1.dtype,
106-
device=x1_obj.sycl_device,
107-
usm_type=x1_obj.usm_type,
108-
sycl_queue=x1_obj.sycl_queue)
109-
res = utils.dpnp_descriptor(res_obj)
110-
return res
111-
112-
res_obj = dpnp_container.empty(x1.size - 1,
113-
dtype=x1.dtype,
114-
device=x1_obj.sycl_device,
115-
usm_type=x1_obj.usm_type,
116-
sycl_queue=x1_obj.sycl_queue)
117-
res = utils.dpnp_descriptor(res_obj)
118-
for i in range(res.size):
119-
res.get_pyobj()[i] = x1.get_pyobj()[i + 1] - x1.get_pyobj()[i]
120-
121-
if n == 1:
122-
return res
123-
124-
return dpnp_diff(res, n - 1)
125-
126-
12797
cpdef utils.dpnp_descriptor dpnp_ediff1d(utils.dpnp_descriptor x1):
12898

12999
if x1.size <= 1:

dpnp/dpnp_iface_indexing.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -550,17 +550,24 @@ def put_along_axis(a, indices, values, axis):
550550
551551
For full documentation refer to :obj:`numpy.put_along_axis`.
552552
553-
Limitations
554-
-----------
555-
Parameters `a` and `indices` are supported either as :class:`dpnp.ndarray`
556-
or :class:`dpctl.tensor.usm_ndarray`.
557-
Parameter `values` is supported either as scalar, :class:`dpnp.ndarray`
558-
or :class:`dpctl.tensor.usm_ndarray`.
559-
Otherwise ``TypeError`` exception will be raised.
553+
Parameters
554+
----------
555+
a : {dpnp.ndarray, usm_ndarray}, (Ni..., M, Nk...)
556+
Destination array.
557+
indices : {dpnp.ndarray, usm_ndarray}, (Ni..., J, Nk...)
558+
Indices to change along each 1d slice of `a`. This must match the
559+
dimension of input array, but dimensions in ``Ni`` and ``Nj``
560+
may be 1 to broadcast against `a`.
561+
values : {scalar, array_like}, (Ni..., J, Nk...)
562+
Values to insert at those indices. Its shape and dimension are
563+
broadcast to match that of `indices`.
564+
axis : int
565+
The axis to take 1d slices along. If axis is ``None``, the destination
566+
array is treated as if a flattened 1d view had been created of it.
560567
561568
See Also
562569
--------
563-
:obj:`dpnp.put` : Put values along an axis, using the same indices for every 1d slice.
570+
:obj:`dpnp.put` : Put values along an axis, using the same indices for every 1d slice.
564571
:obj:`dpnp.take_along_axis` : Take values from the input array by matching 1d index and data slices.
565572
566573
Examples
@@ -736,17 +743,24 @@ def take_along_axis(a, indices, axis):
736743
737744
For full documentation refer to :obj:`numpy.take_along_axis`.
738745
746+
Parameters
747+
----------
748+
a : {dpnp.ndarray, usm_ndarray}, (Ni..., M, Nk...)
749+
Source array
750+
indices : {dpnp.ndarray, usm_ndarray}, (Ni..., J, Nk...)
751+
Indices to take along each 1d slice of `a`. This must match the
752+
dimension of the input array, but dimensions ``Ni`` and ``Nj``
753+
only need to broadcast against `a`.
754+
axis : int
755+
The axis to take 1d slices along. If axis is ``None``, the input
756+
array is treated as if it had first been flattened to 1d,
757+
for consistency with `sort` and `argsort`.
758+
739759
Returns
740760
-------
741761
out : dpnp.ndarray
742762
The indexed result.
743763
744-
Limitations
745-
-----------
746-
Parameters `a` and `indices` are supported either as :class:`dpnp.ndarray`
747-
or :class:`dpctl.tensor.usm_ndarray`.
748-
Otherwise ``TypeError`` exception will be raised.
749-
750764
See Also
751765
--------
752766
:obj:`dpnp.take` : Take along an axis, using the same indices for every 1d slice.

dpnp/dpnp_iface_mathematical.py

Lines changed: 126 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@
4141
import dpctl.tensor as dpt
4242
import dpctl.utils as du
4343
import numpy
44-
from numpy.core.numeric import normalize_axis_tuple
44+
from numpy.core.numeric import (
45+
normalize_axis_index,
46+
normalize_axis_tuple,
47+
)
4548

4649
import dpnp
4750
from dpnp.dpnp_array import dpnp_array
@@ -123,6 +126,31 @@
123126
]
124127

125128

129+
def _append_to_diff_array(a, axis, combined, values):
130+
"""
131+
Append `values` to `combined` list based on data of array `a`.
132+
133+
Scalar value (including case with 0d array) is expanded to an array
134+
with length=1 in the direction of axis and the shape of the input array `a`
135+
in along all other axes.
136+
Note, if `values` is a scalar. then it is converted to 0d array allocating
137+
on the same SYCL queue as the input array `a` and with the same USM type.
138+
139+
"""
140+
141+
dpnp.check_supported_arrays_type(values, scalar_type=True)
142+
if dpnp.isscalar(values):
143+
values = dpnp.asarray(
144+
values, sycl_queue=a.sycl_queue, usm_type=a.usm_type
145+
)
146+
147+
if values.ndim == 0:
148+
shape = list(a.shape)
149+
shape[axis] = 1
150+
values = dpnp.broadcast_to(values, tuple(shape))
151+
combined.append(values)
152+
153+
126154
def absolute(
127155
x,
128156
/,
@@ -603,6 +631,10 @@ def cumsum(x1, **kwargs):
603631
Otherwise the function will be executed sequentially on CPU.
604632
Input array data types are limited by supported DPNP :ref:`Data types`.
605633
634+
See Also
635+
--------
636+
:obj:`dpnp.diff` : Calculate the n-th discrete difference along the given axis.
637+
606638
Examples
607639
--------
608640
>>> import dpnp as np
@@ -624,39 +656,95 @@ def cumsum(x1, **kwargs):
624656
return call_origin(numpy.cumsum, x1, **kwargs)
625657

626658

627-
def diff(x1, n=1, axis=-1, prepend=numpy._NoValue, append=numpy._NoValue):
659+
def diff(a, n=1, axis=-1, prepend=None, append=None):
628660
"""
629661
Calculate the n-th discrete difference along the given axis.
630662
631663
For full documentation refer to :obj:`numpy.diff`.
632664
633-
Limitations
634-
-----------
635-
Input array is supported as :obj:`dpnp.ndarray`.
636-
Parameters `axis`, `prepend` and `append` are supported only with default values.
637-
Otherwise the function will be executed sequentially on CPU.
665+
Parameters
666+
----------
667+
a : {dpnp.ndarray, usm_ndarray}
668+
Input array
669+
n : int, optional
670+
The number of times values are differenced. If zero, the input
671+
is returned as-is.
672+
axis : int, optional
673+
The axis along which the difference is taken, default is the
674+
last axis.
675+
prepend, append : {scalar, dpnp.ndarray, usm_ndarray}, optional
676+
Values to prepend or append to `a` along axis prior to
677+
performing the difference. Scalar values are expanded to
678+
arrays with length 1 in the direction of axis and the shape
679+
of the input array in along all other axes. Otherwise the
680+
dimension and shape must match `a` except along axis.
681+
682+
Returns
683+
-------
684+
out : dpnp.ndarray
685+
The n-th differences. The shape of the output is the same as `a`
686+
except along `axis` where the dimension is smaller by `n`. The
687+
type of the output is the same as the type of the difference
688+
between any two elements of `a`. This is the same as the type of
689+
`a` in most cases.
690+
691+
See Also
692+
--------
693+
:obj:`dpnp.gradient` : Return the gradient of an N-dimensional array.
694+
:obj:`dpnp.ediff1d` : Compute the differences between consecutive elements of an array.
695+
:obj:`dpnp.cumsum` : Return the cumulative sum of the elements along a given axis.
696+
697+
Examples
698+
--------
699+
>>> import dpnp as np
700+
>>> x = np.array([1, 2, 4, 7, 0])
701+
>>> np.diff(x)
702+
array([ 1, 2, 3, -7])
703+
>>> np.diff(x, n=2)
704+
array([ 1, 1, -10])
705+
706+
>>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]])
707+
>>> np.diff(x)
708+
array([[2, 3, 4],
709+
[5, 1, 2]])
710+
>>> np.diff(x, axis=0)
711+
array([[-1, 2, 0, -2]])
712+
638713
"""
639714

640-
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
641-
if x1_desc:
642-
if not isinstance(n, int):
643-
pass
644-
elif n < 1:
645-
pass
646-
elif x1_desc.ndim != 1:
647-
pass
648-
elif axis != -1:
649-
pass
650-
elif prepend is not numpy._NoValue:
651-
pass
652-
elif append is not numpy._NoValue:
653-
pass
654-
else:
655-
return dpnp_diff(x1_desc, n).get_pyobj()
715+
dpnp.check_supported_arrays_type(a)
716+
if n == 0:
717+
return a
718+
if n < 0:
719+
raise ValueError(f"order must be non-negative but got {n}")
656720

657-
return call_origin(
658-
numpy.diff, x1, n=n, axis=axis, prepend=prepend, append=append
659-
)
721+
nd = a.ndim
722+
if nd == 0:
723+
raise ValueError("diff requires input that is at least one dimensional")
724+
axis = normalize_axis_index(axis, nd)
725+
726+
combined = []
727+
if prepend is not None:
728+
_append_to_diff_array(a, axis, combined, prepend)
729+
730+
combined.append(a)
731+
if append is not None:
732+
_append_to_diff_array(a, axis, combined, append)
733+
734+
if len(combined) > 1:
735+
a = dpnp.concatenate(combined, axis=axis)
736+
737+
slice1 = [slice(None)] * nd
738+
slice2 = [slice(None)] * nd
739+
slice1[axis] = slice(1, None)
740+
slice2[axis] = slice(None, -1)
741+
slice1 = tuple(slice1)
742+
slice2 = tuple(slice2)
743+
744+
op = dpnp.not_equal if a.dtype == numpy.bool_ else dpnp.subtract
745+
for _ in range(n):
746+
a = op(a[slice1], a[slice2])
747+
return a
660748

661749

662750
def divide(
@@ -1270,6 +1358,10 @@ def gradient(x1, *varargs, **kwargs):
12701358
Otherwise the function will be executed sequentially on CPU.
12711359
Input array data types are limited by supported DPNP :ref:`Data types`.
12721360
1361+
See Also
1362+
--------
1363+
:obj:`dpnp.diff` : Calculate the n-th discrete difference along the given axis.
1364+
12731365
Examples
12741366
--------
12751367
>>> import dpnp as np
@@ -1379,11 +1471,11 @@ def maximum(
13791471
--------
13801472
:obj:`dpnp.minimum` : Element-wise minimum of two arrays, propagates NaNs.
13811473
:obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs.
1382-
:obj:`dpnp.amax` : The maximum value of an array along a given axis, propagates NaNs.
1383-
:obj:`dpnp.nanmax` : The maximum value of an array along a given axis, ignores NaNs.
1384-
:obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs.
1385-
:obj:`dpnp.amax` : The maximum value of an array along a given axis, propagates NaNs.
1474+
:obj:`dpnp.max` : The maximum value of an array along a given axis, propagates NaNs.
13861475
:obj:`dpnp.nanmax` : The maximum value of an array along a given axis, ignores NaNs.
1476+
:obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs.
1477+
:obj:`dpnp.min` : The minimum value of an array along a given axis, propagates NaNs.
1478+
:obj:`dpnp.nanmin` : The minimum value of an array along a given axis, ignores NaNs.
13871479
13881480
Examples
13891481
--------
@@ -1458,11 +1550,11 @@ def minimum(
14581550
--------
14591551
:obj:`dpnp.maximum` : Element-wise maximum of two arrays, propagates NaNs.
14601552
:obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs.
1461-
:obj:`dpnp.amin` : The minimum value of an array along a given axis, propagates NaNs.
1462-
:obj:`dpnp.nanmin` : The minimum value of an array along a given axis, ignores NaNs.
1463-
:obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs.
1464-
:obj:`dpnp.amin` : The minimum value of an array along a given axis, propagates NaNs.
1553+
:obj:`dpnp.min` : The minimum value of an array along a given axis, propagates NaNs.
14651554
:obj:`dpnp.nanmin` : The minimum value of an array along a given axis, ignores NaNs.
1555+
:obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs.
1556+
:obj:`dpnp.max` : The maximum value of an array along a given axis, propagates NaNs.
1557+
:obj:`dpnp.nanmax` : The maximum value of an array along a given axis, ignores NaNs.
14661558
14671559
Examples
14681560
--------

0 commit comments

Comments
 (0)