|
29 | 29 | make_bounding_boxes, |
30 | 30 | make_detection_masks, |
31 | 31 | make_image, |
| 32 | + make_image_cvcuda, |
32 | 33 | make_image_pil, |
33 | 34 | make_image_tensor, |
34 | 35 | make_keypoints, |
|
51 | 52 | from torchvision.transforms.v2 import functional as F |
52 | 53 | from torchvision.transforms.v2._utils import check_type, is_pure_tensor |
53 | 54 | from torchvision.transforms.v2.functional._geometry import _get_perspective_coeffs, _parallelogram_to_bounding_boxes |
54 | | -from torchvision.transforms.v2.functional._utils import _get_kernel, _register_kernel_internal |
| 55 | +from torchvision.transforms.v2.functional._utils import ( |
| 56 | + _get_kernel, |
| 57 | + _import_cvcuda, |
| 58 | + _is_cvcuda_available, |
| 59 | + _register_kernel_internal, |
| 60 | +) |
| 61 | + |
55 | 62 |
|
| 63 | +CVCUDA_AVAILABLE = _is_cvcuda_available() |
| 64 | +if CVCUDA_AVAILABLE: |
| 65 | + cvcuda = _import_cvcuda() |
56 | 66 |
|
57 | 67 | # turns all warnings into errors for this module |
58 | 68 | pytestmark = [pytest.mark.filterwarnings("error")] |
@@ -6732,6 +6742,93 @@ def test_functional_error(self): |
6732 | 6742 | F.pil_to_tensor(object()) |
6733 | 6743 |
|
6734 | 6744 |
|
| 6745 | +@pytest.mark.skipif(not CVCUDA_AVAILABLE, reason="test requires CVCUDA") |
| 6746 | +@needs_cuda |
| 6747 | +class TestToCVCUDATensor: |
| 6748 | + @pytest.mark.parametrize("image_type", (torch.Tensor, tv_tensors.Image)) |
| 6749 | + @pytest.mark.parametrize("dtype", [torch.uint8, torch.uint16, torch.float32, torch.float64]) |
| 6750 | + @pytest.mark.parametrize("device", cpu_and_cuda()) |
| 6751 | + @pytest.mark.parametrize("color_space", ["RGB", "GRAY"]) |
| 6752 | + @pytest.mark.parametrize("batch_dims", [(1,), (2,), (4,)]) |
| 6753 | + @pytest.mark.parametrize( |
| 6754 | + "fn", |
| 6755 | + [F.to_cvcuda_tensor, transform_cls_to_functional(transforms.ToCVCUDATensor)], |
| 6756 | + ) |
| 6757 | + def test_functional_and_transform(self, image_type, dtype, device, color_space, batch_dims, fn): |
| 6758 | + image = make_image(dtype=dtype, device=device, color_space=color_space, batch_dims=batch_dims) |
| 6759 | + if image_type is torch.Tensor: |
| 6760 | + image = image.as_subclass(torch.Tensor) |
| 6761 | + assert is_pure_tensor(image) |
| 6762 | + output = fn(image) |
| 6763 | + |
| 6764 | + assert isinstance(output, cvcuda.Tensor) |
| 6765 | + assert F.get_size(output) == F.get_size(image) |
| 6766 | + assert output is not None |
| 6767 | + |
| 6768 | + def test_invalid_input_type(self): |
| 6769 | + with pytest.raises(TypeError, match=r"inpt should be ``torch.Tensor``"): |
| 6770 | + F.to_cvcuda_tensor("invalid_input") |
| 6771 | + |
| 6772 | + def test_invalid_dimensions(self): |
| 6773 | + with pytest.raises(ValueError, match=r"pic should be 4 dimensional"): |
| 6774 | + img_data = torch.randint(0, 256, (3, 1, 3), dtype=torch.uint8) |
| 6775 | + img_data = img_data.cuda() |
| 6776 | + F.to_cvcuda_tensor(img_data) |
| 6777 | + |
| 6778 | + with pytest.raises(ValueError, match=r"pic should be 4 dimensional"): |
| 6779 | + img_data = torch.randint(0, 256, (4,), dtype=torch.uint8) |
| 6780 | + img_data = img_data.cuda() |
| 6781 | + F.to_cvcuda_tensor(img_data) |
| 6782 | + |
| 6783 | + with pytest.raises(ValueError, match=r"pic should be 4 dimensional"): |
| 6784 | + img_data = torch.randint(0, 256, (4, 4), dtype=torch.uint8) |
| 6785 | + img_data = img_data.cuda() |
| 6786 | + F.to_cvcuda_tensor(img_data) |
| 6787 | + |
| 6788 | + with pytest.raises(ValueError, match=r"pic should be 4 dimensional"): |
| 6789 | + img_data = torch.randint(0, 256, (1, 1, 3, 4, 4), dtype=torch.uint8) |
| 6790 | + img_data = img_data.cuda() |
| 6791 | + F.to_cvcuda_tensor(img_data) |
| 6792 | + |
| 6793 | + @pytest.mark.parametrize("dtype", [torch.uint8, torch.uint16, torch.float32, torch.float64]) |
| 6794 | + @pytest.mark.parametrize("device", cpu_and_cuda()) |
| 6795 | + @pytest.mark.parametrize("color_space", ["RGB", "GRAY"]) |
| 6796 | + @pytest.mark.parametrize("batch_size", [1, 2, 4]) |
| 6797 | + def test_round_trip(self, dtype, device, color_space, batch_size): |
| 6798 | + original_tensor = make_image_tensor( |
| 6799 | + dtype=dtype, device=device, color_space=color_space, batch_dims=(batch_size,) |
| 6800 | + ) |
| 6801 | + cvcuda_tensor = F.to_cvcuda_tensor(original_tensor) |
| 6802 | + result_tensor = F.cvcuda_to_tensor(cvcuda_tensor) |
| 6803 | + torch.testing.assert_close(result_tensor.to(device), original_tensor, rtol=0, atol=0) |
| 6804 | + assert result_tensor.shape[0] == batch_size |
| 6805 | + |
| 6806 | + |
| 6807 | +@pytest.mark.skipif(not CVCUDA_AVAILABLE, reason="test requires CVCUDA") |
| 6808 | +@needs_cuda |
| 6809 | +class TestCVDUDAToTensor: |
| 6810 | + @pytest.mark.parametrize("dtype", [torch.uint8, torch.uint16, torch.float32, torch.float64]) |
| 6811 | + @pytest.mark.parametrize("device", cpu_and_cuda()) |
| 6812 | + @pytest.mark.parametrize("color_space", ["RGB", "GRAY"]) |
| 6813 | + @pytest.mark.parametrize("batch_dims", [(1,), (2,), (4,)]) |
| 6814 | + @pytest.mark.parametrize( |
| 6815 | + "fn", |
| 6816 | + [F.cvcuda_to_tensor, transform_cls_to_functional(transforms.CVCUDAToTensor)], |
| 6817 | + ) |
| 6818 | + def test_functional_and_transform(self, dtype, device, color_space, batch_dims, fn): |
| 6819 | + input = make_image_cvcuda(dtype=dtype, device=device, color_space=color_space, batch_dims=batch_dims) |
| 6820 | + |
| 6821 | + output = fn(input) |
| 6822 | + |
| 6823 | + assert isinstance(output, torch.Tensor) |
| 6824 | + input_tensor = F.cvcuda_to_tensor(input) |
| 6825 | + assert F.get_size(output) == F.get_size(input_tensor) |
| 6826 | + |
| 6827 | + def test_functional_error(self): |
| 6828 | + with pytest.raises(TypeError, match="cvcuda_img should be `cvcuda.Tensor`"): |
| 6829 | + F.cvcuda_to_tensor(object()) |
| 6830 | + |
| 6831 | + |
6735 | 6832 | class TestLambda: |
6736 | 6833 | @pytest.mark.parametrize("input", [object(), torch.empty(()), np.empty(()), "string", 1, 0.0]) |
6737 | 6834 | @pytest.mark.parametrize("types", [(), (torch.Tensor, np.ndarray)]) |
|
0 commit comments