Skip to content

Commit 2b1ac6d

Browse files
committed
fix_issue-2319
1 parent 15b7644 commit 2b1ac6d

File tree

2 files changed

+83
-64
lines changed

2 files changed

+83
-64
lines changed

dpnp/linalg/dpnp_utils_linalg.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,10 +2401,17 @@ def dpnp_norm(x, ord=None, axis=None, keepdims=False):
24012401
axis = (axis,)
24022402

24032403
if len(axis) == 1:
2404+
if x.shape[axis[0]] == 0 and ord in [1, 2, dpnp.inf]:
2405+
x = dpnp.moveaxis(x, axis, -1)
2406+
return dpnp.zeros_like(x, shape=x.shape[:-1])
24042407
axis = normalize_axis_index(axis[0], ndim)
24052408
return _norm_int_axis(x, ord, axis, keepdims)
24062409

24072410
if len(axis) == 2:
2411+
flag = x.shape[axis[0]] == 0 or x.shape[axis[1]] == 0
2412+
if flag and ord in ["fro", "nuc", 1, 2, dpnp.inf]:
2413+
x = dpnp.moveaxis(x, axis, (-2, -1))
2414+
return dpnp.zeros_like(x, shape=x.shape[:-2])
24082415
row_axis, col_axis = axis
24092416
row_axis = normalize_axis_index(row_axis, ndim)
24102417
col_axis = normalize_axis_index(col_axis, ndim)

dpnp/tests/test_linalg.py

Lines changed: 76 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
assert_allclose,
99
assert_almost_equal,
1010
assert_array_equal,
11+
assert_equal,
1112
assert_raises,
1213
assert_raises_regex,
1314
suppress_warnings,
@@ -2087,29 +2088,29 @@ def setup_method(self):
20872088
def test_empty(self, shape, ord, axis, keepdims):
20882089
a = numpy.empty(shape)
20892090
ia = dpnp.array(a)
2091+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
2092+
20902093
if axis is None and a.ndim > 1 and ord in [0, 3]:
20912094
# Invalid norm order for matrices (a.ndim == 2) or
20922095
# Improper number of dimensions to norm (a.ndim>2)
2093-
with pytest.raises(ValueError):
2094-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2096+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2097+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
20952098
elif axis is None and a.ndim > 2 and ord is not None:
20962099
# Improper number of dimensions to norm
2097-
with pytest.raises(ValueError):
2098-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2100+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2101+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
20992102
elif (
21002103
axis is None
2101-
and ord is not None
2104+
and ord in [-2, -1, 0, 3]
21022105
and a.ndim != 1
21032106
and a.shape[-1] == 0
21042107
):
21052108
# reduction cannot be performed over zero-size axes
2106-
with pytest.raises(ValueError):
2107-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2109+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2110+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
21082111
else:
2109-
result = dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2110-
expected = numpy.linalg.norm(
2111-
a, ord=ord, axis=axis, keepdims=keepdims
2112-
)
2112+
result = dpnp.linalg.norm(ia, **kwarg)
2113+
expected = numpy.linalg.norm(a, **kwarg)
21132114
assert_dtype_allclose(result, expected)
21142115

21152116
@pytest.mark.parametrize(
@@ -2121,11 +2122,11 @@ def test_0D(self, ord, axis):
21212122
ia = dpnp.array(a)
21222123
if axis is None and ord is not None:
21232124
# Improper number of dimensions to norm
2124-
with pytest.raises(ValueError):
2125-
dpnp.linalg.norm(ia, ord=ord, axis=axis)
2125+
assert_raises(ValueError, dpnp.linalg.norm, ia, ord=ord, axis=axis)
2126+
assert_raises(ValueError, numpy.linalg.norm, a, ord=ord, axis=axis)
21262127
elif axis is not None:
2127-
with pytest.raises(AxisError):
2128-
dpnp.linalg.norm(ia, ord=ord, axis=axis)
2128+
assert_raises(IndexError, dpnp.linalg.norm, ia, ord=ord, axis=axis)
2129+
assert_raises(AxisError, numpy.linalg.norm, a, ord=ord, axis=axis)
21292130
else:
21302131
result = dpnp.linalg.norm(ia, ord=ord, axis=axis)
21312132
expected = numpy.linalg.norm(a, ord=ord, axis=axis)
@@ -2158,24 +2159,21 @@ def test_1D(self, dtype, ord, axis, keepdims):
21582159
def test_2D(self, dtype, ord, axis, keepdims):
21592160
a = generate_random_numpy_array((3, 5), dtype)
21602161
ia = dpnp.array(a)
2162+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
2163+
21612164
if (axis in [-1, 0, 1] and ord in ["nuc", "fro"]) or (
21622165
(isinstance(axis, tuple) or axis is None) and ord == 3
21632166
):
21642167
# Invalid norm order for vectors
2165-
with pytest.raises(ValueError):
2166-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2168+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2169+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
21672170
else:
2168-
result = dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2169-
expected = numpy.linalg.norm(
2170-
a, ord=ord, axis=axis, keepdims=keepdims
2171-
)
2171+
result = dpnp.linalg.norm(ia, **kwarg)
2172+
expected = numpy.linalg.norm(a, **kwarg)
21722173
assert_dtype_allclose(result, expected)
21732174

21742175
@pytest.mark.usefixtures("suppress_divide_numpy_warnings")
2175-
@pytest.mark.parametrize(
2176-
"dtype",
2177-
get_all_dtypes(no_none=True),
2178-
)
2176+
@pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True))
21792177
@pytest.mark.parametrize(
21802178
"ord", [None, -dpnp.inf, -2, -1, 1, 2, 3, dpnp.inf, "fro", "nuc"]
21812179
)
@@ -2188,21 +2186,21 @@ def test_2D(self, dtype, ord, axis, keepdims):
21882186
def test_ND(self, dtype, ord, axis, keepdims):
21892187
a = generate_random_numpy_array((2, 3, 4, 5), dtype)
21902188
ia = dpnp.array(a)
2189+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
2190+
21912191
if (axis in [-1, 0, 1] and ord in ["nuc", "fro"]) or (
21922192
isinstance(axis, tuple) and ord == 3
21932193
):
21942194
# Invalid norm order for vectors
2195-
with pytest.raises(ValueError):
2196-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2195+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2196+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
21972197
elif axis is None and ord is not None:
21982198
# Improper number of dimensions to norm
2199-
with pytest.raises(ValueError):
2200-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2199+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2200+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
22012201
else:
2202-
result = dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2203-
expected = numpy.linalg.norm(
2204-
a, ord=ord, axis=axis, keepdims=keepdims
2205-
)
2202+
result = dpnp.linalg.norm(ia, **kwarg)
2203+
expected = numpy.linalg.norm(a, **kwarg)
22062204
assert_dtype_allclose(result, expected)
22072205

22082206
@pytest.mark.usefixtures("suppress_divide_numpy_warnings")
@@ -2219,21 +2217,21 @@ def test_ND(self, dtype, ord, axis, keepdims):
22192217
def test_usm_ndarray(self, dtype, ord, axis, keepdims):
22202218
a = generate_random_numpy_array((2, 3, 4, 5), dtype)
22212219
ia = dpt.asarray(a)
2220+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
2221+
22222222
if (axis in [-1, 0, 1] and ord in ["nuc", "fro"]) or (
22232223
isinstance(axis, tuple) and ord == 3
22242224
):
22252225
# Invalid norm order for vectors
2226-
with pytest.raises(ValueError):
2227-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2226+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2227+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
22282228
elif axis is None and ord is not None:
22292229
# Improper number of dimensions to norm
2230-
with pytest.raises(ValueError):
2231-
dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2230+
assert_raises(ValueError, dpnp.linalg.norm, ia, **kwarg)
2231+
assert_raises(ValueError, numpy.linalg.norm, a, **kwarg)
22322232
else:
2233-
result = dpnp.linalg.norm(ia, ord=ord, axis=axis, keepdims=keepdims)
2234-
expected = numpy.linalg.norm(
2235-
a, ord=ord, axis=axis, keepdims=keepdims
2236-
)
2233+
result = dpnp.linalg.norm(ia, **kwarg)
2234+
expected = numpy.linalg.norm(a, **kwarg)
22372235
assert_dtype_allclose(result, expected)
22382236

22392237
@pytest.mark.parametrize("stride", [3, -1, -5])
@@ -2257,8 +2255,7 @@ def test_strided_2D(self, axis, stride):
22572255
A = numpy.random.rand(20, 30)
22582256
B = dpnp.asarray(A)
22592257
slices = tuple(slice(None, None, stride[i]) for i in range(A.ndim))
2260-
a = A[slices]
2261-
b = B[slices]
2258+
a, b = A[slices], B[slices]
22622259

22632260
result = dpnp.linalg.norm(b, axis=axis)
22642261
expected = numpy.linalg.norm(a, axis=axis)
@@ -2278,8 +2275,7 @@ def test_strided_ND(self, axis, stride):
22782275
A = numpy.random.rand(12, 16, 20, 24)
22792276
B = dpnp.asarray(A)
22802277
slices = tuple(slice(None, None, stride[i]) for i in range(A.ndim))
2281-
a = A[slices]
2282-
b = B[slices]
2278+
a, b = A[slices], B[slices]
22832279

22842280
result = dpnp.linalg.norm(b, axis=axis)
22852281
expected = numpy.linalg.norm(a, axis=axis)
@@ -2299,6 +2295,28 @@ def test_matrix_norm(self, ord, keepdims):
22992295
expected = numpy.linalg.matrix_norm(a, ord=ord, keepdims=keepdims)
23002296
assert_dtype_allclose(result, expected)
23012297

2298+
@pytest.mark.parametrize("dtype", [dpnp.float32, dpnp.int32])
2299+
@pytest.mark.parametrize(
2300+
"shape_axis", [[(2, 0), None], [(2, 0, 3), (0, 1)]]
2301+
)
2302+
def test_matrix_norm_empty(self, dtype, shape_axis):
2303+
shape, axis = shape_axis[0], shape_axis[1]
2304+
x = dpnp.zeros(shape, dtype=dtype)
2305+
2306+
assert_equal(dpnp.linalg.norm(x, axis=axis, ord="fro"), 0)
2307+
assert_equal(dpnp.linalg.norm(x, axis=axis, ord="nuc"), 0)
2308+
assert_equal(dpnp.linalg.norm(x, axis=axis, ord=2), 0)
2309+
assert_equal(dpnp.linalg.norm(x, axis=axis, ord=1), 0)
2310+
assert_equal(dpnp.linalg.norm(x, axis=axis, ord=dpnp.inf), 0)
2311+
2312+
@pytest.mark.parametrize("dtype", [dpnp.float32, dpnp.int32])
2313+
@pytest.mark.parametrize("axis", [None, 0])
2314+
def test_vector_norm_empty(self, dtype, axis):
2315+
x = dpnp.zeros(0, dtype=dtype)
2316+
assert_equal(dpnp.linalg.vector_norm(x, axis=axis, ord=1), 0)
2317+
assert_equal(dpnp.linalg.vector_norm(x, axis=axis, ord=2), 0)
2318+
assert_equal(dpnp.linalg.vector_norm(x, axis=axis, ord=dpnp.inf), 0)
2319+
23022320
@testing.with_requires("numpy>=2.0")
23032321
@pytest.mark.parametrize(
23042322
"ord", [None, -dpnp.inf, -2, -1, 0, 1, 2, 3.5, dpnp.inf]
@@ -2320,13 +2338,10 @@ def test_vector_norm_0D(self, ord):
23202338
def test_vector_norm_1D(self, ord, axis, keepdims):
23212339
a = generate_random_numpy_array(10)
23222340
ia = dpnp.array(a)
2341+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
23232342

2324-
result = dpnp.linalg.vector_norm(
2325-
ia, ord=ord, axis=axis, keepdims=keepdims
2326-
)
2327-
expected = numpy.linalg.vector_norm(
2328-
a, ord=ord, axis=axis, keepdims=keepdims
2329-
)
2343+
result = dpnp.linalg.vector_norm(ia, **kwarg)
2344+
expected = numpy.linalg.vector_norm(a, **kwarg)
23302345
assert_dtype_allclose(result, expected)
23312346

23322347
@testing.with_requires("numpy>=2.0")
@@ -2343,29 +2358,26 @@ def test_vector_norm_1D(self, ord, axis, keepdims):
23432358
def test_vector_norm_ND(self, ord, axis, keepdims):
23442359
a = numpy.arange(120).reshape(2, 3, 4, 5)
23452360
ia = dpnp.array(a)
2361+
kwarg = {"ord": ord, "axis": axis, "keepdims": keepdims}
23462362

2347-
result = dpnp.linalg.vector_norm(
2348-
ia, ord=ord, axis=axis, keepdims=keepdims
2349-
)
2350-
expected = numpy.linalg.vector_norm(
2351-
a, ord=ord, axis=axis, keepdims=keepdims
2352-
)
2363+
result = dpnp.linalg.vector_norm(ia, **kwarg)
2364+
expected = numpy.linalg.vector_norm(a, **kwarg)
23532365
assert_dtype_allclose(result, expected)
23542366

23552367
def test_error(self):
2356-
ia = dpnp.arange(120).reshape(2, 3, 4, 5)
2368+
a = numpy.arange(120).reshape(2, 3, 4, 5)
2369+
ia = dpnp.array(a)
23572370

23582371
# Duplicate axes given
2359-
with pytest.raises(ValueError):
2360-
dpnp.linalg.norm(ia, axis=(2, 2))
2372+
assert_raises(ValueError, dpnp.linalg.norm, ia, axis=(2, 2))
2373+
assert_raises(ValueError, numpy.linalg.norm, a, axis=(2, 2))
23612374

23622375
#'axis' must be None, an integer or a tuple of integers
2363-
with pytest.raises(TypeError):
2364-
dpnp.linalg.norm(ia, axis=[2])
2376+
assert_raises(TypeError, dpnp.linalg.norm, ia, axis=[2])
2377+
assert_raises(TypeError, numpy.linalg.norm, a, axis=[2])
23652378

23662379
# Invalid norm order for vectors
2367-
with pytest.raises(ValueError):
2368-
dpnp.linalg.norm(ia, axis=1, ord=[3])
2380+
assert_raises(ValueError, dpnp.linalg.norm, ia, axis=1, ord=[3])
23692381

23702382

23712383
class TestQr:

0 commit comments

Comments
 (0)