2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3 * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include "kernels/GreaterEqual.h"
19 #include "kernels/TestUtils.h"
20 #include "luci_interpreter/TestMemoryManager.h"
22 namespace luci_interpreter
29 using namespace testing;
31 class GreaterEqualTest : public ::testing::Test
34 void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
36 std::unique_ptr<IMemoryManager> _memory_manager;
39 TEST_F(GreaterEqualTest, FloatSimple)
41 std::vector<float> x_data{
42 0.5, 0.7, 0.9, // Row 1
46 std::vector<float> y_data{
47 0.9, 0.7, 0.5, // Row 1
51 std::vector<bool> ref_output_data{
52 false, true, true, // Row 1
53 true, true, false, // Row 2
56 Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data, _memory_manager.get());
57 Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data, _memory_manager.get());
58 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
60 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
62 _memory_manager->allocate_memory(output_tensor);
65 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
66 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
69 TEST_F(GreaterEqualTest, FloatBroardcast)
71 std::vector<float> x_data{
72 0.5, 0.7, 0.9, // Row 1
77 std::vector<float> y_data{
78 0.9, 0.7, 0.5, // Row 1
81 std::vector<bool> ref_output_data{
82 false, true, true, // Row 1
83 true, false, false, // Row 2
84 false, false, true, // Row 3
87 Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, x_data, _memory_manager.get());
88 Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data, _memory_manager.get());
89 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
91 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
93 _memory_manager->allocate_memory(output_tensor);
96 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
97 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3, 3}));
99 template <loco::DataType DType>
100 void checkIntegerSimple(luci_interpreter::IMemoryManager *memory_manager)
102 using dtype = typename loco::DataTypeImpl<DType>::Type;
103 dtype min_value = std::numeric_limits<dtype>::min();
104 dtype max_value = std::numeric_limits<dtype>::max();
105 std::vector<dtype> x_data{min_value, 2, max_value};
107 std::vector<dtype> y_data{min_value + 1, -2, max_value};
109 std::vector<bool> ref_output_data{false, true, true};
111 Tensor x_tensor = makeInputTensor<DType>({3}, x_data, memory_manager);
112 Tensor y_tensor = makeInputTensor<DType>({3}, y_data, memory_manager);
113 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
115 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
117 memory_manager->allocate_memory(output_tensor);
120 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
121 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3}));
124 template <loco::DataType DType>
125 void checkIntegerBroadcast(luci_interpreter::IMemoryManager *memory_manager)
127 using dtype = typename loco::DataTypeImpl<DType>::Type;
128 dtype min_value = std::numeric_limits<dtype>::min();
129 dtype max_value = std::numeric_limits<dtype>::max();
130 std::vector<dtype> x_data{
131 min_value, 2, 3, // Row 1
132 4, 5, max_value, // Row 2
134 min_value, -2, max_value - 1, // Row 4
137 std::vector<dtype> y_data{
138 min_value + 1, -2, max_value - 1, // Row 1
141 std::vector<bool> ref_output_data{
142 false, true, false, // Row 1
143 true, true, true, // Row 2
144 true, false, false, // Row 3
145 false, true, true, // Row 4
148 Tensor x_tensor = makeInputTensor<DType>({4, 3}, x_data, memory_manager);
149 Tensor y_tensor = makeInputTensor<DType>({3}, y_data, memory_manager);
150 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
152 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
154 memory_manager->allocate_memory(output_tensor);
157 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
158 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({4, 3}));
161 TEST_F(GreaterEqualTest, Int32)
163 checkIntegerSimple<loco::DataType::S32>(_memory_manager.get());
164 checkIntegerBroadcast<loco::DataType::S32>(_memory_manager.get());
168 TEST_F(GreaterEqualTest, Int64)
170 checkIntegerSimple<loco::DataType::S64>(_memory_manager.get());
171 checkIntegerBroadcast<loco::DataType::S64>(_memory_manager.get());
175 // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
176 const float F_MIN = -128.0 / 128.0;
177 const float F_MAX = 127.0 / 128.0;
179 TEST_F(GreaterEqualTest, Uint8Quantized)
181 std::vector<float> x_data{
182 0.5, 0.6, 0.7, 0.9, // Row 1
183 1, 0, 0.05, -1, // Row 2
186 std::vector<float> y_data{
187 0.9, 0.6, 0.55, 0.5, // Row 1
188 -1, 0.05, 0, 1, // Row 2
191 std::vector<bool> ref_output_data{
192 false, true, true, true, // Row 1
193 true, false, true, false, // Row 2
196 std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
197 Tensor x_tensor = makeInputTensor<DataType::U8>(
198 {1, 2, 4, 1}, quant_param.first, quant_param.second, x_data, _memory_manager.get());
199 Tensor y_tensor = makeInputTensor<DataType::U8>(
200 {1, 2, 4, 1}, quant_param.first, quant_param.second, y_data, _memory_manager.get());
201 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
203 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
205 _memory_manager->allocate_memory(output_tensor);
208 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
209 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
212 TEST_F(GreaterEqualTest, Uint8QuantizedRescale)
214 std::vector<float> x_data{
215 0.5, 0.5, 0.7, 0.9, // Row 1
216 1, 0, 0.05, -1, // Row 2
219 std::vector<float> y_data{
220 0.9, 0.5, 0.6, 0.5, // Row 1
221 -1, 0.05, 0, 1, // Row 2
224 std::vector<bool> ref_output_data{
225 false, true, true, true, // Row 1
226 true, false, true, false, // Row 2
229 std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
230 std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 1.2, F_MAX * 1.5);
232 Tensor x_tensor = makeInputTensor<DataType::U8>(
233 {1, 2, 4, 1}, x_quant_param.first, x_quant_param.second, x_data, _memory_manager.get());
234 Tensor y_tensor = makeInputTensor<DataType::U8>(
235 {1, 2, 4, 1}, y_quant_param.first, y_quant_param.second, y_data, _memory_manager.get());
236 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
238 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
240 _memory_manager->allocate_memory(output_tensor);
243 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
244 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
247 TEST_F(GreaterEqualTest, Uint8QuantizedBroadcast)
249 std::vector<float> x_data{
250 0.4, -0.8, 0.7, 0.3, // Row 1
251 -0.5, 0.1, 0, 0.5, // Row 2
252 1, 0, 0.05, -1, // Row 3
255 std::vector<float> y_data{
256 -1, 0.05, 0, 1, // Row 1
259 std::vector<bool> ref_output_data{
260 true, false, true, false, // Row 1
261 true, true, true, false, // Row 2
262 true, false, true, false, // Row 3
265 std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
266 Tensor x_tensor = makeInputTensor<DataType::U8>(
267 {1, 3, 4, 1}, quant_param.first, quant_param.second, x_data, _memory_manager.get());
268 Tensor y_tensor = makeInputTensor<DataType::U8>(
269 {1, 1, 4, 1}, quant_param.first, quant_param.second, y_data, _memory_manager.get());
270 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
272 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
274 _memory_manager->allocate_memory(output_tensor);
277 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 3, 4, 1}));
278 EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
281 TEST_F(GreaterEqualTest, Input_Type_Mismatch_NEG)
283 Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
284 Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1}, _memory_manager.get());
285 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
287 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
288 EXPECT_ANY_THROW(kernel.configure());
291 TEST_F(GreaterEqualTest, Input_Output_Type_NEG)
293 Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
294 Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
295 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
297 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
298 EXPECT_ANY_THROW(kernel.configure());
301 TEST_F(GreaterEqualTest, Float_Broadcast_NEG)
303 Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2}, {1.f, 2.f}, _memory_manager.get());
304 Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({3}, {1.f, 2.f, 3.f}, _memory_manager.get());
305 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
307 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
308 EXPECT_ANY_THROW(kernel.configure());
311 TEST_F(GreaterEqualTest, Int32_Broadcast_NEG)
313 Tensor x_tensor = makeInputTensor<DataType::S32>({2}, {1, 2}, _memory_manager.get());
314 Tensor y_tensor = makeInputTensor<DataType::S32>({3}, {1, 2, 3}, _memory_manager.get());
315 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
317 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
318 EXPECT_ANY_THROW(kernel.configure());
321 TEST_F(GreaterEqualTest, Int64_Broadcast_NEG)
323 Tensor x_tensor = makeInputTensor<DataType::S64>({2}, {1, 2}, _memory_manager.get());
324 Tensor y_tensor = makeInputTensor<DataType::S64>({3}, {1, 2, 3}, _memory_manager.get());
325 Tensor output_tensor = makeOutputTensor(DataType::BOOL);
327 GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
328 EXPECT_ANY_THROW(kernel.configure());
332 } // namespace kernels
333 } // namespace luci_interpreter