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/Relu6.h"
19 #include "kernels/TestUtils.h"
20 #include "luci_interpreter/TestMemoryManager.h"
22 namespace luci_interpreter
29 using namespace testing;
31 class Relu6Test : public ::testing::Test
34 void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
36 std::unique_ptr<IMemoryManager> _memory_manager;
39 TEST_F(Relu6Test, FloatSimple)
41 std::vector<float> input_data{
42 0.0f, 1.0f, 3.0f, // Row 1
43 7.0f, -1.0f, -2.0f, // Row 2
46 std::vector<float> ref_output_data{
47 0.0f, 1.0f, 3.0f, // Row 1
48 6.0f, 0.0f, 0.0f, // Row 2
52 makeInputTensor<DataType::FLOAT32>({2, 3}, input_data, _memory_manager.get());
53 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
55 Relu6 kernel(&input_tensor, &output_tensor);
57 _memory_manager->allocate_memory(output_tensor);
60 EXPECT_THAT(extractTensorData<float>(output_tensor),
61 ::testing::ElementsAreArray(ref_output_data));
62 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
65 TEST_F(Relu6Test, Uint8Quantized)
67 // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
68 const float f_min = (-128.0 / 128.0) * 10;
69 const float f_max = (127.0 / 128.0) * 10;
70 const float tolerance = (f_max - f_min) / 255.0;
72 std::vector<float> input_data{
77 std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(f_min, f_max);
78 Tensor input_tensor = makeInputTensor<DataType::U8>(
79 {1, 2, 4, 1}, quant_param.first, quant_param.second, input_data, _memory_manager.get());
80 Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
82 Relu6 kernel(&input_tensor, &output_tensor);
84 _memory_manager->allocate_memory(output_tensor);
87 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
88 EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
89 ::testing::ElementsAreArray({128, 128, 154, 205, 128, 166, 205, 141}));
90 EXPECT_THAT(dequantizeTensorData(output_tensor),
91 FloatArrayNear({0, 0, 2, 6, 0, 3, 6, 1}, tolerance));
94 TEST_F(Relu6Test, Uint8Requantized)
96 // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
97 const float in_min = (-128.0 / 128.0) * 10;
98 const float in_max = (127.0 / 128.0) * 10;
99 const float out_min = (0.0 / 256.0) * 0;
100 const float out_max = (255.0 / 256.0) * 6;
101 const float tolerance = (in_max - in_min) / 255.0;
103 std::vector<float> input_data{
108 std::pair<float, int32_t> quant_input = quantizationParams<uint8_t>(in_min, in_max);
109 Tensor input_tensor = makeInputTensor<DataType::U8>(
110 {1, 2, 4, 1}, quant_input.first, quant_input.second, input_data, _memory_manager.get());
112 std::pair<float, int32_t> quant_output = quantizationParams<uint8_t>(out_min, out_max);
113 Tensor output_tensor = makeOutputTensor(DataType::U8, quant_output.first, quant_output.second);
115 Relu6 kernel(&input_tensor, &output_tensor);
117 _memory_manager->allocate_memory(output_tensor);
120 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
121 EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
122 ::testing::ElementsAreArray({0, 0, 87, 255, 0, 127, 255, 43}));
123 EXPECT_THAT(dequantizeTensorData(output_tensor),
124 FloatArrayNear({0, 0, 2, 6, 0, 3, 6, 1}, tolerance));
127 TEST_F(Relu6Test, Input_Output_Type_NEG)
129 Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
130 Tensor output_tensor = makeOutputTensor(DataType::U8);
132 Relu6 kernel(&input_tensor, &output_tensor);
133 EXPECT_ANY_THROW(kernel.configure());
136 TEST_F(Relu6Test, Invalid_Input_Type_NEG)
138 Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1}, _memory_manager.get());
139 Tensor output_tensor = makeOutputTensor(DataType::S64);
141 Relu6 kernel(&input_tensor, &output_tensor);
143 _memory_manager->allocate_memory(output_tensor);
144 EXPECT_ANY_THROW(kernel.execute());
148 } // namespace kernels
149 } // namespace luci_interpreter