Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 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
5 changes: 4 additions & 1 deletion backends/test/harness/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,10 @@ def run_method_and_compare_outputs(
print(f"Comparing Stage {stage} with Stage {reference_stage}")
for run_iteration in range(number_of_runs):
inputs_to_run = inputs if inputs else next(self.generate_random_inputs())
input_shapes = [generated_input.shape for generated_input in inputs_to_run]
input_shapes = [
generated_input.shape if hasattr(generated_input, "shape") else None
for generated_input in inputs_to_run
]
print(f"Run {run_iteration} with input shapes: {input_shapes}")

# Reference output (and quantization scale)
Expand Down
5 changes: 4 additions & 1 deletion backends/test/suite/operators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ def _create_test_for_backend(


class OperatorTest(unittest.TestCase):
def _test_op(self, model, inputs, flow: TestFlow):
def _test_op(
self, model, inputs, flow: TestFlow, generate_random_test_inputs: bool = True
):
context = get_active_test_context()

# This should be set in the wrapped test. See _make_wrapped_test above.
Expand All @@ -145,6 +147,7 @@ def _test_op(self, model, inputs, flow: TestFlow):
flow,
context.test_name,
context.params,
generate_random_test_inputs=generate_random_test_inputs,
)

log_test_summary(run_summary)
Expand Down
176 changes: 176 additions & 0 deletions backends/test/suite/operators/test_cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# 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 CatModel(torch.nn.Module):
def __init__(self, dim: int = 0):
super().__init__()
self.dim = dim

def forward(self, x1, x2, x3):
return torch.cat([x1, x2, x3], dim=self.dim)


@operator_test
class Cat(OperatorTest):
@dtype_test
def test_cat_dtype(self, flow: TestFlow, dtype) -> None:
self._test_op(
CatModel(),
(
torch.rand(8, 32).to(dtype),
torch.rand(12, 32).to(dtype),
torch.rand(16, 32).to(dtype),
),
flow,
)

def test_cat_dimensions(self, flow: TestFlow) -> None:
self._test_op(
CatModel(dim=0),
(
torch.randn(8, 32),
torch.randn(12, 32),
torch.randn(16, 32),
),
flow,
)

self._test_op(
CatModel(dim=1),
(
torch.randn(16, 8),
torch.randn(16, 12),
torch.randn(16, 16),
),
flow,
)

self._test_op(
CatModel(dim=2),
(
torch.randn(4, 8, 4),
torch.randn(4, 8, 8),
torch.randn(4, 8, 12),
),
flow,
)

def test_cat_negative_dim(self, flow: TestFlow) -> None:
self._test_op(
CatModel(dim=-1),
(
torch.randn(16, 8),
torch.randn(16, 12),
torch.randn(16, 16),
),
flow,
)

self._test_op(
CatModel(dim=-2),
(
torch.randn(8, 32),
torch.randn(12, 32),
torch.randn(16, 32),
),
flow,
)

def test_cat_different_shapes(self, flow: TestFlow) -> None:
self._test_op(
CatModel(),
(
torch.randn(128),
torch.randn(256),
torch.randn(384),
),
flow,
)

self._test_op(
CatModel(dim=0),
(
torch.randn(4, 8, 16),
torch.randn(8, 8, 16),
torch.randn(12, 8, 16),
),
flow,
)

self._test_op(
CatModel(dim=1),
(
torch.randn(8, 4, 16),
torch.randn(8, 8, 16),
torch.randn(8, 12, 16),
),
flow,
)

self._test_op(
CatModel(dim=2),
(
torch.randn(8, 12, 4),
torch.randn(8, 12, 8),
torch.randn(8, 12, 12),
),
flow,
)

def test_cat_broadcast(self, flow: TestFlow) -> None:
self._test_op(
CatModel(dim=0),
(
torch.randn(2, 16, 32),
torch.randn(4, 16, 32),
torch.randn(6, 16, 32),
),
flow,
)

self._test_op(
CatModel(dim=1),
(
torch.randn(8, 8, 16),
torch.randn(8, 16, 16),
torch.randn(8, 24, 16),
),
flow,
)

self._test_op(
CatModel(dim=2),
(
torch.randn(4, 16, 8),
torch.randn(4, 16, 16),
torch.randn(4, 16, 24),
),
flow,
)

def test_cat_same_shapes(self, flow: TestFlow) -> None:
self._test_op(
CatModel(),
(
torch.randn(8, 32),
torch.randn(8, 32),
torch.randn(8, 32),
),
flow,
)
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,
)
Loading
Loading