@@ -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