Skip to content

Commit 5f73575

Browse files
Update dpnp.linalg.cond() test for singular matrix
1 parent c3b8403 commit 5f73575

File tree

1 file changed

+50
-17
lines changed

1 file changed

+50
-17
lines changed

dpnp/tests/test_linalg.py

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -326,29 +326,62 @@ def test_bool(self, p):
326326
@pytest.mark.parametrize(
327327
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]
328328
)
329-
def test_nan(self, p):
329+
def test_singular_2D(self, p):
330+
a = numpy.ones((2, 2))
331+
ia = dpnp.array(a)
332+
333+
# Unlike NumPy which returns `inf` for all norm orders,
334+
# DPNP raises LinAlgError for 1, -1, inf, -inf, and 'fro'
335+
# due to use of gesv in 2D case.
336+
# For None, 2, and -2 DPNP matches NumPy behavior.
337+
if p in [None, 2, -2]:
338+
result = dpnp.linalg.cond(ia, p=p)
339+
expected = numpy.linalg.cond(a, p=p)
340+
assert_dtype_allclose(result, expected)
341+
else:
342+
assert_raises(dpnp.linalg.LinAlgError, dpnp.linalg.cond, ia, p=p)
343+
344+
@pytest.mark.parametrize("shape", [(2, 2, 2), (2, 2, 2, 2)])
345+
@pytest.mark.parametrize(
346+
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]
347+
)
348+
def test_singular_ND(self, shape, p):
330349
# dpnp.linalg.cond uses dpnp.linalg.inv()
331350
# for the case when p is not None or p != -2 or p != 2
332351
# For singular matrices cuSolver raises an error
333-
# while OneMKL returns nans
334-
if is_cuda_device() and p in [-dpnp.inf, -1, 1, dpnp.inf, "fro"]:
352+
# while OneMKL < 2025.2 returns nans
353+
# TODO: remove it when mkl=2025.2 is released
354+
if (
355+
is_cuda_device()
356+
and not requires_intel_mkl_version("2025.2")
357+
and p in [-dpnp.inf, -1, 1, dpnp.inf, "fro"]
358+
):
335359
pytest.skip("Different behavior on CUDA")
336-
elif requires_intel_mkl_version("2025.2") and p in [
337-
-dpnp.inf,
338-
-1,
339-
1,
340-
dpnp.inf,
341-
"fro",
342-
]:
343-
pytest.skip("SAT-7966")
344-
a = generate_random_numpy_array((2, 2, 2, 2))
345-
a[0, 0] = 0
346-
a[1, 1] = 0
360+
a = numpy.ones((shape))
347361
ia = dpnp.array(a)
348362

349-
result = dpnp.linalg.cond(ia, p=p)
350-
expected = numpy.linalg.cond(a, p=p)
351-
assert_dtype_allclose(result, expected)
363+
# Unlike NumPy which returns `inf` for all norm orders,
364+
# DPNP raises LinAlgError for 1, -1, inf, -inf, and 'fro'
365+
# due to use of dpnp.linalg.inv() with OneMKL >= 2025.2.
366+
# For None, 2, and -2 DPNP matches NumPy behavior.
367+
if requires_intel_mkl_version("2025.2"):
368+
if p in [None, 2, -2]:
369+
result = dpnp.linalg.cond(ia, p=p)
370+
expected = numpy.linalg.cond(a, p=p)
371+
assert_dtype_allclose(result, expected)
372+
else:
373+
assert_raises(
374+
dpnp.linalg.LinAlgError, dpnp.linalg.cond, ia, p=p
375+
)
376+
else:
377+
# For OneMKL < 2025.2:
378+
# dpnp.linalg.inv() uses getrf_batch + getri_batch
379+
# which do not raise LinAlgError.
380+
# Instead, the result may contain `inf` or `nan`
381+
# depending on singularity.
382+
result = dpnp.linalg.cond(ia, p=p)
383+
expected = numpy.linalg.cond(a, p=p)
384+
assert_dtype_allclose(result, expected)
352385

353386
@pytest.mark.parametrize(
354387
"p", [None, -dpnp.inf, -2, -1, 1, 2, dpnp.inf, "fro"]

0 commit comments

Comments
 (0)