bd32e3cc9531dfc274fb7b4104106f9549579a1a
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / Relu.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/Relu.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 ReluTest : 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(ReluTest, FloatSimple)
40 {
41   std::vector<float> input_data{
42     0.0f, 1.0f,  3.0f,  // Row 1
43     1.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     1.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   Relu 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(ReluTest, Uint8Quantized)
66 {
67   std::vector<float> input_data{
68     0, -6, 2, 4, //
69     3, -2, 7, 1, //
70   };
71   // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
72   const float f_min = (-128.0 / 128.0) * 8;
73   const float f_max = (127.0 / 128.0) * 8;
74
75   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(f_min, f_max);
76   Tensor input_tensor = makeInputTensor<DataType::U8>(
77     {1, 2, 4, 1}, quant_param.first, quant_param.second, input_data, _memory_manager.get());
78   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
79
80   Relu kernel(&input_tensor, &output_tensor);
81   kernel.configure();
82   _memory_manager->allocate_memory(output_tensor);
83   kernel.execute();
84
85   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
86   EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
87               ::testing::ElementsAreArray({128, 128, 160, 192, 176, 128, 240, 144}));
88   EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({0, 0, 2, 4, 3, 0, 7, 1}));
89 }
90
91 TEST_F(ReluTest, Uint8Requantized)
92 {
93   std::vector<float> input_data{
94     0, -6, 2, 4, //
95     3, -2, 7, 1, //
96   };
97
98   // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
99   const float in_min = (-128.0 / 128.0) * 8;
100   const float in_max = (127.0 / 128.0) * 8;
101   const float out_min = (0.0 / 256.0) * 8;
102   const float out_max = (255.0 / 256.0) * 8;
103
104   std::pair<float, int32_t> quant_input = quantizationParams<uint8_t>(in_min, in_max);
105   Tensor input_tensor = makeInputTensor<DataType::U8>(
106     {1, 2, 4, 1}, quant_input.first, quant_input.second, input_data, _memory_manager.get());
107
108   std::pair<float, int32_t> quant_output = quantizationParams<uint8_t>(out_min, out_max);
109   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_output.first, quant_output.second);
110
111   Relu kernel(&input_tensor, &output_tensor);
112   kernel.configure();
113   _memory_manager->allocate_memory(output_tensor);
114   kernel.execute();
115
116   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
117   EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
118               ::testing::ElementsAreArray({0, 0, 64, 128, 96, 0, 224, 32}));
119   EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({0, 0, 2, 4, 3, 0, 7, 1}));
120 }
121
122 TEST_F(ReluTest, SInt16)
123 {
124   std::vector<float> input_data{
125     0, -6, 2, 4, //
126     3, -2, 7, 1, //
127   };
128   std::vector<float> ref_output_data{
129     0, 0, 2, 4, //
130     3, 0, 7, 1, //
131   };
132
133   Tensor input_tensor =
134     makeInputTensor<DataType::S16>({1, 2, 4, 1}, 0.5, 0, input_data, _memory_manager.get());
135   Tensor output_tensor = makeOutputTensor(DataType::S16, 0.25, 0);
136
137   Relu kernel(&input_tensor, &output_tensor);
138   kernel.configure();
139   _memory_manager->allocate_memory(output_tensor);
140   kernel.execute();
141
142   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
143   EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
144 }
145
146 TEST_F(ReluTest, Input_Output_Type_NEG)
147 {
148   Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
149   Tensor output_tensor = makeOutputTensor(DataType::U8);
150
151   Relu kernel(&input_tensor, &output_tensor);
152   EXPECT_ANY_THROW(kernel.configure());
153 }
154
155 TEST_F(ReluTest, Invalid_Input_Type_NEG)
156 {
157   Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1}, _memory_manager.get());
158   Tensor output_tensor = makeOutputTensor(DataType::S64);
159
160   Relu kernel(&input_tensor, &output_tensor);
161   kernel.configure();
162   _memory_manager->allocate_memory(output_tensor);
163   EXPECT_ANY_THROW(kernel.execute());
164 }
165
166 } // namespace
167 } // namespace kernels
168 } // namespace luci_interpreter