@@ -1513,6 +1513,9 @@ def test_kernel_video(self):
15131513 make_segmentation_mask ,
15141514 make_video ,
15151515 make_keypoints ,
1516+ pytest .param (
1517+ make_image_cvcuda , marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "CVCUDA not available" )
1518+ ),
15161519 ],
15171520 )
15181521 def test_functional (self , make_input ):
@@ -1528,9 +1531,16 @@ def test_functional(self, make_input):
15281531 (F .affine_mask , tv_tensors .Mask ),
15291532 (F .affine_video , tv_tensors .Video ),
15301533 (F .affine_keypoints , tv_tensors .KeyPoints ),
1534+ pytest .param (
1535+ F ._geometry ._affine_cvcuda ,
1536+ "cvcuda.Tensor" ,
1537+ marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "CVCUDA not available" ),
1538+ ),
15311539 ],
15321540 )
15331541 def test_functional_signature (self , kernel , input_type ):
1542+ if input_type == "cvcuda.Tensor" :
1543+ input_type = _import_cvcuda ().Tensor
15341544 check_functional_kernel_signature_match (F .affine , kernel = kernel , input_type = input_type )
15351545
15361546 @pytest .mark .parametrize (
@@ -1543,6 +1553,9 @@ def test_functional_signature(self, kernel, input_type):
15431553 make_segmentation_mask ,
15441554 make_video ,
15451555 make_keypoints ,
1556+ pytest .param (
1557+ make_image_cvcuda , marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "CVCUDA not available" )
1558+ ),
15461559 ],
15471560 )
15481561 @pytest .mark .parametrize ("device" , cpu_and_cuda ())
@@ -1560,8 +1573,19 @@ def test_transform(self, make_input, device):
15601573 "interpolation" , [transforms .InterpolationMode .NEAREST , transforms .InterpolationMode .BILINEAR ]
15611574 )
15621575 @pytest .mark .parametrize ("fill" , CORRECTNESS_FILLS )
1563- def test_functional_image_correctness (self , angle , translate , scale , shear , center , interpolation , fill ):
1564- image = make_image (dtype = torch .uint8 , device = "cpu" )
1576+ @pytest .mark .parametrize (
1577+ "make_input" ,
1578+ [
1579+ make_image ,
1580+ pytest .param (
1581+ make_image_cvcuda , marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "CVCUDA not available" )
1582+ ),
1583+ ],
1584+ )
1585+ def test_functional_image_correctness (
1586+ self , angle , translate , scale , shear , center , interpolation , fill , make_input
1587+ ):
1588+ image = make_input (dtype = torch .uint8 , device = "cpu" )
15651589
15661590 fill = adapt_fill (fill , dtype = torch .uint8 )
15671591
@@ -1575,6 +1599,14 @@ def test_functional_image_correctness(self, angle, translate, scale, shear, cent
15751599 interpolation = interpolation ,
15761600 fill = fill ,
15771601 )
1602+
1603+ if make_input is make_image_cvcuda :
1604+ actual = F .cvcuda_to_tensor (actual ).to (device = "cpu" )
1605+ actual = actual .squeeze (0 )
1606+ # drop the batch dimensions for image now
1607+ image = F .cvcuda_to_tensor (image )
1608+ image = image .squeeze (0 )
1609+
15781610 expected = F .to_image (
15791611 F .affine (
15801612 F .to_pil_image (image ),
@@ -1589,16 +1621,29 @@ def test_functional_image_correctness(self, angle, translate, scale, shear, cent
15891621 )
15901622
15911623 mae = (actual .float () - expected .float ()).abs ().mean ()
1592- assert mae < 2 if interpolation is transforms .InterpolationMode .NEAREST else 8
1624+ if make_input is make_image_cvcuda :
1625+ # CV-CUDA nearest interpolation does not follow same algorithm as PIL/torch
1626+ assert mae < 255 if interpolation is transforms .InterpolationMode .NEAREST else 1 , f"mae: { mae } "
1627+ else :
1628+ assert mae < 2 if interpolation is transforms .InterpolationMode .NEAREST else 8 , f"mae: { mae } "
15931629
15941630 @pytest .mark .parametrize ("center" , _CORRECTNESS_AFFINE_KWARGS ["center" ])
15951631 @pytest .mark .parametrize (
15961632 "interpolation" , [transforms .InterpolationMode .NEAREST , transforms .InterpolationMode .BILINEAR ]
15971633 )
15981634 @pytest .mark .parametrize ("fill" , CORRECTNESS_FILLS )
15991635 @pytest .mark .parametrize ("seed" , list (range (5 )))
1600- def test_transform_image_correctness (self , center , interpolation , fill , seed ):
1601- image = make_image (dtype = torch .uint8 , device = "cpu" )
1636+ @pytest .mark .parametrize (
1637+ "make_input" ,
1638+ [
1639+ make_image ,
1640+ pytest .param (
1641+ make_image_cvcuda , marks = pytest .mark .skipif (not CVCUDA_AVAILABLE , reason = "CVCUDA not available" )
1642+ ),
1643+ ],
1644+ )
1645+ def test_transform_image_correctness (self , center , interpolation , fill , seed , make_input ):
1646+ image = make_input (dtype = torch .uint8 , device = "cpu" )
16021647
16031648 fill = adapt_fill (fill , dtype = torch .uint8 )
16041649
@@ -1609,11 +1654,23 @@ def test_transform_image_correctness(self, center, interpolation, fill, seed):
16091654 torch .manual_seed (seed )
16101655 actual = transform (image )
16111656
1657+ if make_input is make_image_cvcuda :
1658+ actual = F .cvcuda_to_tensor (actual ).to (device = "cpu" )
1659+ actual = actual .squeeze (0 )
1660+ # drop the batch dimensions for image now
1661+ image = F .cvcuda_to_tensor (image )
1662+ image = image .squeeze (0 )
1663+
16121664 torch .manual_seed (seed )
16131665 expected = F .to_image (transform (F .to_pil_image (image )))
16141666
16151667 mae = (actual .float () - expected .float ()).abs ().mean ()
1616- assert mae < 2 if interpolation is transforms .InterpolationMode .NEAREST else 8
1668+ mae = (actual .float () - expected .float ()).abs ().mean ()
1669+ if make_input is make_image_cvcuda :
1670+ # CV-CUDA nearest interpolation does not follow same algorithm as PIL/torch
1671+ assert mae < 255 if interpolation is transforms .InterpolationMode .NEAREST else 1 , f"mae: { mae } "
1672+ else :
1673+ assert mae < 2 if interpolation is transforms .InterpolationMode .NEAREST else 8 , f"mae: { mae } "
16171674
16181675 def _compute_affine_matrix (self , * , angle , translate , scale , shear , center ):
16191676 rot = math .radians (angle )
0 commit comments