From fd73fb9ef7596f416690daf6c31dd3ae7ca7cda4 Mon Sep 17 00:00:00 2001 From: Gregory Comer Date: Thu, 24 Jul 2025 21:06:04 -0700 Subject: [PATCH 1/2] Update [ghstack-poisoned] --- backends/test/suite/operators/test_conv1d.py | 89 +++++++++++++++++ backends/test/suite/operators/test_conv2d.py | 96 +++++++++++++++++++ backends/test/suite/operators/test_conv3d.py | 95 ++++++++++++++++++ .../suite/operators/test_convtranspose1d.py | 89 +++++++++++++++++ .../suite/operators/test_convtranspose2d.py | 96 +++++++++++++++++++ .../suite/operators/test_convtranspose3d.py | 95 ++++++++++++++++++ 6 files changed, 560 insertions(+) create mode 100644 backends/test/suite/operators/test_conv1d.py create mode 100644 backends/test/suite/operators/test_conv2d.py create mode 100644 backends/test/suite/operators/test_conv3d.py create mode 100644 backends/test/suite/operators/test_convtranspose1d.py create mode 100644 backends/test/suite/operators/test_convtranspose2d.py create mode 100644 backends/test/suite/operators/test_convtranspose3d.py diff --git a/backends/test/suite/operators/test_conv1d.py b/backends/test/suite/operators/test_conv1d.py new file mode 100644 index 00000000000..1efd7685c18 --- /dev/null +++ b/backends/test/suite/operators/test_conv1d.py @@ -0,0 +1,89 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True, + padding_mode="zeros", + ): + super().__init__() + self.conv = torch.nn.Conv1d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias, + padding_mode=padding_mode, + ) + + def forward(self, x): + return self.conv(x) + +@operator_test +class TestConv1d(OperatorTest): + @dtype_test + def test_conv1d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, length) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 10) * 10).to(dtype),), tester_factory) + + def test_conv1d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 10),), tester_factory) + self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 10),), tester_factory) + self._test_op(Model(padding=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 10),), tester_factory) + + def test_conv1d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_padding_modes(self, tester_factory: Callable) -> None: + # Test different padding modes + for mode in ["zeros", "reflect", "replicate", "circular"]: + self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 10),), tester_factory) + + def test_conv1d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 10),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 10),), tester_factory) diff --git a/backends/test/suite/operators/test_conv2d.py b/backends/test/suite/operators/test_conv2d.py new file mode 100644 index 00000000000..40b3b9dc24b --- /dev/null +++ b/backends/test/suite/operators/test_conv2d.py @@ -0,0 +1,96 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable, Union, Tuple + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True, + padding_mode="zeros", + ): + super().__init__() + self.conv = torch.nn.Conv2d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias, + padding_mode=padding_mode, + ) + + def forward(self, x): + return self.conv(x) + +@operator_test +class TestConv2d(OperatorTest): + @dtype_test + def test_conv2d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, height, width) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), tester_factory) + + def test_conv2d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(kernel_size=(3, 5)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(stride=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(padding=(1, 2)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(dilation=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 8, 8),), tester_factory) + + def test_conv2d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_padding_modes(self, tester_factory: Callable) -> None: + # Test different padding modes + for mode in ["zeros", "reflect", "replicate", "circular"]: + self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_conv2d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 8, 8),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 8, 8),), tester_factory) + + def test_conv2d_different_spatial_dims(self, tester_factory: Callable) -> None: + # Test with different height and width + self._test_op(Model(), (torch.randn(2, 3, 10, 8),), tester_factory) diff --git a/backends/test/suite/operators/test_conv3d.py b/backends/test/suite/operators/test_conv3d.py new file mode 100644 index 00000000000..baade4df10e --- /dev/null +++ b/backends/test/suite/operators/test_conv3d.py @@ -0,0 +1,95 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable, Union, Tuple + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + dilation=1, + groups=1, + bias=True, + padding_mode="zeros", + ): + super().__init__() + self.conv = torch.nn.Conv3d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias, + padding_mode=padding_mode, + ) + + def forward(self, x): + return self.conv(x) + +@operator_test +class TestConv3d(OperatorTest): + @dtype_test + def test_conv3d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, depth, height, width) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), tester_factory) + + def test_conv3d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_conv3d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(kernel_size=(1, 3, 3)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_conv3d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 6, 6, 6),), tester_factory) + self._test_op(Model(stride=(1, 2, 2)), (torch.randn(2, 3, 4, 6, 6),), tester_factory) + + def test_conv3d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(padding=(0, 1, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_conv3d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 6, 6, 6),), tester_factory) + self._test_op(Model(dilation=(1, 2, 2)), (torch.randn(2, 3, 4, 6, 6),), tester_factory) + + def test_conv3d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 4, 4, 4),), tester_factory) + + def test_conv3d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_conv3d_padding_modes(self, tester_factory: Callable) -> None: + # Test different padding modes + for mode in ["zeros", "reflect", "replicate", "circular"]: + self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_conv3d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 4, 4, 4),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 4, 4, 4),), tester_factory) + + def test_conv3d_different_spatial_dims(self, tester_factory: Callable) -> None: + # Test with different depth, height, and width + self._test_op(Model(), (torch.randn(2, 3, 3, 4, 5),), tester_factory) diff --git a/backends/test/suite/operators/test_convtranspose1d.py b/backends/test/suite/operators/test_convtranspose1d.py new file mode 100644 index 00000000000..d93e542de4a --- /dev/null +++ b/backends/test/suite/operators/test_convtranspose1d.py @@ -0,0 +1,89 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable, Union, Tuple + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + output_padding=0, + dilation=1, + groups=1, + bias=True, + ): + super().__init__() + self.conv_transpose = torch.nn.ConvTranspose1d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + output_padding=output_padding, + dilation=dilation, + groups=groups, + bias=bias, + ) + + def forward(self, x): + return self.conv_transpose(x) + +@operator_test +class TestConvTranspose1d(OperatorTest): + @dtype_test + def test_convtranspose1d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, length) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 10) * 10).to(dtype),), tester_factory) + + def test_convtranspose1d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 10),), tester_factory) + self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 10),), tester_factory) + self._test_op(Model(padding=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_output_padding(self, tester_factory: Callable) -> None: + # Test with different output_padding values (requires stride > 1) + self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels and out_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 10),), tester_factory) + + def test_convtranspose1d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 10),), tester_factory) + + def test_convtranspose1d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 10),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 10),), tester_factory) + \ No newline at end of file diff --git a/backends/test/suite/operators/test_convtranspose2d.py b/backends/test/suite/operators/test_convtranspose2d.py new file mode 100644 index 00000000000..b5a4dfb784c --- /dev/null +++ b/backends/test/suite/operators/test_convtranspose2d.py @@ -0,0 +1,96 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable, Union, Tuple + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + output_padding=0, + dilation=1, + groups=1, + bias=True, + ): + super().__init__() + self.conv_transpose = torch.nn.ConvTranspose2d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + output_padding=output_padding, + dilation=dilation, + groups=groups, + bias=bias, + ) + + def forward(self, x): + return self.conv_transpose(x) + +@operator_test +class TestConvTranspose2d(OperatorTest): + @dtype_test + def test_convtranspose2d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, height, width) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), tester_factory) + + def test_convtranspose2d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(kernel_size=(3, 5)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(stride=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(padding=(1, 2)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_output_padding(self, tester_factory: Callable) -> None: + # Test with different output_padding values (requires stride > 1) + self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(stride=(2, 2), output_padding=(1, 0)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 8, 8),), tester_factory) + self._test_op(Model(dilation=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels and out_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 8, 8),), tester_factory) + + def test_convtranspose2d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 8, 8),), tester_factory) + + def test_convtranspose2d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 8, 8),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 8, 8),), tester_factory) + + def test_convtranspose2d_different_spatial_dims(self, tester_factory: Callable) -> None: + # Test with different height and width + self._test_op(Model(), (torch.randn(2, 3, 10, 8),), tester_factory) diff --git a/backends/test/suite/operators/test_convtranspose3d.py b/backends/test/suite/operators/test_convtranspose3d.py new file mode 100644 index 00000000000..00612725016 --- /dev/null +++ b/backends/test/suite/operators/test_convtranspose3d.py @@ -0,0 +1,95 @@ +# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +# pyre-strict + +from typing import Callable, Union, Tuple + +import torch + +from executorch.backends.test.compliance_suite import ( + dtype_test, + operator_test, + OperatorTest, +) + +class Model(torch.nn.Module): + def __init__( + self, + in_channels=3, + out_channels=6, + kernel_size=3, + stride=1, + padding=0, + output_padding=0, + dilation=1, + groups=1, + bias=True, + ): + super().__init__() + self.conv_transpose = torch.nn.ConvTranspose3d( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + output_padding=output_padding, + dilation=dilation, + groups=groups, + bias=bias, + ) + + def forward(self, x): + return self.conv_transpose(x) + +@operator_test +class TestConvTranspose3d(OperatorTest): + @dtype_test + def test_convtranspose3d_dtype(self, dtype, tester_factory: Callable) -> None: + # Input shape: (batch_size, in_channels, depth, height, width) + self._test_op(Model().to(dtype), ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), tester_factory) + + def test_convtranspose3d_basic(self, tester_factory: Callable) -> None: + # Basic test with default parameters + self._test_op(Model(), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_kernel_size(self, tester_factory: Callable) -> None: + # Test with different kernel sizes + self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(kernel_size=(1, 3, 3)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_stride(self, tester_factory: Callable) -> None: + # Test with different stride values + self._test_op(Model(stride=2), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(stride=(1, 2, 2)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_padding(self, tester_factory: Callable) -> None: + # Test with different padding values + self._test_op(Model(padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(padding=(0, 1, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_output_padding(self, tester_factory: Callable) -> None: + # Test with different output_padding values (requires stride > 1) + self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(stride=(2, 2, 2), output_padding=(1, 0, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_dilation(self, tester_factory: Callable) -> None: + # Test with different dilation values + self._test_op(Model(dilation=2), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + self._test_op(Model(dilation=(1, 2, 2)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_groups(self, tester_factory: Callable) -> None: + # Test with groups=3 (in_channels and out_channels must be divisible by groups) + self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_no_bias(self, tester_factory: Callable) -> None: + # Test without bias + self._test_op(Model(bias=False), (torch.randn(2, 3, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_channels(self, tester_factory: Callable) -> None: + # Test with different channel configurations + self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 4, 4, 4),), tester_factory) + self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 4, 4, 4),), tester_factory) + + def test_convtranspose3d_different_spatial_dims(self, tester_factory: Callable) -> None: + # Test with different depth, height, and width + self._test_op(Model(), (torch.randn(2, 3, 3, 4, 5),), tester_factory) From 6acef0f6bb0765b434faeb1a277e8ae9160c3e4f Mon Sep 17 00:00:00 2001 From: Gregory James Comer Date: Fri, 25 Jul 2025 21:30:20 -0700 Subject: [PATCH 2/2] Update [ghstack-poisoned] --- backends/test/suite/operators/test_conv1d.py | 144 ++++++++----- backends/test/suite/operators/test_conv2d.py | 182 +++++++++++------ backends/test/suite/operators/test_conv3d.py | 176 ++++++++++------ .../suite/operators/test_convtranspose1d.py | 156 +++++++++----- .../suite/operators/test_convtranspose2d.py | 190 ++++++++++++------ .../suite/operators/test_convtranspose3d.py | 184 +++++++++++------ 6 files changed, 692 insertions(+), 340 deletions(-) diff --git a/backends/test/suite/operators/test_conv1d.py b/backends/test/suite/operators/test_conv1d.py index 1efd7685c18..6f1b840861b 100644 --- a/backends/test/suite/operators/test_conv1d.py +++ b/backends/test/suite/operators/test_conv1d.py @@ -1,17 +1,22 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, @@ -37,53 +42,96 @@ def __init__( bias=bias, padding_mode=padding_mode, ) - + def forward(self, x): return self.conv(x) + @operator_test -class TestConv1d(OperatorTest): +class Conv1d(OperatorTest): @dtype_test - def test_conv1d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, length) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 10) * 10).to(dtype),), tester_factory) - - def test_conv1d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 10),), tester_factory) - self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 10),), tester_factory) - self._test_op(Model(padding=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 10),), tester_factory) - - def test_conv1d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_padding_modes(self, tester_factory: Callable) -> None: - # Test different padding modes + def test_conv1d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 10) * 10).to(dtype),), + flow, + ) + + def test_conv1d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 10),), + flow, + ) + self._test_op( + Model(kernel_size=5), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 10),), + flow, + ) + self._test_op( + Model(padding=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 10),), + flow, + ) + + def test_conv1d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_padding_modes(self, flow: TestFlow) -> None: for mode in ["zeros", "reflect", "replicate", "circular"]: - self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 10),), tester_factory) - - def test_conv1d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 10),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 10),), tester_factory) + self._test_op( + Model(padding=1, padding_mode=mode), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_conv1d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 10),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 10),), + flow, + ) diff --git a/backends/test/suite/operators/test_conv2d.py b/backends/test/suite/operators/test_conv2d.py index 40b3b9dc24b..2a7bae01faa 100644 --- a/backends/test/suite/operators/test_conv2d.py +++ b/backends/test/suite/operators/test_conv2d.py @@ -1,26 +1,32 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable, Union, Tuple +from typing import Tuple, Union import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, in_channels=3, out_channels=6, - kernel_size=3, - stride=1, - padding=0, - dilation=1, + kernel_size: Union[int, Tuple[int, int]] = 3, + stride: Union[int, Tuple[int, int]] = 1, + padding: Union[int, Tuple[int, int]] = 0, + dilation: Union[int, Tuple[int, int]] = 1, groups=1, bias=True, padding_mode="zeros", @@ -37,60 +43,118 @@ def __init__( bias=bias, padding_mode=padding_mode, ) - + def forward(self, x): return self.conv(x) + @operator_test -class TestConv2d(OperatorTest): +class Conv2d(OperatorTest): @dtype_test - def test_conv2d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, height, width) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), tester_factory) - - def test_conv2d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(kernel_size=(3, 5)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(stride=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(padding=(1, 2)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(dilation=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 8, 8),), tester_factory) - - def test_conv2d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_padding_modes(self, tester_factory: Callable) -> None: - # Test different padding modes + def test_conv2d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), + flow, + ) + + def test_conv2d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(kernel_size=5), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(kernel_size=(3, 5)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(stride=(2, 1)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(padding=(1, 2)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(dilation=(2, 1)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 8, 8),), + flow, + ) + + def test_conv2d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_padding_modes(self, flow: TestFlow) -> None: for mode in ["zeros", "reflect", "replicate", "circular"]: - self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_conv2d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 8, 8),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 8, 8),), tester_factory) - - def test_conv2d_different_spatial_dims(self, tester_factory: Callable) -> None: - # Test with different height and width - self._test_op(Model(), (torch.randn(2, 3, 10, 8),), tester_factory) + self._test_op( + Model(padding=1, padding_mode=mode), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_conv2d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 8, 8),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 8, 8),), + flow, + ) + + def test_conv2d_different_spatial_dims(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 10, 8),), + flow, + ) diff --git a/backends/test/suite/operators/test_conv3d.py b/backends/test/suite/operators/test_conv3d.py index baade4df10e..276ee20734e 100644 --- a/backends/test/suite/operators/test_conv3d.py +++ b/backends/test/suite/operators/test_conv3d.py @@ -1,26 +1,32 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable, Union, Tuple +from typing import Tuple, Union import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, in_channels=3, out_channels=6, - kernel_size=3, - stride=1, - padding=0, - dilation=1, + kernel_size: Union[int, Tuple[int, int, int]] = 3, + stride: Union[int, Tuple[int, int, int]] = 1, + padding: Union[int, Tuple[int, int, int]] = 0, + dilation: Union[int, Tuple[int, int, int]] = 1, groups=1, bias=True, padding_mode="zeros", @@ -37,59 +43,113 @@ def __init__( bias=bias, padding_mode=padding_mode, ) - + def forward(self, x): return self.conv(x) + @operator_test -class TestConv3d(OperatorTest): +class Conv3d(OperatorTest): @dtype_test - def test_conv3d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, depth, height, width) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), tester_factory) - - def test_conv3d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_conv3d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(kernel_size=(1, 3, 3)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_conv3d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 6, 6, 6),), tester_factory) - self._test_op(Model(stride=(1, 2, 2)), (torch.randn(2, 3, 4, 6, 6),), tester_factory) - - def test_conv3d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(padding=(0, 1, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_conv3d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 6, 6, 6),), tester_factory) - self._test_op(Model(dilation=(1, 2, 2)), (torch.randn(2, 3, 4, 6, 6),), tester_factory) - - def test_conv3d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 4, 4, 4),), tester_factory) - - def test_conv3d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_conv3d_padding_modes(self, tester_factory: Callable) -> None: - # Test different padding modes + def test_conv3d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), + flow, + ) + + def test_conv3d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_conv3d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(kernel_size=(1, 3, 3)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_conv3d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 6, 6, 6),), + flow, + ) + self._test_op( + Model(stride=(1, 2, 2)), + (torch.randn(2, 3, 4, 6, 6),), + flow, + ) + + def test_conv3d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(padding=(0, 1, 1)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_conv3d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 6, 6, 6),), + flow, + ) + self._test_op( + Model(dilation=(1, 2, 2)), + (torch.randn(2, 3, 4, 6, 6),), + flow, + ) + + def test_conv3d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 4, 4, 4),), + flow, + ) + + def test_conv3d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_conv3d_padding_modes(self, flow: TestFlow) -> None: for mode in ["zeros", "reflect", "replicate", "circular"]: - self._test_op(Model(padding=1, padding_mode=mode), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_conv3d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 4, 4, 4),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 4, 4, 4),), tester_factory) - - def test_conv3d_different_spatial_dims(self, tester_factory: Callable) -> None: - # Test with different depth, height, and width - self._test_op(Model(), (torch.randn(2, 3, 3, 4, 5),), tester_factory) + self._test_op( + Model(padding=1, padding_mode=mode), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_conv3d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 4, 4, 4),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 4, 4, 4),), + flow, + ) + + def test_conv3d_different_spatial_dims(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 3, 4, 5),), + flow, + ) diff --git a/backends/test/suite/operators/test_convtranspose1d.py b/backends/test/suite/operators/test_convtranspose1d.py index d93e542de4a..b2fe3040225 100644 --- a/backends/test/suite/operators/test_convtranspose1d.py +++ b/backends/test/suite/operators/test_convtranspose1d.py @@ -1,27 +1,33 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable, Union, Tuple +from typing import Tuple, Union import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, in_channels=3, out_channels=6, - kernel_size=3, - stride=1, - padding=0, - output_padding=0, - dilation=1, + kernel_size: Union[int, Tuple[int]] = 3, + stride: Union[int, Tuple[int]] = 1, + padding: Union[int, Tuple[int]] = 0, + output_padding: Union[int, Tuple[int]] = 0, + dilation: Union[int, Tuple[int]] = 1, groups=1, bias=True, ): @@ -37,53 +43,95 @@ def __init__( groups=groups, bias=bias, ) - + def forward(self, x): return self.conv_transpose(x) + @operator_test -class TestConvTranspose1d(OperatorTest): +class ConvTranspose1d(OperatorTest): @dtype_test - def test_convtranspose1d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, length) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 10) * 10).to(dtype),), tester_factory) - - def test_convtranspose1d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 10),), tester_factory) - self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 10),), tester_factory) - self._test_op(Model(padding=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_output_padding(self, tester_factory: Callable) -> None: - # Test with different output_padding values (requires stride > 1) - self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels and out_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 10),), tester_factory) - - def test_convtranspose1d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 10),), tester_factory) - - def test_convtranspose1d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 10),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 10),), tester_factory) - \ No newline at end of file + def test_convtranspose1d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 10) * 10).to(dtype),), + flow, + ) + + def test_convtranspose1d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 10),), + flow, + ) + self._test_op( + Model(kernel_size=5), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 10),), + flow, + ) + self._test_op( + Model(padding=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_output_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2, output_padding=1), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 10),), + flow, + ) + + def test_convtranspose1d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 10),), + flow, + ) + + def test_convtranspose1d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 10),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 10),), + flow, + ) diff --git a/backends/test/suite/operators/test_convtranspose2d.py b/backends/test/suite/operators/test_convtranspose2d.py index b5a4dfb784c..13ad272645f 100644 --- a/backends/test/suite/operators/test_convtranspose2d.py +++ b/backends/test/suite/operators/test_convtranspose2d.py @@ -1,27 +1,33 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable, Union, Tuple +from typing import Tuple, Union import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, in_channels=3, out_channels=6, - kernel_size=3, - stride=1, - padding=0, - output_padding=0, - dilation=1, + kernel_size: Union[int, Tuple[int, int]] = 3, + stride: Union[int, Tuple[int, int]] = 1, + padding: Union[int, Tuple[int, int]] = 0, + output_padding: Union[int, Tuple[int, int]] = 0, + dilation: Union[int, Tuple[int, int]] = 1, groups=1, bias=True, ): @@ -37,60 +43,122 @@ def __init__( groups=groups, bias=bias, ) - + def forward(self, x): return self.conv_transpose(x) + @operator_test -class TestConvTranspose2d(OperatorTest): +class ConvTranspose2d(OperatorTest): @dtype_test - def test_convtranspose2d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, height, width) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), tester_factory) - - def test_convtranspose2d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(kernel_size=5), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(kernel_size=(3, 5)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(stride=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(padding=(1, 2)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_output_padding(self, tester_factory: Callable) -> None: - # Test with different output_padding values (requires stride > 1) - self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(stride=(2, 2), output_padding=(1, 0)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 8, 8),), tester_factory) - self._test_op(Model(dilation=(2, 1)), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels and out_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 8, 8),), tester_factory) - - def test_convtranspose2d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 8, 8),), tester_factory) - - def test_convtranspose2d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 8, 8),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 8, 8),), tester_factory) - - def test_convtranspose2d_different_spatial_dims(self, tester_factory: Callable) -> None: - # Test with different height and width - self._test_op(Model(), (torch.randn(2, 3, 10, 8),), tester_factory) + def test_convtranspose2d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 8, 8) * 10).to(dtype),), + flow, + ) + + def test_convtranspose2d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(kernel_size=5), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(kernel_size=(3, 5)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(stride=(2, 1)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(padding=(1, 2)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_output_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2, output_padding=1), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(stride=(2, 2), output_padding=(1, 0)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 8, 8),), + flow, + ) + self._test_op( + Model(dilation=(2, 1)), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 8, 8),), + flow, + ) + + def test_convtranspose2d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 8, 8),), + flow, + ) + + def test_convtranspose2d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 8, 8),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 8, 8),), + flow, + ) + + def test_convtranspose2d_different_spatial_dims(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 10, 8),), + flow, + ) diff --git a/backends/test/suite/operators/test_convtranspose3d.py b/backends/test/suite/operators/test_convtranspose3d.py index 00612725016..6cedc5b31cd 100644 --- a/backends/test/suite/operators/test_convtranspose3d.py +++ b/backends/test/suite/operators/test_convtranspose3d.py @@ -1,27 +1,33 @@ -# (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. -# pyre-strict +# pyre-unsafe -from typing import Callable, Union, Tuple +from typing import Tuple, Union import torch +from executorch.backends.test.suite.flow import TestFlow -from executorch.backends.test.compliance_suite import ( +from executorch.backends.test.suite.operators import ( dtype_test, operator_test, OperatorTest, ) + class Model(torch.nn.Module): def __init__( self, in_channels=3, out_channels=6, - kernel_size=3, - stride=1, - padding=0, - output_padding=0, - dilation=1, + kernel_size: Union[int, Tuple[int, int, int]] = 3, + stride: Union[int, Tuple[int, int, int]] = 1, + padding: Union[int, Tuple[int, int, int]] = 0, + output_padding: Union[int, Tuple[int, int, int]] = 0, + dilation: Union[int, Tuple[int, int, int]] = 1, groups=1, bias=True, ): @@ -37,59 +43,117 @@ def __init__( groups=groups, bias=bias, ) - + def forward(self, x): return self.conv_transpose(x) + @operator_test -class TestConvTranspose3d(OperatorTest): +class ConvTranspose3d(OperatorTest): @dtype_test - def test_convtranspose3d_dtype(self, dtype, tester_factory: Callable) -> None: - # Input shape: (batch_size, in_channels, depth, height, width) - self._test_op(Model().to(dtype), ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), tester_factory) - - def test_convtranspose3d_basic(self, tester_factory: Callable) -> None: - # Basic test with default parameters - self._test_op(Model(), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_kernel_size(self, tester_factory: Callable) -> None: - # Test with different kernel sizes - self._test_op(Model(kernel_size=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(kernel_size=(1, 3, 3)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_stride(self, tester_factory: Callable) -> None: - # Test with different stride values - self._test_op(Model(stride=2), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(stride=(1, 2, 2)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_padding(self, tester_factory: Callable) -> None: - # Test with different padding values - self._test_op(Model(padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(padding=(0, 1, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_output_padding(self, tester_factory: Callable) -> None: - # Test with different output_padding values (requires stride > 1) - self._test_op(Model(stride=2, output_padding=1), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(stride=(2, 2, 2), output_padding=(1, 0, 1)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_dilation(self, tester_factory: Callable) -> None: - # Test with different dilation values - self._test_op(Model(dilation=2), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - self._test_op(Model(dilation=(1, 2, 2)), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_groups(self, tester_factory: Callable) -> None: - # Test with groups=3 (in_channels and out_channels must be divisible by groups) - self._test_op(Model(in_channels=6, out_channels=6, groups=3), (torch.randn(2, 6, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_no_bias(self, tester_factory: Callable) -> None: - # Test without bias - self._test_op(Model(bias=False), (torch.randn(2, 3, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_channels(self, tester_factory: Callable) -> None: - # Test with different channel configurations - self._test_op(Model(in_channels=1, out_channels=1), (torch.randn(2, 1, 4, 4, 4),), tester_factory) - self._test_op(Model(in_channels=5, out_channels=10), (torch.randn(2, 5, 4, 4, 4),), tester_factory) - - def test_convtranspose3d_different_spatial_dims(self, tester_factory: Callable) -> None: - # Test with different depth, height, and width - self._test_op(Model(), (torch.randn(2, 3, 3, 4, 5),), tester_factory) + def test_convtranspose3d_dtype(self, flow: TestFlow, dtype) -> None: + self._test_op( + Model().to(dtype), + ((torch.rand(2, 3, 4, 4, 4) * 10).to(dtype),), + flow, + ) + + def test_convtranspose3d_basic(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_kernel_size(self, flow: TestFlow) -> None: + self._test_op( + Model(kernel_size=1), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(kernel_size=(1, 3, 3)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_stride(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(stride=(1, 2, 2)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(padding=1), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(padding=(0, 1, 1)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_output_padding(self, flow: TestFlow) -> None: + self._test_op( + Model(stride=2, output_padding=1), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(stride=(2, 2, 2), output_padding=(1, 0, 1)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_dilation(self, flow: TestFlow) -> None: + self._test_op( + Model(dilation=2), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + self._test_op( + Model(dilation=(1, 2, 2)), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_groups(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=6, out_channels=6, groups=3), + (torch.randn(2, 6, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_no_bias(self, flow: TestFlow) -> None: + self._test_op( + Model(bias=False), + (torch.randn(2, 3, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_channels(self, flow: TestFlow) -> None: + self._test_op( + Model(in_channels=1, out_channels=1), + (torch.randn(2, 1, 4, 4, 4),), + flow, + ) + self._test_op( + Model(in_channels=5, out_channels=10), + (torch.randn(2, 5, 4, 4, 4),), + flow, + ) + + def test_convtranspose3d_different_spatial_dims(self, flow: TestFlow) -> None: + self._test_op( + Model(), + (torch.randn(2, 3, 3, 4, 5),), + flow, + )