Skip to content

Commit 6870437

Browse files
chong-chen01Jiseong-oh
authored andcommitted
Add SamsungTester and build basic test pipeline
Add SamsungTester which provide basic function of lowering module. Add test for some common ops. Currently, export, partition, lowering to enn backend, to executorch are included, on-device test and evaluation is skipped. Outputs of command : python -m unittest discover backends/samsung/test/ops/ -p "test_*.py" ``` INFO:root:Find 1 subgraphs to partition and lowering. INFO:root:Visiting: aten_add_tensor, aten.add.Tensor WARNING: Logging before InitGoogleLogging() is written to STDERR .INFO:root:Find 1 subgraphs to partition and lowering. INFO:root:Visiting: aten_mul_tensor, aten.mul.Tensor . ---------------------------------------------------------------------- Ran 17 tests in 15.939s OK ``` Co-authored-by: chong-chen <[email protected]>
1 parent 07d9c61 commit 6870437

File tree

7 files changed

+453
-0
lines changed

7 files changed

+453
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
9+
import unittest
10+
11+
import torch
12+
13+
from executorch.backends.samsung.serialization.compile_options import (
14+
gen_samsung_backend_compile_spec,
15+
)
16+
from executorch.backends.samsung.test.tester import SamsungTester
17+
18+
19+
class Add(torch.nn.Module):
20+
def __init__(self) -> None:
21+
super().__init__()
22+
23+
def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
24+
return x + y
25+
26+
27+
class AddConstant(torch.nn.Module):
28+
def __init__(self, constant) -> None:
29+
super().__init__()
30+
self.constant = constant
31+
32+
def forward(self, x: torch.Tensor) -> torch.Tensor:
33+
return x + self.constant
34+
35+
36+
class TestAdd(unittest.TestCase):
37+
def _test(self, module: torch.nn.Module, inputs):
38+
tester = SamsungTester(
39+
module,
40+
inputs,
41+
[gen_samsung_backend_compile_spec("E9955")],
42+
)
43+
(
44+
tester.export()
45+
.check_count({"torch.ops.aten.add.Tensor": 1})
46+
.to_edge_transform_and_lower()
47+
.check_not(["executorch_exir_dialects_edge__ops_aten_add_Tensor"])
48+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
49+
.to_executorch()
50+
)
51+
52+
def test_fp32_simple_add(self):
53+
inputs = (torch.randn(1, 3, 8, 8), torch.randn(1, 3, 8, 8))
54+
self._test(Add(), inputs)
55+
56+
def test_fp32_const_add(self):
57+
inputs = (torch.randn(1, 3, 8, 8),)
58+
self._test(AddConstant(torch.randn(1, 3, 8, 8)), inputs)
59+
60+
def test_fp32_add_broadcast(self):
61+
inputs = (torch.randn(1, 1, 8, 8), torch.randn(1, 3, 8, 8))
62+
self._test(Add(), inputs)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
9+
import unittest
10+
11+
import torch
12+
13+
from executorch.backends.samsung.serialization.compile_options import (
14+
gen_samsung_backend_compile_spec,
15+
)
16+
from executorch.backends.samsung.test.tester import SamsungTester
17+
18+
19+
class AvgPool2d(torch.nn.Module):
20+
def __init__(
21+
self,
22+
kernel_size=2,
23+
stride=1,
24+
padding=0,
25+
) -> None:
26+
super().__init__()
27+
self.avg_pool = torch.nn.AvgPool2d(
28+
kernel_size=kernel_size,
29+
stride=stride,
30+
padding=padding,
31+
count_include_pad=False,
32+
ceil_mode=False,
33+
).to(torch.float)
34+
35+
def get_example_inputs(self) -> tuple[torch.Tensor]:
36+
input_1 = torch.randn(1, 16, 24, 24)
37+
return (input_1,)
38+
39+
def forward(self, x: torch.Tensor) -> torch.Tensor:
40+
return self.avg_pool(x)
41+
42+
43+
class TestAvgPool2d(unittest.TestCase):
44+
def _test(self, module: torch.nn.Module):
45+
tester = SamsungTester(
46+
module,
47+
module.get_example_inputs(),
48+
[gen_samsung_backend_compile_spec("E9955")],
49+
)
50+
(
51+
tester.export()
52+
.check_count({"torch.ops.aten.avg_pool2d.default": 1})
53+
.to_edge_transform_and_lower()
54+
.check_not(["executorch_exir_dialects_edge__ops_aten_avg_pool2d_default"])
55+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
56+
.to_executorch()
57+
)
58+
59+
def test_fp32_avg_pool2d(self):
60+
self._test(AvgPool2d())
61+
62+
def test_fp32_avg_pool2d_with_stride(self):
63+
self._test(AvgPool2d(stride=2))
64+
65+
def test_fp32_avg_pool2d_with_kernel_size(self):
66+
self._test(AvgPool2d(kernel_size=4))
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
9+
import unittest
10+
11+
import torch
12+
13+
from executorch.backends.samsung.serialization.compile_options import (
14+
gen_samsung_backend_compile_spec,
15+
)
16+
from executorch.backends.samsung.test.tester import SamsungTester
17+
18+
19+
class Conv2d(torch.nn.Module):
20+
def __init__(
21+
self,
22+
in_channels=3,
23+
out_channels=16,
24+
stride=(2, 2),
25+
padding=(1, 1),
26+
dilation=(1, 1),
27+
groups=1,
28+
bias=True,
29+
) -> None:
30+
super().__init__()
31+
self.conv = torch.nn.Conv2d(
32+
in_channels=in_channels,
33+
out_channels=out_channels,
34+
kernel_size=3,
35+
stride=stride,
36+
padding=padding,
37+
dilation=dilation,
38+
groups=groups,
39+
bias=bias,
40+
).to(torch.float)
41+
42+
self.in_channels = in_channels
43+
44+
def get_example_inputs(self) -> tuple[torch.Tensor]:
45+
input_1 = torch.randn(1, self.in_channels, 24, 24)
46+
return (input_1,)
47+
48+
def forward(self, x: torch.Tensor) -> torch.Tensor:
49+
return self.conv(x)
50+
51+
52+
class TransposeConv2d(torch.nn.Module):
53+
def __init__(self) -> None:
54+
super().__init__()
55+
self.conv = torch.nn.ConvTranspose2d(
56+
in_channels=32,
57+
out_channels=8,
58+
kernel_size=2,
59+
stride=(2, 2),
60+
padding=(0, 0),
61+
dilation=(1, 1),
62+
bias=True,
63+
)
64+
65+
def get_example_inputs(self) -> tuple[torch.Tensor]:
66+
input_1 = torch.randn(1, 32, 24, 24)
67+
return (input_1,)
68+
69+
def forward(self, x: torch.Tensor) -> torch.Tensor:
70+
return self.conv(x)
71+
72+
73+
class TestConv2d(unittest.TestCase):
74+
def _test(self, module: torch.nn.Module):
75+
tester = SamsungTester(
76+
module,
77+
module.get_example_inputs(),
78+
[gen_samsung_backend_compile_spec("E9955")],
79+
)
80+
(
81+
tester.export()
82+
.to_edge_transform_and_lower()
83+
.check_not(["executorch_exir_dialects_edge__ops_aten_convolution_default"])
84+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
85+
.to_executorch()
86+
)
87+
88+
def test_fp32_conv2d_without_bias(self):
89+
self._test(Conv2d(bias=False))
90+
91+
def test_fp32_conv2d_with_bias(self):
92+
self._test(Conv2d(bias=True))
93+
94+
def test_fp32_depthwise_conv2d(self):
95+
self._test(Conv2d(in_channels=8, out_channels=8, groups=8))
96+
97+
def test_fp32_transpose_conv2d(self):
98+
self._test(TransposeConv2d())
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
9+
import unittest
10+
11+
import torch
12+
13+
from executorch.backends.samsung.serialization.compile_options import (
14+
gen_samsung_backend_compile_spec,
15+
)
16+
from executorch.backends.samsung.test.tester import SamsungTester
17+
18+
19+
class MaxPool2d(torch.nn.Module):
20+
def __init__(
21+
self,
22+
kernel_size=2,
23+
stride=1,
24+
padding=0,
25+
dilation=1,
26+
) -> None:
27+
super().__init__()
28+
self.max_pool = torch.nn.MaxPool2d(
29+
kernel_size=kernel_size,
30+
stride=stride,
31+
padding=padding,
32+
dilation=dilation,
33+
return_indices=False,
34+
ceil_mode=False,
35+
).to(torch.float)
36+
37+
def get_example_inputs(self) -> tuple[torch.Tensor]:
38+
input_1 = torch.randn(1, 16, 24, 24)
39+
return (input_1,)
40+
41+
def forward(self, x: torch.Tensor) -> torch.Tensor:
42+
return self.max_pool(x)
43+
44+
45+
class TestMaxPool2d(unittest.TestCase):
46+
def _test(self, module: torch.nn.Module):
47+
tester = SamsungTester(
48+
module,
49+
module.get_example_inputs(),
50+
[gen_samsung_backend_compile_spec("E9955")],
51+
)
52+
(
53+
tester.export()
54+
.check_count({"torch.ops.aten.max_pool2d.default": 1})
55+
.to_edge_transform_and_lower()
56+
.check_not(["executorch_exir_dialects_edge__ops_aten_max_pool2d_default"])
57+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
58+
.to_executorch()
59+
)
60+
61+
def test_fp32_max_pool2d(self):
62+
self._test(MaxPool2d())
63+
64+
def test_fp32_max_pool2d_with_padding(self):
65+
self._test(MaxPool2d(padding=1))
66+
67+
def test_fp32_max_pool2d_with_kernel_size(self):
68+
self._test(MaxPool2d(kernel_size=4))
69+
70+
def test_fp32_max_pool2d_with_dilation(self):
71+
self._test(MaxPool2d(dilation=2))
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
9+
import unittest
10+
11+
import torch
12+
13+
from executorch.backends.samsung.serialization.compile_options import (
14+
gen_samsung_backend_compile_spec,
15+
)
16+
from executorch.backends.samsung.test.tester import SamsungTester
17+
18+
19+
class Mul(torch.nn.Module):
20+
def __init__(self) -> None:
21+
super().__init__()
22+
23+
def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
24+
return x * y
25+
26+
27+
class MulConstant(torch.nn.Module):
28+
def __init__(self, constant) -> None:
29+
super().__init__()
30+
self.constant = constant
31+
32+
def forward(self, x: torch.Tensor) -> torch.Tensor:
33+
return x * self.constant
34+
35+
36+
class TestMul(unittest.TestCase):
37+
def _test(self, module: torch.nn.Module, inputs):
38+
tester = SamsungTester(
39+
module,
40+
inputs,
41+
[gen_samsung_backend_compile_spec("E9955")],
42+
)
43+
(
44+
tester.export()
45+
.check_count({"torch.ops.aten.mul.Tensor": 1})
46+
.to_edge_transform_and_lower()
47+
.check_not(["executorch_exir_dialects_edge__ops_aten_mul_Tensor"])
48+
.check_count({"torch.ops.higher_order.executorch_call_delegate": 1})
49+
.to_executorch()
50+
)
51+
52+
def test_fp32_simple_mul(self):
53+
inputs = (torch.randn(1, 3, 8, 8), torch.randn(1, 3, 8, 8))
54+
self._test(Mul(), inputs)
55+
56+
def test_fp32_const_mul(self):
57+
inputs = (torch.randn(1, 3, 8, 8),)
58+
self._test(MulConstant(torch.randn(1, 3, 8, 8)), inputs)
59+
60+
def test_fp32_mul_broadcast(self):
61+
inputs = (torch.randn(1, 1, 8, 8), torch.randn(1, 3, 8, 8))
62+
self._test(Mul(), inputs)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) Samsung Electronics Co. LTD
2+
# All rights reserved
3+
#
4+
# Licensed under the BSD License (the "License"); you may not use this file
5+
# except in compliance with the License. See the license file in the root
6+
# directory of this source tree for more details.
7+
8+
from executorch.backends.samsung.test.tester.samsung_tester import SamsungTester
9+
10+
11+
__all__ = ["SamsungTester"]

0 commit comments

Comments
 (0)