Skip to content

Commit 13f6155

Browse files
committed
[Backend Tester] Add more pointwise op tests
ghstack-source-id: be6e7b1 ghstack-comment-id: 3116317028 Pull-Request: #12855
1 parent df4948a commit 13f6155

File tree

9 files changed

+541
-0
lines changed

9 files changed

+541
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class AbsModel(torch.nn.Module):
21+
def __init__(self):
22+
super().__init__()
23+
24+
def forward(self, x):
25+
return torch.abs(x)
26+
27+
28+
@operator_test
29+
class TestAbs(OperatorTest):
30+
@dtype_test
31+
def test_abs_dtype(self, flow: TestFlow, dtype) -> None:
32+
# Test with different dtypes
33+
model = AbsModel().to(dtype)
34+
self._test_op(model, (torch.rand(10, 10).to(dtype) * 2 - 1,), flow)
35+
36+
def test_abs_shapes(self, flow: TestFlow) -> None:
37+
# Test with different tensor shapes
38+
39+
# 1D tensor
40+
self._test_op(AbsModel(), (torch.randn(20),), flow)
41+
42+
# 2D tensor
43+
self._test_op(AbsModel(), (torch.randn(5, 10),), flow)
44+
45+
# 3D tensor
46+
self._test_op(AbsModel(), (torch.randn(3, 4, 5),), flow)
47+
48+
def test_abs_edge_cases(self, flow: TestFlow) -> None:
49+
# Test edge cases
50+
51+
# Tensor with infinity
52+
x = torch.tensor([float("inf"), float("-inf"), 1.0, -1.0])
53+
self._test_op(AbsModel(), (x,), flow, generate_random_test_inputs=False)
54+
55+
# Tensor with NaN
56+
x = torch.tensor([float("nan"), 1.0, -1.0])
57+
self._test_op(AbsModel(), (x,), flow, generate_random_test_inputs=False)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class CeilModel(torch.nn.Module):
21+
def __init__(self):
22+
super().__init__()
23+
24+
def forward(self, x):
25+
return torch.ceil(x)
26+
27+
28+
@operator_test
29+
class TestCeil(OperatorTest):
30+
@dtype_test
31+
def test_ceil_dtype(self, flow: TestFlow, dtype) -> None:
32+
# Test with different dtypes
33+
model = CeilModel().to(dtype)
34+
self._test_op(model, (torch.rand(10, 10).to(dtype) * 2 - 1,), flow)
35+
36+
def test_ceil_shapes(self, flow: TestFlow) -> None:
37+
# Test with different tensor shapes
38+
39+
# 1D tensor
40+
self._test_op(CeilModel(), (torch.randn(20),), flow)
41+
42+
# 2D tensor
43+
self._test_op(CeilModel(), (torch.randn(5, 10),), flow)
44+
45+
# 3D tensor
46+
self._test_op(CeilModel(), (torch.randn(3, 4, 5),), flow)
47+
48+
def test_ceil_edge_cases(self, flow: TestFlow) -> None:
49+
# Test edge cases
50+
51+
# Tensor with infinity
52+
x = torch.tensor([float("inf"), float("-inf"), 1.0, -1.0])
53+
self._test_op(CeilModel(), (x,), flow, generate_random_test_inputs=False)
54+
55+
# Tensor with NaN
56+
x = torch.tensor([float("nan"), 1.0, -1.0])
57+
self._test_op(CeilModel(), (x,), flow, generate_random_test_inputs=False)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class ClampModel(torch.nn.Module):
21+
def __init__(self, min_val=None, max_val=None):
22+
super().__init__()
23+
self.min_val = min_val
24+
self.max_val = max_val
25+
26+
def forward(self, x):
27+
return torch.clamp(x, min=self.min_val, max=self.max_val)
28+
29+
30+
@operator_test
31+
class TestClamp(OperatorTest):
32+
@dtype_test
33+
def test_clamp_dtype(self, flow: TestFlow, dtype) -> None:
34+
# Test with different dtypes
35+
model = ClampModel(min_val=-0.5, max_val=0.5).to(dtype)
36+
self._test_op(model, (torch.rand(10, 10).to(dtype) * 2 - 1,), flow)
37+
38+
def test_clamp_min_only(self, flow: TestFlow) -> None:
39+
# Test with only min value specified
40+
self._test_op(ClampModel(min_val=0.0), (torch.randn(10, 10),), flow)
41+
42+
def test_clamp_max_only(self, flow: TestFlow) -> None:
43+
# Test with only max value specified
44+
self._test_op(ClampModel(max_val=0.0), (torch.randn(10, 10),), flow)
45+
46+
def test_clamp_shapes(self, flow: TestFlow) -> None:
47+
# Test with different tensor shapes
48+
model = ClampModel(min_val=-1.0, max_val=1.0)
49+
50+
# 1D tensor
51+
self._test_op(model, (torch.randn(20),), flow)
52+
53+
# 2D tensor
54+
self._test_op(model, (torch.randn(5, 10),), flow)
55+
56+
# 3D tensor
57+
self._test_op(model, (torch.randn(3, 4, 5),), flow)
58+
59+
def test_clamp_edge_cases(self, flow: TestFlow) -> None:
60+
# Test edge cases
61+
62+
# Min equals max
63+
self._test_op(
64+
ClampModel(min_val=0.0, max_val=0.0), (torch.randn(10, 10),), flow
65+
)
66+
67+
# Tensor with infinity
68+
x = torch.tensor([float("inf"), float("-inf"), 1.0, -1.0])
69+
self._test_op(
70+
ClampModel(min_val=-2.0, max_val=2.0),
71+
(x,),
72+
flow,
73+
generate_random_test_inputs=False,
74+
)
75+
76+
# Tensor with NaN
77+
x = torch.tensor([float("nan"), 1.0, -1.0])
78+
self._test_op(
79+
ClampModel(min_val=-2.0, max_val=2.0),
80+
(x,),
81+
flow,
82+
generate_random_test_inputs=False,
83+
)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class ExpModel(torch.nn.Module):
21+
def __init__(self):
22+
super().__init__()
23+
24+
def forward(self, x):
25+
return torch.exp(x)
26+
27+
28+
@operator_test
29+
class TestExp(OperatorTest):
30+
@dtype_test
31+
def test_exp_dtype(self, flow: TestFlow, dtype) -> None:
32+
# Test with different dtypes
33+
model = ExpModel().to(dtype)
34+
# Use smaller range to avoid overflow
35+
self._test_op(model, (torch.rand(10, 10).to(dtype) * 4 - 2,), flow)
36+
37+
def test_exp_shapes(self, flow: TestFlow) -> None:
38+
# Test with different tensor shapes
39+
40+
# 1D tensor
41+
self._test_op(ExpModel(), (torch.randn(20),), flow)
42+
43+
# 2D tensor
44+
self._test_op(ExpModel(), (torch.randn(5, 10),), flow)
45+
46+
# 3D tensor
47+
self._test_op(ExpModel(), (torch.randn(3, 4, 5),), flow)
48+
49+
def test_exp_edge_cases(self, flow: TestFlow) -> None:
50+
# Test edge cases
51+
52+
# Tensor with infinity
53+
x = torch.tensor([float("inf"), float("-inf"), 1.0, -1.0])
54+
self._test_op(ExpModel(), (x,), flow, generate_random_test_inputs=False)
55+
56+
# Tensor with NaN
57+
x = torch.tensor([float("nan"), 1.0, -1.0])
58+
self._test_op(ExpModel(), (x,), flow, generate_random_test_inputs=False)
59+
60+
# Overflow
61+
x = torch.tensor([10e10])
62+
self._test_op(ExpModel(), (x,), flow, generate_random_test_inputs=False)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class FloorModel(torch.nn.Module):
21+
def __init__(self):
22+
super().__init__()
23+
24+
25+
@operator_test
26+
class TestFloor(OperatorTest):
27+
@dtype_test
28+
def test_floor_dtype(self, flow: TestFlow, dtype) -> None:
29+
# Test with different dtypes
30+
model = FloorModel().to(dtype)
31+
self._test_op(model, (torch.rand(10, 10).to(dtype) * 2 - 1,), flow)
32+
33+
def test_floor_shapes(self, flow: TestFlow) -> None:
34+
# Test with different tensor shapes
35+
36+
# 1D tensor
37+
self._test_op(FloorModel(), (torch.randn(20),), flow)
38+
39+
# 2D tensor
40+
self._test_op(FloorModel(), (torch.randn(5, 10),), flow)
41+
42+
# 3D tensor
43+
self._test_op(FloorModel(), (torch.randn(3, 4, 5),), flow)
44+
45+
def test_floor_edge_cases(self, flow: TestFlow) -> None:
46+
# Test edge cases
47+
48+
# Tensor with infinity
49+
x = torch.tensor([float("inf"), float("-inf"), 1.0, -1.0])
50+
self._test_op(FloorModel(), (x,), flow, generate_random_test_inputs=False)
51+
52+
# Tensor with NaN
53+
x = torch.tensor([float("nan"), 1.0, -1.0])
54+
self._test_op(FloorModel(), (x,), flow, generate_random_test_inputs=False)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
10+
import torch
11+
from executorch.backends.test.suite.flow import TestFlow
12+
13+
from executorch.backends.test.suite.operators import (
14+
dtype_test,
15+
operator_test,
16+
OperatorTest,
17+
)
18+
19+
20+
class LogModel(torch.nn.Module):
21+
def __init__(self):
22+
super().__init__()
23+
24+
def forward(self, x):
25+
return torch.log(x)
26+
27+
28+
@operator_test
29+
class TestLog(OperatorTest):
30+
@dtype_test
31+
def test_log_dtype(self, flow: TestFlow, dtype) -> None:
32+
# Test with different dtypes
33+
model = LogModel().to(dtype)
34+
# Use positive values only for log
35+
self._test_op(model, (torch.rand(10, 10).to(dtype) + 0.01,), flow)
36+
37+
def test_log_shapes(self, flow: TestFlow) -> None:
38+
# Test with different tensor shapes
39+
40+
# 1D tensor
41+
self._test_op(LogModel(), (torch.rand(20) + 0.01,), flow)
42+
43+
# 2D tensor
44+
self._test_op(LogModel(), (torch.rand(5, 10) + 0.01,), flow)
45+
46+
# 3D tensor
47+
self._test_op(LogModel(), (torch.rand(3, 4, 5) + 0.01,), flow)
48+
49+
def test_log_edge_cases(self, flow: TestFlow) -> None:
50+
# Test edge cases
51+
# Tensor with infinity
52+
x = torch.tensor([float("inf"), 1.0, 2.0])
53+
self._test_op(LogModel(), (x,), flow, generate_random_test_inputs=False)
54+
55+
# Tensor with NaN
56+
x = torch.tensor([float("nan"), 1.0, 2.0])
57+
self._test_op(LogModel(), (x,), flow, generate_random_test_inputs=False)

0 commit comments

Comments
 (0)