Skip to content

[Backend Tester] Add convolution tests #12847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions backends/test/suite/operators/test_conv1d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# 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-unsafe


import torch
from executorch.backends.test.suite.flow import TestFlow

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,
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 Conv1d(OperatorTest):
@dtype_test
def test_conv1d_dtype(self, flow: TestFlow, dtype) -> None:
self._test_op(
Model().to(dtype),
((torch.rand(4, 3, 50) * 10).to(dtype),),
flow,
)

def test_conv1d_basic(self, flow: TestFlow) -> None:
self._test_op(
Model(),
(torch.randn(4, 3, 50),),
flow,
)

def test_conv1d_kernel_size(self, flow: TestFlow) -> None:
self._test_op(
Model(kernel_size=1),
(torch.randn(4, 3, 50),),
flow,
)
self._test_op(
Model(kernel_size=5),
(torch.randn(4, 3, 50),),
flow,
)

def test_conv1d_stride(self, flow: TestFlow) -> None:
self._test_op(
Model(stride=2),
(torch.randn(4, 3, 50),),
flow,
)

def test_conv1d_padding(self, flow: TestFlow) -> None:
self._test_op(
Model(padding=1),
(torch.randn(4, 3, 50),),
flow,
)
self._test_op(
Model(padding=2),
(torch.randn(4, 3, 50),),
flow,
)

def test_conv1d_dilation(self, flow: TestFlow) -> None:
self._test_op(
Model(dilation=2),
(torch.randn(4, 3, 50),),
flow,
)

def test_conv1d_groups(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=6, out_channels=6, groups=3),
(torch.randn(4, 6, 50),),
flow,
)

def test_conv1d_depthwise(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=8, out_channels=8, groups=8),
(torch.randn(4, 8, 50),),
flow,
)

def test_conv1d_no_bias(self, flow: TestFlow) -> None:
self._test_op(
Model(bias=False),
(torch.randn(4, 3, 50),),
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(4, 3, 50),),
flow,
)

def test_conv1d_channels(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=1, out_channels=1),
(torch.randn(4, 1, 50),),
flow,
)
self._test_op(
Model(in_channels=5, out_channels=10),
(torch.randn(4, 5, 50),),
flow,
)
167 changes: 167 additions & 0 deletions backends/test/suite/operators/test_conv2d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 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-unsafe

from typing import Tuple, Union

import torch
from executorch.backends.test.suite.flow import TestFlow

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: 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",
):
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 Conv2d(OperatorTest):
@dtype_test
def test_conv2d_dtype(self, flow: TestFlow, dtype) -> None:
self._test_op(
Model().to(dtype),
((torch.rand(4, 3, 16, 16) * 10).to(dtype),),
flow,
)

def test_conv2d_basic(self, flow: TestFlow) -> None:
self._test_op(
Model(),
(torch.randn(4, 3, 16, 16),),
flow,
)

def test_conv2d_kernel_size(self, flow: TestFlow) -> None:
self._test_op(
Model(kernel_size=1),
(torch.randn(4, 3, 16, 16),),
flow,
)
self._test_op(
Model(kernel_size=5),
(torch.randn(4, 3, 16, 16),),
flow,
)
self._test_op(
Model(kernel_size=(3, 5)),
(torch.randn(4, 3, 16, 16),),
flow,
)

def test_conv2d_stride(self, flow: TestFlow) -> None:
self._test_op(
Model(stride=2),
(torch.randn(4, 3, 16, 16),),
flow,
)
self._test_op(
Model(stride=(2, 1)),
(torch.randn(4, 3, 16, 16),),
flow,
)

def test_conv2d_padding(self, flow: TestFlow) -> None:
self._test_op(
Model(padding=1),
(torch.randn(4, 3, 16, 16),),
flow,
)
self._test_op(
Model(padding=(1, 2)),
(torch.randn(4, 3, 16, 16),),
flow,
)

def test_conv2d_dilation(self, flow: TestFlow) -> None:
self._test_op(
Model(dilation=2),
(torch.randn(4, 3, 16, 16),),
flow,
)
self._test_op(
Model(dilation=(2, 1)),
(torch.randn(4, 3, 16, 16),),
flow,
)

def test_conv2d_groups(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=6, out_channels=6, groups=3),
(torch.randn(4, 6, 16, 16),),
flow,
)

def test_conv2d_depthwise(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=8, out_channels=8, groups=8),
(torch.randn(4, 8, 16, 16),),
flow,
)

def test_conv2d_no_bias(self, flow: TestFlow) -> None:
self._test_op(
Model(bias=False),
(torch.randn(4, 3, 16, 16),),
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(4, 3, 16, 16),),
flow,
)

def test_conv2d_channels(self, flow: TestFlow) -> None:
self._test_op(
Model(in_channels=1, out_channels=1),
(torch.randn(4, 1, 16, 16),),
flow,
)
self._test_op(
Model(in_channels=5, out_channels=10),
(torch.randn(4, 5, 16, 16),),
flow,
)

def test_conv2d_different_spatial_dims(self, flow: TestFlow) -> None:
self._test_op(
Model(),
(torch.randn(4, 3, 20, 16),),
flow,
)
Loading
Loading