Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dpnp.linalg.vector_norm raises exception for zero sized input array #2319

Closed
antonwolfy opened this issue Feb 17, 2025 · 2 comments · Fixed by #2371
Closed

dpnp.linalg.vector_norm raises exception for zero sized input array #2319

antonwolfy opened this issue Feb 17, 2025 · 2 comments · Fixed by #2371
Assignees

Comments

@antonwolfy
Copy link
Contributor

The example below with dpnp.linalg.vector_norm triggers ValueError exception:

import dpnp

dpnp.__version__
# Out: '0.17.0dev6+25.g1ee8e197e0c'

x = dpnp.zeros(0)
dpnp.linalg.norm(x, ord=dpnp.inf)  # the same with ord=-dpnp.inf
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 np.linalg.norm(x, ord=np.inf)

File ~/code/dpnp/dpnp/linalg/dpnp_iface_linalg.py:1419, in norm(x, ord, axis, keepdims)
   1266 r"""
   1267 Matrix or vector norm.
   1268
   (...)
   1415
   1416 """
   1418 dpnp.check_supported_arrays_type(x)
-> 1419 return dpnp_norm(x, ord, axis, keepdims)

File ~/code/dpnp/dpnp/linalg/dpnp_utils_linalg.py:2403, in dpnp_norm(x, ord, axis, keepdims)
   2401 if len(axis) == 1:
   2402     axis = normalize_axis_index(axis[0], ndim)
-> 2403     return _norm_int_axis(x, ord, axis, keepdims)
   2405 if len(axis) == 2:
   2406     row_axis, col_axis = axis

File ~/code/dpnp/dpnp/linalg/dpnp_utils_linalg.py:1186, in _norm_int_axis(x, ord, axis, keepdims)
   1178 """
   1179 _norm_int_axis(x, ord, axis, keepdims)
   1180
   1181 Compute matrix or vector norm of `x` along integer `axis`.
   1182
   1183 """
   1185 if ord == dpnp.inf:
-> 1186     return dpnp.abs(x).max(axis=axis, keepdims=keepdims)
   1187 if ord == -dpnp.inf:
   1188     return dpnp.abs(x).min(axis=axis, keepdims=keepdims)

File ~/code/dpnp/dpnp/dpnp_array.py:1272, in dpnp_array.max(self, axis, out, keepdims, initial, where)
   1257 def max(
   1258     self,
   1259     axis=None,
   (...)
   1263     where=True,
   1264 ):
   1265     """
   1266     Return the maximum along an axis.
   1267
   1268     Refer to :obj:`dpnp.max` for full documentation.
   1269
   1270     """
-> 1272     return dpnp.max(
   1273         self,
   1274         axis=axis,
   1275         out=out,
   1276         keepdims=keepdims,
   1277         initial=initial,
   1278         where=where,
   1279     )

File ~/code/dpnp/dpnp/dpnp_iface_statistics.py:999, in max(a, axis, out, keepdims, initial, where)
    996 dpnp.check_limitations(initial=initial, where=where)
    997 usm_a = dpnp.get_usm_ndarray(a)
--> 999 return dpnp_wrap_reduction_call(
   1000     usm_a,
   1001     out,
   1002     dpt.max,
   1003     a.dtype,
   1004     axis=axis,
   1005     keepdims=keepdims,
   1006 )

File ~/code/dpnp/dpnp/dpnp_utils/dpnp_utils_reduction.py:48, in dpnp_wrap_reduction_call(usm_a, out, _reduction_fn, res_dt, **kwargs)
     45     usm_out = dpnp.get_usm_ndarray(out)
     47 kwargs["out"] = usm_out
---> 48 res_usm = _reduction_fn(usm_a, **kwargs)
     49 return dpnp.get_result_array(res_usm, input_out, casting="unsafe")

File ~/miniforge3/envs/dpnp_dev/lib/python3.12/site-packages/dpctl/tensor/_reduction.py:569, in max(x, axis, keepdims, out)
    539 def max(x, /, *, axis=None, keepdims=False, out=None):
    540     """
    541     Calculates the maximum value of the input array ``x``.
    542
   (...)
    567             array has the same data type as ``x``.
    568     """
--> 569     return _comparison_over_axis(x, axis, keepdims, out, tri._max_over_axis)

File ~/miniforge3/envs/dpnp_dev/lib/python3.12/site-packages/dpctl/tensor/_reduction.py:458, in _comparison_over_axis(x, axis, keepdims, out, _reduction_fn)
    456 red_nd = len(axis)
    457 if any([x_tmp.shape[i] == 0 for i in range(-red_nd, 0)]):
--> 458     raise ValueError("reduction cannot be performed over zero-size axes")
    459 res_shape = x_tmp.shape[: nd - red_nd]
    460 exec_q = x.sycl_queue

ValueError: reduction cannot be performed over zero-size axes
@vtavana
Copy link
Collaborator

vtavana commented Feb 18, 2025

NumPy raises a similar Error, what is the use case that you encountered it?

>>> import numpy
>>> numpy.linalg.norm(numpy.zeros(0), ord=numpy.inf)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 numpy.linalg.norm(numpy.zeros(0), ord=numpy.inf)

File /localdisk/work/vtavana/miniforge/envs/dpnp_2025/lib/python3.12/site-packages/numpy/linalg/_linalg.py:2765, in norm(x, ord, axis, keepdims)
   2763 if len(axis) == 1:
   2764     if ord == inf:
-> 2765         return abs(x).max(axis=axis, keepdims=keepdims)
   2766     elif ord == -inf:
   2767         return abs(x).min(axis=axis, keepdims=keepdims)

File /localdisk/work/vtavana/miniforge/envs/dpnp_2025/lib/python3.12/site-packages/numpy/_core/_methods.py:44, in _amax(a, axis, out, keepdims, initial, where)
     42 def _amax(a, axis=None, out=None, keepdims=False,
     43           initial=_NoValue, where=True):
---> 44     return umr_maximum(a, axis, None, out, keepdims, initial, where)

ValueError: zero-size array to reduction operation maximum which has no identity

@antonwolfy
Copy link
Contributor Author

antonwolfy commented Feb 18, 2025

NumPy is going to resolve that in numpy#28343

@vtavana vtavana mentioned this issue Mar 17, 2025
7 tasks
vtavana added a commit that referenced this issue Mar 20, 2025
resolves #2319

The vector norms `ord={None, 1, 2, inf}` and the matrix norms
`ord={None, 1, 2, inf, "fro", "nuc"}` now consistently return zero for
empty arrays, which are arrays with at least one axis of size zero. This
change affects `dpnp.linalg.norm`, `dpnp.linalg.vector_norm`, and
`dpnp.linalg.matrix_norm`. Previously, dpnp would either raise errors or
return zero depending on the parameters provided
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants