af7b3f3dbb7c1493315038e40eeede994811b2d5
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / Relu6.test.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
4  *
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
8  *
9  *    http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 #include "kernels/Relu6.h"
19 #include "kernels/TestUtils.h"
20 #include "luci_interpreter/TestMemoryManager.h"
21
22 namespace luci_interpreter
23 {
24 namespace kernels
25 {
26 namespace
27 {
28
29 using namespace testing;
30
31 class Relu6Test : public ::testing::Test
32 {
33 protected:
34   void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
35
36   std::unique_ptr<IMemoryManager> _memory_manager;
37 };
38
39 TEST_F(Relu6Test, FloatSimple)
40 {
41   std::vector<float> input_data{
42     0.0f, 1.0f,  3.0f,  // Row 1
43     7.0f, -1.0f, -2.0f, // Row 2
44   };
45
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
49   };
50
51   Tensor input_tensor =
52     makeInputTensor<DataType::FLOAT32>({2, 3}, input_data, _memory_manager.get());
53   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
54
55   Relu6 kernel(&input_tensor, &output_tensor);
56   kernel.configure();
57   _memory_manager->allocate_memory(output_tensor);
58   kernel.execute();
59
60   EXPECT_THAT(extractTensorData<float>(output_tensor),
61               ::testing::ElementsAreArray(ref_output_data));
62   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
63 }
64
65 TEST_F(Relu6Test, Uint8Quantized)
66 {
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;
71
72   std::vector<float> input_data{
73     0,  -6, 2, 8, //
74     -2, 3,  7, 1, //
75   };
76
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);
81
82   Relu6 kernel(&input_tensor, &output_tensor);
83   kernel.configure();
84   _memory_manager->allocate_memory(output_tensor);
85   kernel.execute();
86
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));
92 }
93
94 TEST_F(Relu6Test, Uint8Requantized)
95 {
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;
102
103   std::vector<float> input_data{
104     0,  -6, 2, 8, //
105     -2, 3,  7, 1, //
106   };
107
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());
111
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);
114
115   Relu6 kernel(&input_tensor, &output_tensor);
116   kernel.configure();
117   _memory_manager->allocate_memory(output_tensor);
118   kernel.execute();
119
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));
125 }
126
127 TEST_F(Relu6Test, Input_Output_Type_NEG)
128 {
129   Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
130   Tensor output_tensor = makeOutputTensor(DataType::U8);
131
132   Relu6 kernel(&input_tensor, &output_tensor);
133   EXPECT_ANY_THROW(kernel.configure());
134 }
135
136 TEST_F(Relu6Test, Invalid_Input_Type_NEG)
137 {
138   Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1}, _memory_manager.get());
139   Tensor output_tensor = makeOutputTensor(DataType::S64);
140
141   Relu6 kernel(&input_tensor, &output_tensor);
142   kernel.configure();
143   _memory_manager->allocate_memory(output_tensor);
144   EXPECT_ANY_THROW(kernel.execute());
145 }
146
147 } // namespace
148 } // namespace kernels
149 } // namespace luci_interpreter