@@ -2712,21 +2712,74 @@ def fn(value):
27122712 @pytest .mark .parametrize ("output_dtype" , [torch .float32 , torch .float64 , torch .uint8 , torch .uint16 ])
27132713 @pytest .mark .parametrize ("device" , cpu_and_cuda ())
27142714 @pytest .mark .parametrize ("scale" , (True , False ))
2715- def test_image_correctness (self , input_dtype , output_dtype , device , scale ):
2715+ @pytest .mark .parametrize (
2716+ "make_input" ,
2717+ [
2718+ make_image ,
2719+ pytest .param (
2720+ make_image_cvcuda , marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "test requires CVCUDA" )
2721+ ),
2722+ ],
2723+ )
2724+ def test_image_correctness (self , input_dtype , output_dtype , device , scale , make_input ):
27162725 if input_dtype .is_floating_point and output_dtype == torch .int64 :
27172726 pytest .xfail ("float to int64 conversion is not supported" )
27182727 if input_dtype == torch .uint8 and output_dtype == torch .uint16 and device == "cuda" :
27192728 pytest .xfail ("uint8 to uint16 conversion is not supported on cuda" )
2729+ if input_dtype == torch .uint8 and output_dtype == torch .uint16 and scale and make_input == make_image_cvcuda :
2730+ pytest .xfail ("uint8 to uint16 conversion with scale is not supported in F._misc._to_dtype_cvcuda" )
27202731
2721- input = make_image (dtype = input_dtype , device = device )
2722-
2732+ input = make_input (dtype = input_dtype , device = device )
27232733 out = F .to_dtype (input , dtype = output_dtype , scale = scale )
2724- expected = self .reference_convert_dtype_image_tensor (input , dtype = output_dtype , scale = scale )
27252734
2726- if input_dtype .is_floating_point and not output_dtype .is_floating_point and scale :
2727- torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2728- else :
2729- torch .testing .assert_close (out , expected )
2735+ if isinstance (input , torch .Tensor ):
2736+ expected = self .reference_convert_dtype_image_tensor (input , dtype = output_dtype , scale = scale )
2737+ if input_dtype .is_floating_point and not output_dtype .is_floating_point and scale :
2738+ torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2739+ else :
2740+ torch .testing .assert_close (out , expected )
2741+ else : # cvcuda.Tensor
2742+ expected = self .reference_convert_dtype_image_tensor (
2743+ F .cvcuda_to_tensor (input ), dtype = output_dtype , scale = scale
2744+ )
2745+ out = F .cvcuda_to_tensor (out )
2746+ # there are some differences in dtype conversion between torchvision and cvcuda
2747+ # due to different rounding behavior when converting between types with different bit widths
2748+ # Check if we're converting to a type with more bits (without scaling)
2749+ in_bits = torch .iinfo (input_dtype ).bits if not input_dtype .is_floating_point else None
2750+ out_bits = torch .iinfo (output_dtype ).bits if not output_dtype .is_floating_point else None
2751+
2752+ if scale :
2753+ if input_dtype .is_floating_point and not output_dtype .is_floating_point :
2754+ # float -> int with scaling: allow for rounding differences
2755+ torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2756+ elif input_dtype == torch .uint16 and output_dtype == torch .uint8 :
2757+ # uint16 -> uint8 with scaling: allow large differences
2758+ torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2759+ else :
2760+ torch .testing .assert_close (out , expected )
2761+ else :
2762+ if in_bits is not None and out_bits is not None and out_bits > in_bits :
2763+ # uint to larger uint without scaling: allow large differences due to bit expansion
2764+ if input_dtype == torch .uint8 and output_dtype == torch .uint16 :
2765+ torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2766+ else :
2767+ torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2768+ elif not input_dtype .is_floating_point and not output_dtype .is_floating_point :
2769+ # uint to uint without scaling (same or smaller bits): allow for rounding
2770+ if input_dtype == torch .uint16 and output_dtype == torch .uint8 :
2771+ # uint16 -> uint8 can have large differences due to bit reduction
2772+ torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2773+ else :
2774+ torch .testing .assert_close (out , expected )
2775+ elif input_dtype .is_floating_point and not output_dtype .is_floating_point :
2776+ # float -> uint without scaling: allow for rounding differences
2777+ torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2778+ elif not input_dtype .is_floating_point and output_dtype .is_floating_point :
2779+ # uint -> float without scaling: allow for rounding differences
2780+ torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2781+ else :
2782+ torch .testing .assert_close (out , expected )
27302783
27312784 def was_scaled (self , inpt ):
27322785 # this assumes the target dtype is float
@@ -2825,65 +2878,6 @@ def test_uint16(self):
28252878 assert_equal (F .to_dtype (img_float32 , torch .uint8 , scale = True ), img_uint8 )
28262879 assert_close (F .to_dtype (img_uint8 , torch .float32 , scale = True ), img_float32 , rtol = 0 , atol = 1e-2 )
28272880
2828- @pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "test requires CVCUDA" )
2829- @pytest .mark .parametrize ("input_dtype" , [torch .float32 , torch .float64 , torch .uint8 , torch .uint16 ])
2830- @pytest .mark .parametrize ("output_dtype" , [torch .float32 , torch .float64 , torch .uint8 , torch .uint16 ])
2831- @pytest .mark .parametrize ("device" , cpu_and_cuda ())
2832- @pytest .mark .parametrize ("scale" , (True , False ))
2833- def test_cvcuda_parity (self , input_dtype , output_dtype , device , scale ):
2834- if input_dtype .is_floating_point and output_dtype == torch .int64 :
2835- pytest .xfail ("float to int64 conversion is not supported" )
2836- if input_dtype == torch .uint8 and output_dtype == torch .uint16 and device == "cuda" :
2837- pytest .xfail ("uint8 to uint16 conversion is not supported on cuda" )
2838- if input_dtype == torch .uint8 and output_dtype == torch .uint16 and scale :
2839- pytest .xfail ("uint8 to uint16 conversion with scale is not supported in F.to_dtype_image" )
2840-
2841- cvc_input = make_image_cvcuda (batch_dims = (1 ,), dtype = input_dtype , device = device )
2842- torch_input = F .cvcuda_to_tensor (cvc_input )
2843-
2844- out = F .to_dtype (cvc_input , dtype = output_dtype , scale = scale )
2845- out = F .cvcuda_to_tensor (out )
2846-
2847- expected = F .to_dtype (torch_input , dtype = output_dtype , scale = scale )
2848-
2849- # there are some differences in dtype conversion between torchvision and cvcuda
2850- # due to different rounding behavior when converting between types with different bit widths
2851- # Check if we're converting to a type with more bits (without scaling)
2852- in_bits = torch .iinfo (input_dtype ).bits if not input_dtype .is_floating_point else None
2853- out_bits = torch .iinfo (output_dtype ).bits if not output_dtype .is_floating_point else None
2854-
2855- if scale :
2856- if input_dtype .is_floating_point and not output_dtype .is_floating_point :
2857- # float -> int with scaling: allow for rounding differences
2858- torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2859- elif input_dtype == torch .uint16 and output_dtype == torch .uint8 :
2860- # uint16 -> uint8 with scaling: allow large differences
2861- torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2862- else :
2863- torch .testing .assert_close (out , expected )
2864- else :
2865- if in_bits is not None and out_bits is not None and out_bits > in_bits :
2866- # uint to larger uint without scaling: allow large differences due to bit expansion
2867- if input_dtype == torch .uint8 and output_dtype == torch .uint16 :
2868- torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2869- else :
2870- torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2871- elif not input_dtype .is_floating_point and not output_dtype .is_floating_point :
2872- # uint to uint without scaling (same or smaller bits): allow for rounding
2873- if input_dtype == torch .uint16 and output_dtype == torch .uint8 :
2874- # uint16 -> uint8 can have large differences due to bit reduction
2875- torch .testing .assert_close (out , expected , atol = 255 , rtol = 0 )
2876- else :
2877- torch .testing .assert_close (out , expected )
2878- elif input_dtype .is_floating_point and not output_dtype .is_floating_point :
2879- # float -> uint without scaling: allow for rounding differences
2880- torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2881- elif not input_dtype .is_floating_point and output_dtype .is_floating_point :
2882- # uint -> float without scaling: allow for rounding differences
2883- torch .testing .assert_close (out , expected , atol = 1 , rtol = 0 )
2884- else :
2885- torch .testing .assert_close (out , expected )
2886-
28872881
28882882class TestAdjustBrightness :
28892883 _CORRECTNESS_BRIGHTNESS_FACTORS = [0.5 , 0.0 , 1.0 , 5.0 ]
0 commit comments