99
1010
1111class TestMisc :
12+ @staticmethod
13+ def _interp_atol (_result_dtype , dtype_x = None , ** _kwargs ):
14+ """Compute absolute tolerance based on intermediate computation dtype.
15+
16+ Args:
17+ _result_dtype: Output dtype (unused - we check input dtype instead)
18+ dtype_x: Input dtype for fx coordinates
19+ _kwargs: Additional test parameters (unused)
20+
21+ When dtype_x is int8/uint8/float16, xp.sin(fx) uses float16 precision,
22+ so we need relaxed tolerance even if the final result is upcasted to float64.
23+ Float16 has ~3 decimal digits of precision, hence atol=1e-3.
24+ """
25+ if dtype_x is not None :
26+ if numpy .dtype (dtype_x ).type in (
27+ numpy .int8 ,
28+ numpy .uint8 ,
29+ numpy .float16 ,
30+ ):
31+ return 1e-3
32+ return 1e-5
1233
1334 @testing .for_all_dtypes ()
1435 @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
@@ -401,17 +422,22 @@ def test_real_if_close_with_float_tol_false(self, xp, dtype):
401422
402423 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
403424 @testing .for_all_dtypes (name = "dtype_y" , no_bool = True )
404- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
425+ @testing .numpy_cupy_allclose (
426+ atol = _interp_atol , type_check = has_support_aspect64 ()
427+ )
405428 def test_interp (self , xp , dtype_y , dtype_x ):
406429 # interpolate at points on and outside the boundaries
430+ # tolerance is automatically adjusted based on dtype_x via resolver
407431 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
408432 fx = xp .asarray ([1 , 3 , 5 , 7 , 9 ], dtype = dtype_x )
409433 fy = xp .sin (fx ).astype (dtype_y )
410434 return xp .interp (x , fx , fy )
411435
412436 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
413437 @testing .for_all_dtypes (name = "dtype_y" , no_bool = True )
414- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
438+ @testing .numpy_cupy_allclose (
439+ atol = _interp_atol , type_check = has_support_aspect64 ()
440+ )
415441 def test_interp_period (self , xp , dtype_y , dtype_x ):
416442 # interpolate at points on and outside the boundaries
417443 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -421,7 +447,9 @@ def test_interp_period(self, xp, dtype_y, dtype_x):
421447
422448 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
423449 @testing .for_all_dtypes (name = "dtype_y" , no_bool = True )
424- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
450+ @testing .numpy_cupy_allclose (
451+ atol = _interp_atol , type_check = has_support_aspect64 ()
452+ )
425453 def test_interp_left_right (self , xp , dtype_y , dtype_x ):
426454 # interpolate at points on and outside the boundaries
427455 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -434,7 +462,9 @@ def test_interp_left_right(self, xp, dtype_y, dtype_x):
434462 @testing .with_requires ("numpy>=1.17.0" )
435463 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
436464 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
437- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
465+ @testing .numpy_cupy_allclose (
466+ atol = _interp_atol , type_check = has_support_aspect64 ()
467+ )
438468 def test_interp_nan_fy (self , xp , dtype_y , dtype_x ):
439469 # interpolate at points on and outside the boundaries
440470 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -446,7 +476,9 @@ def test_interp_nan_fy(self, xp, dtype_y, dtype_x):
446476 @testing .with_requires ("numpy>=1.17.0" )
447477 @testing .for_float_dtypes (name = "dtype_x" )
448478 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
449- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
479+ @testing .numpy_cupy_allclose (
480+ atol = _interp_atol , type_check = has_support_aspect64 ()
481+ )
450482 def test_interp_nan_fx (self , xp , dtype_y , dtype_x ):
451483 # interpolate at points on and outside the boundaries
452484 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -458,7 +490,9 @@ def test_interp_nan_fx(self, xp, dtype_y, dtype_x):
458490 @testing .with_requires ("numpy>=1.17.0" )
459491 @testing .for_float_dtypes (name = "dtype_x" )
460492 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
461- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
493+ @testing .numpy_cupy_allclose (
494+ atol = _interp_atol , type_check = has_support_aspect64 ()
495+ )
462496 def test_interp_nan_x (self , xp , dtype_y , dtype_x ):
463497 # interpolate at points on and outside the boundaries
464498 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -470,7 +504,9 @@ def test_interp_nan_x(self, xp, dtype_y, dtype_x):
470504 @testing .with_requires ("numpy>=1.17.0" )
471505 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
472506 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
473- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
507+ @testing .numpy_cupy_allclose (
508+ atol = _interp_atol , type_check = has_support_aspect64 ()
509+ )
474510 def test_interp_inf_fy (self , xp , dtype_y , dtype_x ):
475511 # interpolate at points on and outside the boundaries
476512 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -482,7 +518,9 @@ def test_interp_inf_fy(self, xp, dtype_y, dtype_x):
482518 @testing .with_requires ("numpy>=1.17.0" )
483519 @testing .for_float_dtypes (name = "dtype_x" )
484520 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
485- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
521+ @testing .numpy_cupy_allclose (
522+ atol = _interp_atol , type_check = has_support_aspect64 ()
523+ )
486524 def test_interp_inf_fx (self , xp , dtype_y , dtype_x ):
487525 # interpolate at points on and outside the boundaries
488526 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -494,7 +532,9 @@ def test_interp_inf_fx(self, xp, dtype_y, dtype_x):
494532 @testing .with_requires ("numpy>=1.17.0" )
495533 @testing .for_float_dtypes (name = "dtype_x" )
496534 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
497- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
535+ @testing .numpy_cupy_allclose (
536+ atol = _interp_atol , type_check = has_support_aspect64 ()
537+ )
498538 def test_interp_inf_x (self , xp , dtype_y , dtype_x ):
499539 # interpolate at points on and outside the boundaries
500540 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -505,7 +545,9 @@ def test_interp_inf_x(self, xp, dtype_y, dtype_x):
505545
506546 @testing .for_all_dtypes (name = "dtype_x" , no_bool = True , no_complex = True )
507547 @testing .for_all_dtypes (name = "dtype_y" , no_bool = True )
508- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
548+ @testing .numpy_cupy_allclose (
549+ atol = _interp_atol , type_check = has_support_aspect64 ()
550+ )
509551 def test_interp_size1 (self , xp , dtype_y , dtype_x ):
510552 # interpolate at points on and outside the boundaries
511553 x = xp .asarray ([0 , 1 , 2 , 4 , 6 , 8 , 9 , 10 ], dtype = dtype_x )
@@ -518,7 +560,9 @@ def test_interp_size1(self, xp, dtype_y, dtype_x):
518560 @testing .with_requires ("numpy>=1.17.0" )
519561 @testing .for_float_dtypes (name = "dtype_x" )
520562 @testing .for_dtypes ("efdFD" , name = "dtype_y" )
521- @testing .numpy_cupy_allclose (atol = 1e-5 , type_check = has_support_aspect64 ())
563+ @testing .numpy_cupy_allclose (
564+ atol = _interp_atol , type_check = has_support_aspect64 ()
565+ )
522566 def test_interp_inf_to_nan (self , xp , dtype_y , dtype_x ):
523567 # from NumPy's test_non_finite_inf
524568 x = xp .asarray ([0.5 ], dtype = dtype_x )
0 commit comments