Skip to content

Commit

Permalink
address comments - second round
Browse files Browse the repository at this point in the history
  • Loading branch information
vtavana committed Oct 30, 2023
1 parent 0195522 commit 45ee8e3
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 182 deletions.
1 change: 1 addition & 0 deletions dpnp/dpnp_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ def full(
):
"""Validate input parameters before passing them into `dpctl.tensor` module"""
dpu.validate_usm_type(usm_type, allow_none=True)

sycl_queue_normalized = dpnp.get_normalized_queue_device(
fill_value, sycl_queue=sycl_queue, device=device
)
Expand Down
109 changes: 40 additions & 69 deletions dpnp/dpnp_iface_arraycreation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# cython: language_level=3
# distutils: language = c++
# -*- coding: utf-8 -*-
# *****************************************************************************
# Copyright (c) 2016-2023, Intel Corporation
Expand Down Expand Up @@ -575,7 +573,7 @@ def copy(a, order="K", subok=False):
return array(a, order=order, subok=subok, copy=True)


def diag(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
def diag(v, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
"""
Extract a diagonal or construct a diagonal array.
Expand All @@ -588,9 +586,8 @@ def diag(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
Limitations
-----------
Parameter `x1` is supported as :class:`dpnp.dpnp_array` or :class:`dpctl.tensor.usm_ndarray`.
Parameter `k` is only supported as integer data type.
Otherwise the function will be executed sequentially on CPU.
Otherwise ``TypeError`` exception will be raised.
See Also
--------
Expand Down Expand Up @@ -623,56 +620,44 @@ def diag(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
"""

if not isinstance(x1, (dpnp.ndarray, dpt.usm_ndarray)):
pass
elif not isinstance(k, int):
pass
if not isinstance(k, int):
raise TypeError("An integer is required, but got {}".format(type(k)))
else:
_usm_type = x1.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
x1, sycl_queue=sycl_queue, device=device
)
x1 = (
x1.to_device(_sycl_queue.sycl_device)
if x1.sycl_queue != _sycl_queue
else x1
v = dpnp.asarray(
v, device=device, usm_type=usm_type, sycl_queue=sycl_queue
)

init0 = max(0, -k)
init1 = max(0, k)
if x1.ndim == 1:
size = x1.shape[0] + abs(k)
if v.ndim == 1:
size = v.shape[0] + abs(k)
m = dpnp.zeros(
(size, size),
dtype=x1.dtype,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
dtype=v.dtype,
usm_type=v.usm_type,
sycl_queue=v.sycl_queue,
)
for i in range(x1.shape[0]):
m[(init0 + i), init1 + i] = x1[i]
for i in range(v.shape[0]):
m[(init0 + i), init1 + i] = v[i]
return m
elif x1.ndim == 2:
size = min(
x1.shape[0], x1.shape[0] + k, x1.shape[1], x1.shape[1] - k
)
elif v.ndim == 2:
size = min(v.shape[0], v.shape[0] + k, v.shape[1], v.shape[1] - k)
if size < 0:
size = 0
m = dpnp.zeros(
(size,),
dtype=x1.dtype,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
dtype=v.dtype,
usm_type=v.usm_type,
sycl_queue=v.sycl_queue,
)
for i in range(size):
m[i] = x1[(init0 + i), init1 + i]
m[i] = v[(init0 + i), init1 + i]
return m
else:
raise ValueError("Input must be a 1-D or 2-D array.")

return call_origin(numpy.diag, x1, k)


def diagflat(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
def diagflat(v, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
"""
Create a two-dimensional array with the flattened input as a diagonal.
Expand All @@ -691,9 +676,8 @@ def diagflat(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
Limitations
-----------
Parameter `x1` is supported as :class:`dpnp.dpnp_array` or :class:`dpctl.tensor.usm_ndarray`.
Parameter `k` is only supported as integer data type.
Otherwise the function will be executed sequentially on CPU.
Otherwise ``TypeError`` exception will be raised.
Examples
--------
Expand All @@ -713,19 +697,15 @@ def diagflat(x1, /, k=0, *, device=None, usm_type=None, sycl_queue=None):
[0, 0, 0, 0, 0]])
"""
if not isinstance(x1, (dpnp.ndarray, dpt.usm_ndarray)):
pass
elif not isinstance(k, int):
pass

if not isinstance(k, int):
raise TypeError("An integer is required, but got {}".format(type(k)))
else:
_usm_type = x1.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
x1, sycl_queue=sycl_queue, device=device
v = dpnp.asarray(
v, device=device, usm_type=usm_type, sycl_queue=sycl_queue
)
v = dpnp.ravel(x1)
return dpnp.diag(v, k, usm_type=_usm_type, sycl_queue=_sycl_queue)

return call_origin(numpy.diagflat, x1, k)
v = dpnp.ravel(v)
return dpnp.diag(v, k, usm_type=v.usm_type, sycl_queue=v.sycl_queue)


def empty(
Expand Down Expand Up @@ -1024,6 +1004,7 @@ def full(
[10, 10, 10, 10]
"""

if like is not None:
pass
elif order not in ("C", "c", "F", "f", None):
Expand Down Expand Up @@ -1824,8 +1805,8 @@ def vander(
Limitations
-----------
Parameter `x1` is supported as :class:`dpnp.dpnp_array` or :class:`dpctl.tensor.usm_ndarray`.
Otherwise the function will be executed sequentially on CPU.
Parameter `N`, if it is not ``None``, is only supported as integer data type.
Otherwise ``TypeError`` exception will be raised.
Examples
--------
Expand All @@ -1852,44 +1833,34 @@ def vander(
[ 1, 5, 25, 125]])
"""

if not isinstance(x1, (dpnp.ndarray, dpt.usm_ndarray)):
pass
elif N is not None and not isinstance(N, int):
pass
x1 = dpnp.asarray(
x1, device=device, usm_type=usm_type, sycl_queue=sycl_queue
)

if N is not None and not isinstance(N, int):
raise TypeError("An integer is required, but got {}".format(type(N)))
elif x1.ndim != 1:
raise ValueError("x1 must be a one-dimensional array or sequence.")
else:
if N is None:
N = x1.size

_dtype = int if x1.dtype == bool else x1.dtype
_usm_type = x1.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
x1, sycl_queue=sycl_queue, device=device
)
x1 = (
x1.to_device(_sycl_queue.sycl_device)
if x1.sycl_queue != _sycl_queue
else x1
)

m = empty(
(x1.size, N),
dtype=_dtype,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
usm_type=x1.usm_type,
sycl_queue=x1.sycl_queue,
)
tmp = m[:, ::-1] if not increasing else m
dpnp.power(
x1.reshape(-1, 1),
dpnp.arange(N, dtype=_dtype, sycl_queue=_sycl_queue),
dpnp.arange(N, dtype=_dtype, sycl_queue=x1.sycl_queue),
out=tmp,
)

return m

return call_origin(numpy.vander, x1, N=N, increasing=increasing)


def zeros(
shape,
Expand Down
16 changes: 5 additions & 11 deletions dpnp/dpnp_iface_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ def ptp(
Limitations
-----------
Input array is supported as :class:`dpnp.dpnp_array` or :class:`dpctl.tensor.usm_ndarray`.
Otherwise the function will be executed sequentially on CPU.
Examples
--------
Expand All @@ -729,16 +728,11 @@ def ptp(
"""

if not isinstance(a, (dpnp.ndarray, dpt.usm_ndarray)):
pass
else:
return dpnp.subtract(
dpnp.max(a, axis=axis, keepdims=keepdims),
dpnp.min(a, axis=axis, keepdims=keepdims),
out=out,
)

return call_origin(numpy.ptp, a, axis, out, keepdims)
return dpnp.subtract(
dpnp.max(a, axis=axis, keepdims=keepdims, out=out),
dpnp.min(a, axis=axis, keepdims=keepdims),
out=out,
)


def nanvar(x1, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
Expand Down
5 changes: 0 additions & 5 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,6 @@ tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_ones_like_s
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_like_subok
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_strides

tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_list
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_tuple
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_list
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_tuple

tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid0
tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid1
tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid2
Expand Down
5 changes: 0 additions & 5 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,6 @@ tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes
tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes_param_3_{order='C', shape=(2, 3)}::test_item
tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes_param_4_{order='F', shape=(2, 3)}::test_item

tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_list
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_tuple
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_list
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_tuple

tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_4_{shape=(3, 3), val=(2,), wrap=True}::test_1darray
tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_4_{shape=(3, 3), val=(2,), wrap=True}::test_fill_diagonal
tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_5_{shape=(3, 3), val=(2,), wrap=False}::test_1darray
Expand Down
47 changes: 28 additions & 19 deletions tests/test_arraycreation.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,41 +117,40 @@ def test_arange(start, stop, step, dtype):
"[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]",
],
)
def test_diag(v, k):
def test_diag_diagflat(v, k):
a = numpy.array(v)
ia = dpnp.array(a)
expected = numpy.diag(a, k)
result = dpnp.diag(ia, k)
assert_array_equal(expected, result)

expected = numpy.diagflat(a, k)
result = dpnp.diagflat(ia, k)
assert_array_equal(expected, result)


@pytest.mark.parametrize(
"axis",
[None, 0, 1],
ids=["None", "0", "1"],
)
@pytest.mark.parametrize(
"v",
"seq",
[
[[0, 0], [0, 0]],
[[1, 2], [1, 2]],
[[1, 2], [3, 4]],
[0, 1, 2, 3, 4],
(0, 1, 2, 3, 4),
[[0, 1, 2], [3, 4, 5], [6, 7, 8]],
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]],
],
ids=[
"[[0, 0], [0, 0]]",
"[[1, 2], [1, 2]]",
"[[1, 2], [3, 4]]",
"[0, 1, 2, 3, 4]",
"(0, 1, 2, 3, 4)",
"[[0, 1, 2], [3, 4, 5], [6, 7, 8]]",
"[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]",
],
)
def test_ptp(v, axis):
a = numpy.array(v)
ia = dpnp.array(a)
expected = numpy.ptp(a, axis)
result = dpnp.ptp(ia, axis)
def test_diag_diagflat_seq(seq):
expected = numpy.diag(seq)
result = dpnp.diag(seq)
assert_array_equal(expected, result)

expected = numpy.diagflat(seq)
result = dpnp.diagflat(seq)
assert_array_equal(expected, result)


Expand Down Expand Up @@ -479,7 +478,7 @@ def test_triu_size_null(k):
def test_vander(array, dtype, n, increase):
if dtype in [dpnp.complex64, dpnp.complex128] and array == [0, 3, 5]:
pytest.skip(
"dpnp.power(dpnp.array(complex(0,0)), dpnp.array(0)) returns nan+nanj while it should be 1+0j"
"per array API dpnp.power(complex(0,0)), 0) returns nan+nanj while NumPy returns 1+0j"
)
vander_func = lambda xp, x: xp.vander(x, N=n, increasing=increase)

Expand All @@ -489,6 +488,16 @@ def test_vander(array, dtype, n, increase):
assert_allclose(vander_func(numpy, a_np), vander_func(dpnp, a_dpnp))


@pytest.mark.parametrize(
"sequence",
[[1, 2, 3, 4], (1, 2, 3, 4)],
ids=["[1, 2, 3, 4]", "(1, 2, 3, 4)"],
)
def test_vander_seq(sequence):
vander_func = lambda xp, x: xp.vander(x)
assert_allclose(vander_func(numpy, sequence), vander_func(dpnp, sequence))


@pytest.mark.parametrize(
"shape",
[(), 0, (0,), (2, 0, 3), (3, 2)],
Expand Down
Loading

0 comments on commit 45ee8e3

Please sign in to comment.