Skip to content

Commit b2bf967

Browse files
authored
Merge 489625e into 636ac00
2 parents 636ac00 + 489625e commit b2bf967

File tree

3 files changed

+93
-89
lines changed

3 files changed

+93
-89
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ In addition, this release completes implementation of `dpnp.fft` module and adds
9797
* Extended `dpnp.heaviside` to support `order` and `out` keyword arguments by writing dedicated kernel for it [#2008](https://github.com/IntelPython/dpnp/pull/2008)
9898
* `dpnp` uses pybind11 2.13.5 [#2010](https://github.com/IntelPython/dpnp/pull/2010)
9999
* Add `COMPILER_VERSION_2025_OR_LATER` flag to be able to run `dpnp.fft` module with both 2024.2 and 2025.0 versions of the compiler [#2025](https://github.com/IntelPython/dpnp/pull/2025)
100+
* Cleaned up an implementation of `dpnp.gradient` by removing obsolete TODO which is not going to be done [#2032](https://github.com/IntelPython/dpnp/pull/2032)
101+
* Updated `Array Manipulation Routines` page in documentation to add missing functions and to remove duplicate entries [#2033](https://github.com/IntelPython/dpnp/pull/2033)
100102

101103
### Fixed
102104

103105
* Resolved an issue with `dpnp.matmul` when an f_contiguous `out` keyword is passed to the the function [#1872](https://github.com/IntelPython/dpnp/pull/1872)
104106
* Resolved a possible race condition in `dpnp.inv` [#1940](https://github.com/IntelPython/dpnp/pull/1940)
107+
* Resolved an issue with failing tests for `dpnp.append` when running on a device without fp64 support [#2034](https://github.com/IntelPython/dpnp/pull/2034)
108+
105109

106110
## [0.15.0] - 05/25/2024
107111

dpnp/dpnp_iface_manipulation.py

Lines changed: 88 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def append(arr, values, axis=None):
297297
out : dpnp.ndarray
298298
A copy of `arr` with `values` appended to `axis`. Note that
299299
`append` does not occur in-place: a new array is allocated and
300-
filled. If `axis` is None, `out` is a flattened array.
300+
filled. If `axis` is ``None``, `out` is a flattened array.
301301
302302
See Also
303303
--------
@@ -342,6 +342,89 @@ def append(arr, values, axis=None):
342342
return dpnp.concatenate((arr, values), axis=axis)
343343

344344

345+
def array_split(ary, indices_or_sections, axis=0):
346+
"""
347+
Split an array into multiple sub-arrays.
348+
349+
Please refer to the :obj:`dpnp.split` documentation. The only difference
350+
between these functions is that ``dpnp.array_split`` allows
351+
`indices_or_sections` to be an integer that does *not* equally divide the
352+
axis. For an array of length l that should be split into n sections, it
353+
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
354+
``l//n``.
355+
356+
For full documentation refer to :obj:`numpy.array_split`.
357+
358+
Parameters
359+
----------
360+
ary : {dpnp.ndarray, usm_ndarray}
361+
Array to be divided into sub-arrays.
362+
indices_or_sections : {int, sequence of ints}
363+
If `indices_or_sections` is an integer, N, and array length is l, it
364+
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
365+
``l//n``.
366+
367+
If `indices_or_sections` is a sequence of sorted integers, the entries
368+
indicate where along `axis` the array is split.
369+
axis : int, optional
370+
The axis along which to split.
371+
Default: ``0``.
372+
373+
Returns
374+
-------
375+
sub-arrays : list of dpnp.ndarray
376+
A list of sub arrays. Each array is a view of the corresponding input
377+
array.
378+
379+
See Also
380+
--------
381+
:obj:`dpnp.split` : Split array into multiple sub-arrays of equal size.
382+
383+
Examples
384+
--------
385+
>>> import dpnp as np
386+
>>> x = np.arange(8.0)
387+
>>> np.array_split(x, 3)
388+
[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])]
389+
390+
>>> x = np.arange(9)
391+
>>> np.array_split(x, 4)
392+
[array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]
393+
394+
"""
395+
396+
dpnp.check_supported_arrays_type(ary)
397+
n_tot = ary.shape[axis]
398+
try:
399+
# handle array case.
400+
n_sec = len(indices_or_sections) + 1
401+
div_points = [0] + list(indices_or_sections) + [n_tot]
402+
except TypeError:
403+
# indices_or_sections is a scalar, not an array.
404+
n_sec = int(indices_or_sections)
405+
if n_sec <= 0:
406+
raise ValueError("number sections must be larger than 0.") from None
407+
n_each_sec, extras = numpy.divmod(n_tot, n_sec)
408+
section_sizes = (
409+
[0] + extras * [n_each_sec + 1] + (n_sec - extras) * [n_each_sec]
410+
)
411+
div_points = dpnp.array(
412+
section_sizes,
413+
dtype=dpnp.intp,
414+
usm_type=ary.usm_type,
415+
sycl_queue=ary.sycl_queue,
416+
).cumsum()
417+
418+
sub_arys = []
419+
sary = dpnp.swapaxes(ary, axis, 0)
420+
for i in range(n_sec):
421+
st = div_points[i]
422+
end = div_points[i + 1]
423+
sub_arys.append(dpnp.swapaxes(sary[st:end], axis, 0))
424+
425+
return sub_arys
426+
427+
345428
def asarray_chkfinite(
346429
a, dtype=None, order=None, *, device=None, usm_type=None, sycl_queue=None
347430
):
@@ -356,12 +439,12 @@ def asarray_chkfinite(
356439
Input data, in any form that can be converted to an array. This
357440
includes lists, lists of tuples, tuples, tuples of tuples, tuples
358441
of lists and ndarrays. Success requires no NaNs or Infs.
359-
dtype : str or dtype object, optional
442+
dtype : {None, str, dtype object}, optional
360443
By default, the data-type is inferred from the input data.
361-
default: ``None``.
362-
order : {"C", "F", "A", "K"}, optional
444+
Default: ``None``.
445+
order : {None, "C", "F", "A", "K"}, optional
363446
Memory layout of the newly output array.
364-
Default: "K".
447+
Default: ``"K"``.
365448
device : {None, string, SyclDevice, SyclQueue}, optional
366449
An array API concept of device where the output array is created.
367450
The `device` can be ``None`` (the default), an OneAPI filter selector
@@ -452,89 +535,6 @@ def asarray_chkfinite(
452535
return a
453536

454537

455-
def array_split(ary, indices_or_sections, axis=0):
456-
"""
457-
Split an array into multiple sub-arrays.
458-
459-
Please refer to the :obj:`dpnp.split` documentation. The only difference
460-
between these functions is that ``dpnp.array_split`` allows
461-
`indices_or_sections` to be an integer that does *not* equally divide the
462-
axis. For an array of length l that should be split into n sections, it
463-
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
464-
``l//n``.
465-
466-
For full documentation refer to :obj:`numpy.array_split`.
467-
468-
Parameters
469-
----------
470-
ary : {dpnp.ndarray, usm_ndarray}
471-
Array to be divided into sub-arrays.
472-
indices_or_sections : {int, sequence of ints}
473-
If `indices_or_sections` is an integer, N, and array length is l, it
474-
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
475-
``l//n``.
476-
477-
If `indices_or_sections` is a sequence of sorted integers, the entries
478-
indicate where along `axis` the array is split.
479-
axis : int, optional
480-
The axis along which to split.
481-
Default: ``0``.
482-
483-
Returns
484-
-------
485-
sub-arrays : list of dpnp.ndarray
486-
A list of sub arrays. Each array is a view of the corresponding input
487-
array.
488-
489-
See Also
490-
--------
491-
:obj:`dpnp.split` : Split array into multiple sub-arrays of equal size.
492-
493-
Examples
494-
--------
495-
>>> import dpnp as np
496-
>>> x = np.arange(8.0)
497-
>>> np.array_split(x, 3)
498-
[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])]
499-
500-
>>> x = np.arange(9)
501-
>>> np.array_split(x, 4)
502-
[array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]
503-
504-
"""
505-
506-
dpnp.check_supported_arrays_type(ary)
507-
n_tot = ary.shape[axis]
508-
try:
509-
# handle array case.
510-
n_sec = len(indices_or_sections) + 1
511-
div_points = [0] + list(indices_or_sections) + [n_tot]
512-
except TypeError:
513-
# indices_or_sections is a scalar, not an array.
514-
n_sec = int(indices_or_sections)
515-
if n_sec <= 0:
516-
raise ValueError("number sections must be larger than 0.") from None
517-
n_each_sec, extras = numpy.divmod(n_tot, n_sec)
518-
section_sizes = (
519-
[0] + extras * [n_each_sec + 1] + (n_sec - extras) * [n_each_sec]
520-
)
521-
div_points = dpnp.array(
522-
section_sizes,
523-
dtype=dpnp.intp,
524-
usm_type=ary.usm_type,
525-
sycl_queue=ary.sycl_queue,
526-
).cumsum()
527-
528-
sub_arys = []
529-
sary = dpnp.swapaxes(ary, axis, 0)
530-
for i in range(n_sec):
531-
st = div_points[i]
532-
end = div_points[i + 1]
533-
sub_arys.append(dpnp.swapaxes(sary[st:end], axis, 0))
534-
535-
return sub_arys
536-
537-
538538
def asfarray(a, dtype=None, *, device=None, usm_type=None, sycl_queue=None):
539539
"""
540540
Return an array converted to a float type.

tests/third_party/cupy/manipulation_tests/test_add_remove.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class TestAppend(unittest.TestCase):
6363
@testing.for_all_dtypes_combination(
6464
names=["dtype1", "dtype2"], no_bool=True
6565
)
66-
@testing.numpy_cupy_array_equal()
66+
@testing.numpy_cupy_array_equal(type_check=has_support_aspect64())
6767
def test(self, xp, dtype1, dtype2):
6868
a = testing.shaped_random((3, 4, 5), xp, dtype1)
6969
b = testing.shaped_random((6, 7), xp, dtype2)

0 commit comments

Comments
 (0)