@@ -111,8 +111,10 @@ def _check_kernel_scripted_vs_eager(kernel, input, *args, rtol, atol, **kwargs):
111
111
112
112
input = input .as_subclass (torch .Tensor )
113
113
with ignore_jit_no_profile_information_warning ():
114
- actual = kernel_scripted (input , * args , ** kwargs )
115
- expected = kernel (input , * args , ** kwargs )
114
+ with freeze_rng_state ():
115
+ actual = kernel_scripted (input , * args , ** kwargs )
116
+ with freeze_rng_state ():
117
+ expected = kernel (input , * args , ** kwargs )
116
118
117
119
assert_close (actual , expected , rtol = rtol , atol = atol )
118
120
@@ -3238,6 +3240,78 @@ def test_functional_image_correctness(self, dimensions, kernel_size, sigma, dtyp
3238
3240
torch .testing .assert_close (actual , expected , rtol = 0 , atol = 1 )
3239
3241
3240
3242
3243
+ class TestGaussianNoise :
3244
+ @pytest .mark .parametrize (
3245
+ "make_input" ,
3246
+ [make_image_tensor , make_image , make_video ],
3247
+ )
3248
+ def test_kernel (self , make_input ):
3249
+ check_kernel (
3250
+ F .gaussian_noise ,
3251
+ make_input (dtype = torch .float32 ),
3252
+ # This cannot pass because the noise on a batch in not per-image
3253
+ check_batched_vs_unbatched = False ,
3254
+ )
3255
+
3256
+ @pytest .mark .parametrize (
3257
+ "make_input" ,
3258
+ [make_image_tensor , make_image , make_video ],
3259
+ )
3260
+ def test_functional (self , make_input ):
3261
+ check_functional (F .gaussian_noise , make_input (dtype = torch .float32 ))
3262
+
3263
+ @pytest .mark .parametrize (
3264
+ ("kernel" , "input_type" ),
3265
+ [
3266
+ (F .gaussian_noise , torch .Tensor ),
3267
+ (F .gaussian_noise_image , tv_tensors .Image ),
3268
+ (F .gaussian_noise_video , tv_tensors .Video ),
3269
+ ],
3270
+ )
3271
+ def test_functional_signature (self , kernel , input_type ):
3272
+ check_functional_kernel_signature_match (F .gaussian_noise , kernel = kernel , input_type = input_type )
3273
+
3274
+ @pytest .mark .parametrize (
3275
+ "make_input" ,
3276
+ [make_image_tensor , make_image , make_video ],
3277
+ )
3278
+ def test_transform (self , make_input ):
3279
+ def adapter (_ , input , __ ):
3280
+ # This transform doesn't support uint8 so we have to convert the auto-generated uint8 tensors to float32
3281
+ # Same for PIL images
3282
+ for key , value in input .items ():
3283
+ if isinstance (value , torch .Tensor ) and not value .is_floating_point ():
3284
+ input [key ] = value .to (torch .float32 )
3285
+ if isinstance (value , PIL .Image .Image ):
3286
+ input [key ] = F .pil_to_tensor (value ).to (torch .float32 )
3287
+ return input
3288
+
3289
+ check_transform (transforms .GaussianNoise (), make_input (dtype = torch .float32 ), check_sample_input = adapter )
3290
+
3291
+ def test_bad_input (self ):
3292
+ with pytest .raises (ValueError , match = "Gaussian Noise is not implemented for PIL images." ):
3293
+ F .gaussian_noise (make_image_pil ())
3294
+ with pytest .raises (ValueError , match = "Input tensor is expected to be in float dtype" ):
3295
+ F .gaussian_noise (make_image (dtype = torch .uint8 ))
3296
+ with pytest .raises (ValueError , match = "sigma shouldn't be negative" ):
3297
+ F .gaussian_noise (make_image (dtype = torch .float32 ), sigma = - 1 )
3298
+
3299
+ def test_clip (self ):
3300
+ img = make_image (dtype = torch .float32 )
3301
+
3302
+ out = F .gaussian_noise (img , mean = 100 , clip = False )
3303
+ assert out .min () > 50
3304
+
3305
+ out = F .gaussian_noise (img , mean = 100 , clip = True )
3306
+ assert (out == 1 ).all ()
3307
+
3308
+ out = F .gaussian_noise (img , mean = - 100 , clip = False )
3309
+ assert out .min () < - 50
3310
+
3311
+ out = F .gaussian_noise (img , mean = - 100 , clip = True )
3312
+ assert (out == 0 ).all ()
3313
+
3314
+
3241
3315
class TestAutoAugmentTransforms :
3242
3316
# These transforms have a lot of branches in their `forward()` passes which are conditioned on random sampling.
3243
3317
# It's typically very hard to test the effect on some parameters without heavy mocking logic.
0 commit comments