From f2bbbf38bf6937071f05d3cc93f47d4cefa614d1 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 23 Jul 2025 06:07:23 -0700 Subject: [PATCH 1/3] update dpnp.size to accept tuple of ints for axes --- dpnp/dpnp_iface_manipulation.py | 24 +++++++++++++----------- dpnp/tests/test_manipulation.py | 8 ++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 2806f621b5c6..725cae779eda 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -46,7 +46,11 @@ import dpctl import dpctl.tensor as dpt import numpy -from dpctl.tensor._numpy_helper import AxisError, normalize_axis_index +from dpctl.tensor._numpy_helper import ( + AxisError, + normalize_axis_index, + normalize_axis_tuple, +) import dpnp @@ -3528,8 +3532,8 @@ def size(a, axis=None): ---------- a : array_like Input data. - axis : {None, int}, optional - Axis along which the elements are counted. + axis : {None, int, tuple of ints}, optional + Axis or axes along which the elements are counted. By default, give the total number of elements. Default: ``None``. @@ -3551,23 +3555,21 @@ def size(a, axis=None): >>> a = [[1, 2, 3], [4, 5, 6]] >>> np.size(a) 6 - >>> np.size(a, 1) + >>> np.size(a, axis=1) 3 - >>> np.size(a, 0) + >>> np.size(a, axis=0) 2 - - >>> a = np.asarray(a) - >>> np.size(a) + >>> np.size(a, axis=(0, 1)) 6 - >>> np.size(a, 1) - 3 """ if dpnp.is_supported_array_type(a): if axis is None: return a.size - return a.shape[axis] + _shape = a.shape + _axis = normalize_axis_tuple(axis, a.ndim) + return math.prod(_shape[ax] for ax in _axis) return numpy.size(a, axis) diff --git a/dpnp/tests/test_manipulation.py b/dpnp/tests/test_manipulation.py index 5fc3d7df8c5f..af59d9d4a7d1 100644 --- a/dpnp/tests/test_manipulation.py +++ b/dpnp/tests/test_manipulation.py @@ -74,6 +74,8 @@ def test_ndim(): assert dpnp.ndim(ia) == exp +# TODO: include commented code in the test when numpy-2.4 is released +# @testing.with_requires("numpy>=2.4") def test_size(): a = [[1, 2, 3], [4, 5, 6]] ia = dpnp.array(a) @@ -87,6 +89,12 @@ def test_size(): assert dpnp.size(a, 0) == exp assert dpnp.size(ia, 0) == exp + assert dpnp.size(ia, 1) == numpy.size(a, 1) + assert dpnp.size(ia, ()) == 1 # numpy.size(a, ()) + assert dpnp.size(ia, (0,)) == 2 # numpy.size(a, (0,)) + assert dpnp.size(ia, (1,)) == 3 # numpy.size(a, (1,)) + assert dpnp.size(ia, (0, 1)) == 6 # numpy.size(a, (0, 1)) + class TestAppend: @pytest.mark.parametrize( From 4c232d03213f5c81002d9b06c7d0af5e3a138105 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 23 Jul 2025 16:37:45 -0700 Subject: [PATCH 2/3] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8d1fd619e8..b3f7c28ef17e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Removed the use of class template argument deduction for alias template to conform to the C++17 standard [#2517](https://github.com/IntelPython/dpnp/pull/2517) * Changed th order of individual FFTs over `axes` for `dpnp.fft.irfftn` to be in forward order [#2524](https://github.com/IntelPython/dpnp/pull/2524) * Replaced the use of `numpy.testing.suppress_warnings` with appropriate calls from the warnings module [#2529](https://github.com/IntelPython/dpnp/pull/2529) +* Updated `dpnp.size` to accept tuple of ints for `axes` argument [#2536](https://github.com/IntelPython/dpnp/pull/2536) ### Deprecated From bed493ad381359f9122fd7bc750bba993d358a50 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Thu, 24 Jul 2025 06:44:27 -0700 Subject: [PATCH 3/3] add a separate test_size_tuple --- dpnp/tests/test_manipulation.py | 40 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/dpnp/tests/test_manipulation.py b/dpnp/tests/test_manipulation.py index af59d9d4a7d1..68e8d15f24d5 100644 --- a/dpnp/tests/test_manipulation.py +++ b/dpnp/tests/test_manipulation.py @@ -74,26 +74,32 @@ def test_ndim(): assert dpnp.ndim(ia) == exp -# TODO: include commented code in the test when numpy-2.4 is released -# @testing.with_requires("numpy>=2.4") -def test_size(): - a = [[1, 2, 3], [4, 5, 6]] - ia = dpnp.array(a) +class TestSize: + def test_size(self): + a = [[1, 2, 3], [4, 5, 6]] + ia = dpnp.array(a) - exp = numpy.size(a) - assert ia.size == exp - assert dpnp.size(a) == exp - assert dpnp.size(ia) == exp + exp = numpy.size(a) + assert ia.size == exp + assert dpnp.size(a) == exp + assert dpnp.size(ia) == exp - exp = numpy.size(a, 0) - assert dpnp.size(a, 0) == exp - assert dpnp.size(ia, 0) == exp + exp = numpy.size(a, 0) + assert dpnp.size(a, 0) == exp + assert dpnp.size(ia, 0) == exp + + assert dpnp.size(ia, 1) == numpy.size(a, 1) + + # TODO: include commented code in the test when numpy-2.4 is released + # @testing.with_requires("numpy>=2.4") + def test_size_tuple(self): + a = [[1, 2, 3], [4, 5, 6]] + ia = dpnp.array(a) - assert dpnp.size(ia, 1) == numpy.size(a, 1) - assert dpnp.size(ia, ()) == 1 # numpy.size(a, ()) - assert dpnp.size(ia, (0,)) == 2 # numpy.size(a, (0,)) - assert dpnp.size(ia, (1,)) == 3 # numpy.size(a, (1,)) - assert dpnp.size(ia, (0, 1)) == 6 # numpy.size(a, (0, 1)) + assert dpnp.size(ia, ()) == 1 # numpy.size(a, ()) + assert dpnp.size(ia, (0,)) == 2 # numpy.size(a, (0,)) + assert dpnp.size(ia, (1,)) == 3 # numpy.size(a, (1,)) + assert dpnp.size(ia, (0, 1)) == 6 # numpy.size(a, (0, 1)) class TestAppend: