Skip to content

Commit

Permalink
Merge 489625e into 636ac00
Browse files Browse the repository at this point in the history
  • Loading branch information
antonwolfy authored Sep 14, 2024
2 parents 636ac00 + 489625e commit b2bf967
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 89 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ In addition, this release completes implementation of `dpnp.fft` module and adds
* Extended `dpnp.heaviside` to support `order` and `out` keyword arguments by writing dedicated kernel for it [#2008](https://github.com/IntelPython/dpnp/pull/2008)
* `dpnp` uses pybind11 2.13.5 [#2010](https://github.com/IntelPython/dpnp/pull/2010)
* 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)
* 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)
* Updated `Array Manipulation Routines` page in documentation to add missing functions and to remove duplicate entries [#2033](https://github.com/IntelPython/dpnp/pull/2033)

### Fixed

* 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)
* Resolved a possible race condition in `dpnp.inv` [#1940](https://github.com/IntelPython/dpnp/pull/1940)
* 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)


## [0.15.0] - 05/25/2024

Expand Down
176 changes: 88 additions & 88 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def append(arr, values, axis=None):
out : dpnp.ndarray
A copy of `arr` with `values` appended to `axis`. Note that
`append` does not occur in-place: a new array is allocated and
filled. If `axis` is None, `out` is a flattened array.
filled. If `axis` is ``None``, `out` is a flattened array.
See Also
--------
Expand Down Expand Up @@ -342,6 +342,89 @@ def append(arr, values, axis=None):
return dpnp.concatenate((arr, values), axis=axis)


def array_split(ary, indices_or_sections, axis=0):
"""
Split an array into multiple sub-arrays.
Please refer to the :obj:`dpnp.split` documentation. The only difference
between these functions is that ``dpnp.array_split`` allows
`indices_or_sections` to be an integer that does *not* equally divide the
axis. For an array of length l that should be split into n sections, it
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
``l//n``.
For full documentation refer to :obj:`numpy.array_split`.
Parameters
----------
ary : {dpnp.ndarray, usm_ndarray}
Array to be divided into sub-arrays.
indices_or_sections : {int, sequence of ints}
If `indices_or_sections` is an integer, N, and array length is l, it
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
``l//n``.
If `indices_or_sections` is a sequence of sorted integers, the entries
indicate where along `axis` the array is split.
axis : int, optional
The axis along which to split.
Default: ``0``.
Returns
-------
sub-arrays : list of dpnp.ndarray
A list of sub arrays. Each array is a view of the corresponding input
array.
See Also
--------
:obj:`dpnp.split` : Split array into multiple sub-arrays of equal size.
Examples
--------
>>> import dpnp as np
>>> x = np.arange(8.0)
>>> np.array_split(x, 3)
[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])]
>>> x = np.arange(9)
>>> np.array_split(x, 4)
[array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]
"""

dpnp.check_supported_arrays_type(ary)
n_tot = ary.shape[axis]
try:
# handle array case.
n_sec = len(indices_or_sections) + 1
div_points = [0] + list(indices_or_sections) + [n_tot]
except TypeError:
# indices_or_sections is a scalar, not an array.
n_sec = int(indices_or_sections)
if n_sec <= 0:
raise ValueError("number sections must be larger than 0.") from None
n_each_sec, extras = numpy.divmod(n_tot, n_sec)
section_sizes = (
[0] + extras * [n_each_sec + 1] + (n_sec - extras) * [n_each_sec]
)
div_points = dpnp.array(
section_sizes,
dtype=dpnp.intp,
usm_type=ary.usm_type,
sycl_queue=ary.sycl_queue,
).cumsum()

sub_arys = []
sary = dpnp.swapaxes(ary, axis, 0)
for i in range(n_sec):
st = div_points[i]
end = div_points[i + 1]
sub_arys.append(dpnp.swapaxes(sary[st:end], axis, 0))

return sub_arys


def asarray_chkfinite(
a, dtype=None, order=None, *, device=None, usm_type=None, sycl_queue=None
):
Expand All @@ -356,12 +439,12 @@ def asarray_chkfinite(
Input data, in any form that can be converted to an array. This
includes lists, lists of tuples, tuples, tuples of tuples, tuples
of lists and ndarrays. Success requires no NaNs or Infs.
dtype : str or dtype object, optional
dtype : {None, str, dtype object}, optional
By default, the data-type is inferred from the input data.
default: ``None``.
order : {"C", "F", "A", "K"}, optional
Default: ``None``.
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: "K".
Default: ``"K"``.
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
Expand Down Expand Up @@ -452,89 +535,6 @@ def asarray_chkfinite(
return a


def array_split(ary, indices_or_sections, axis=0):
"""
Split an array into multiple sub-arrays.
Please refer to the :obj:`dpnp.split` documentation. The only difference
between these functions is that ``dpnp.array_split`` allows
`indices_or_sections` to be an integer that does *not* equally divide the
axis. For an array of length l that should be split into n sections, it
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
``l//n``.
For full documentation refer to :obj:`numpy.array_split`.
Parameters
----------
ary : {dpnp.ndarray, usm_ndarray}
Array to be divided into sub-arrays.
indices_or_sections : {int, sequence of ints}
If `indices_or_sections` is an integer, N, and array length is l, it
returns ``l % n`` sub-arrays of size ``l//n + 1`` and the rest of size
``l//n``.
If `indices_or_sections` is a sequence of sorted integers, the entries
indicate where along `axis` the array is split.
axis : int, optional
The axis along which to split.
Default: ``0``.
Returns
-------
sub-arrays : list of dpnp.ndarray
A list of sub arrays. Each array is a view of the corresponding input
array.
See Also
--------
:obj:`dpnp.split` : Split array into multiple sub-arrays of equal size.
Examples
--------
>>> import dpnp as np
>>> x = np.arange(8.0)
>>> np.array_split(x, 3)
[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])]
>>> x = np.arange(9)
>>> np.array_split(x, 4)
[array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]
"""

dpnp.check_supported_arrays_type(ary)
n_tot = ary.shape[axis]
try:
# handle array case.
n_sec = len(indices_or_sections) + 1
div_points = [0] + list(indices_or_sections) + [n_tot]
except TypeError:
# indices_or_sections is a scalar, not an array.
n_sec = int(indices_or_sections)
if n_sec <= 0:
raise ValueError("number sections must be larger than 0.") from None
n_each_sec, extras = numpy.divmod(n_tot, n_sec)
section_sizes = (
[0] + extras * [n_each_sec + 1] + (n_sec - extras) * [n_each_sec]
)
div_points = dpnp.array(
section_sizes,
dtype=dpnp.intp,
usm_type=ary.usm_type,
sycl_queue=ary.sycl_queue,
).cumsum()

sub_arys = []
sary = dpnp.swapaxes(ary, axis, 0)
for i in range(n_sec):
st = div_points[i]
end = div_points[i + 1]
sub_arys.append(dpnp.swapaxes(sary[st:end], axis, 0))

return sub_arys


def asfarray(a, dtype=None, *, device=None, usm_type=None, sycl_queue=None):
"""
Return an array converted to a float type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class TestAppend(unittest.TestCase):
@testing.for_all_dtypes_combination(
names=["dtype1", "dtype2"], no_bool=True
)
@testing.numpy_cupy_array_equal()
@testing.numpy_cupy_array_equal(type_check=has_support_aspect64())
def test(self, xp, dtype1, dtype2):
a = testing.shaped_random((3, 4, 5), xp, dtype1)
b = testing.shaped_random((6, 7), xp, dtype2)
Expand Down

0 comments on commit b2bf967

Please sign in to comment.