Skip to content

Commit c876f6e

Browse files
committed
[Backend Tester] Add pointwise op tests
ghstack-source-id: 60a1de2 ghstack-comment-id: 3116316934 Pull-Request: #12854
1 parent 2de02d3 commit c876f6e

File tree

8 files changed

+1479
-0
lines changed

8 files changed

+1479
-0
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
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+
import torch
10+
from executorch.backends.test.suite.flow import TestFlow
11+
12+
from executorch.backends.test.suite.operators import (
13+
dtype_test,
14+
operator_test,
15+
OperatorTest,
16+
)
17+
18+
19+
class FloorDivideModel(torch.nn.Module):
20+
def __init__(self):
21+
super().__init__()
22+
23+
def forward(self, x, y):
24+
return torch.floor_divide(x, y)
25+
26+
27+
@operator_test
28+
class TestFloorDivide(OperatorTest):
29+
@dtype_test
30+
def test_floor_divide_dtype(self, flow: TestFlow, dtype) -> None:
31+
# Test with different dtypes
32+
model = FloorDivideModel().to(dtype)
33+
# Use values that won't cause division by zero
34+
x = torch.randint(-100, 100, (10, 10)).to(dtype)
35+
y = torch.full_like(x, 2) # Divisor of 2
36+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
37+
38+
def test_floor_divide_basic(self, flow: TestFlow) -> None:
39+
# Basic test with default parameters
40+
# Input: tensor with integer values, divisor: constant tensor
41+
x = torch.randint(-100, 100, (10, 10))
42+
y = torch.full_like(x, 2).clone() # Divisor of 2
43+
self._test_op(
44+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
45+
)
46+
47+
def test_floor_divide_scalar_divisors(self, flow: TestFlow) -> None:
48+
# Test with different scalar divisors as tensors
49+
50+
# Positive divisor
51+
x = torch.randint(-100, 100, (10, 10))
52+
y = torch.full_like(x, 3) # Divisor of 3
53+
self._test_op(
54+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
55+
)
56+
57+
# Negative divisor
58+
x = torch.randint(-100, 100, (10, 10))
59+
y = torch.full_like(x, -2) # Divisor of -2
60+
self._test_op(
61+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
62+
)
63+
64+
# Fractional divisor
65+
x = torch.randint(-100, 100, (10, 10)).float()
66+
y = torch.full_like(x, 2.5) # Divisor of 2.5
67+
self._test_op(
68+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
69+
)
70+
71+
# Large divisor
72+
x = torch.randint(-1000, 1000, (10, 10))
73+
y = torch.full_like(x, 100) # Divisor of 100
74+
self._test_op(
75+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
76+
)
77+
78+
# Small divisor
79+
x = torch.randint(-100, 100, (10, 10)).float()
80+
y = torch.full_like(x, 0.5) # Divisor of 0.5
81+
self._test_op(
82+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
83+
)
84+
85+
def test_floor_divide_tensor_divisors(self, flow: TestFlow) -> None:
86+
# Test with tensor divisors
87+
88+
# Constant divisor tensor
89+
x = torch.randint(-100, 100, (10, 10))
90+
y = torch.full_like(x, 2) # All elements are 2
91+
self._test_op(
92+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
93+
)
94+
95+
# Random divisor tensor (non-zero)
96+
x = torch.randint(-100, 100, (10, 10))
97+
y = torch.randint(1, 10, (10, 10)) # Positive divisors
98+
self._test_op(
99+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
100+
)
101+
102+
# Mixed positive and negative divisors
103+
x = torch.randint(-100, 100, (10, 10))
104+
y = torch.randint(-10, 10, (10, 10))
105+
# Replace zeros to avoid division by zero
106+
y[y == 0] = 1
107+
self._test_op(
108+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
109+
)
110+
111+
# Broadcasting: scalar dividend, tensor divisor
112+
x = torch.tensor([10])
113+
y = torch.arange(1, 5) # [1, 2, 3, 4]
114+
self._test_op(
115+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
116+
)
117+
118+
# Broadcasting: tensor dividend, scalar divisor
119+
x = torch.arange(-10, 10)
120+
y = torch.tensor([2])
121+
self._test_op(
122+
FloorDivideModel(), (x, y), flow, generate_random_test_inputs=False
123+
)
124+
125+
def test_floor_divide_shapes(self, flow: TestFlow) -> None:
126+
# Test with different tensor shapes
127+
model = FloorDivideModel()
128+
129+
# 1D tensor
130+
x = torch.randint(-100, 100, (20,))
131+
y = torch.full_like(x, 2) # Divisor of 2
132+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
133+
134+
# 2D tensor
135+
x = torch.randint(-100, 100, (5, 10))
136+
y = torch.full_like(x, 2) # Divisor of 2
137+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
138+
139+
# 3D tensor
140+
x = torch.randint(-100, 100, (3, 4, 5))
141+
y = torch.full_like(x, 2) # Divisor of 2
142+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
143+
144+
# 4D tensor
145+
x = torch.randint(-100, 100, (2, 3, 4, 5))
146+
y = torch.full_like(x, 2) # Divisor of 2
147+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
148+
149+
# 5D tensor
150+
x = torch.randint(-100, 100, (2, 2, 3, 4, 5))
151+
y = torch.full_like(x, 2) # Divisor of 2
152+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
153+
154+
def test_floor_divide_values(self, flow: TestFlow) -> None:
155+
# Test with different value ranges
156+
model = FloorDivideModel()
157+
158+
# Test with specific dividend values
159+
x = torch.tensor([-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7])
160+
161+
# Divide by 2
162+
y = torch.tensor([2]).expand_as(x).clone()
163+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
164+
165+
# Divide by -2
166+
y = torch.tensor([-2]).expand_as(x).clone()
167+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
168+
169+
# Divide by 3
170+
y = torch.tensor([3]).expand_as(x).clone()
171+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
172+
173+
# Divide by -3
174+
y = torch.tensor([-3]).expand_as(x).clone()
175+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
176+
177+
# Test with floating point values
178+
x = torch.tensor(
179+
[-3.8, -3.5, -3.2, -0.8, -0.5, -0.2, 0.0, 0.2, 0.5, 0.8, 3.2, 3.5, 3.8]
180+
)
181+
182+
# Divide by 2.0
183+
y = torch.tensor([2.0]).expand_as(x).clone()
184+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
185+
186+
# Divide by -2.0
187+
y = torch.tensor([-2.0]).expand_as(x).clone()
188+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
189+
190+
def test_floor_divide_edge_cases(self, flow: TestFlow) -> None:
191+
# Test edge cases
192+
model = FloorDivideModel()
193+
194+
# Zero dividend
195+
x = torch.zeros(10)
196+
y = torch.full_like(x, 2)
197+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
198+
199+
# Division that results in exact integers
200+
x = torch.tensor([0, 2, 4, 6, 8, 10])
201+
y = torch.full_like(x, 2)
202+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
203+
204+
# Division with remainder
205+
x = torch.tensor([1, 3, 5, 7, 9])
206+
y = torch.full_like(x, 2)
207+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
208+
209+
# Tensor with infinity
210+
x = torch.tensor([float("inf"), float("-inf"), 10.0, -10.0])
211+
y = torch.full_like(x, 2)
212+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
213+
214+
# Tensor with NaN
215+
x = torch.tensor([float("nan"), 10.0, -10.0])
216+
y = torch.full_like(x, 2)
217+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
218+
219+
# Very large values
220+
x = torch.tensor([1e10, -1e10])
221+
y = torch.full_like(x, 3)
222+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
223+
224+
# Very small values
225+
x = torch.tensor([1e-10, -1e-10])
226+
y = torch.full_like(x, 2)
227+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
228+
229+
def test_floor_divide_scalar(self, flow: TestFlow) -> None:
230+
# Test with scalar input (1-element tensor)
231+
model = FloorDivideModel()
232+
233+
# Positive dividend, positive divisor
234+
x = torch.tensor([7])
235+
y = torch.tensor([2])
236+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
237+
238+
# Negative dividend, positive divisor
239+
x = torch.tensor([-7])
240+
y = torch.tensor([2])
241+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
242+
243+
# Zero dividend
244+
x = torch.tensor([0])
245+
y = torch.tensor([2])
246+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
247+
248+
# Positive dividend, negative divisor
249+
x = torch.tensor([7])
250+
y = torch.tensor([-2])
251+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)
252+
253+
# Negative dividend, negative divisor
254+
x = torch.tensor([-7])
255+
y = torch.tensor([-2])
256+
self._test_op(model, (x, y), flow, generate_random_test_inputs=False)

0 commit comments

Comments
 (0)