021d68d068230db38054512823e241ffcf63fde7
[platform/core/ml/nnfw.git] / compiler / luci-interpreter / src / kernels / Div.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/Div.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 DivTest : 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 float GetTolerance(float min, float max)
40 {
41   const float kQuantizedStep = (max - min) / 255.0f;
42   const float kQuantizedTolerance = 2.0f * kQuantizedStep + kQuantizedStep * kQuantizedStep;
43   return kQuantizedTolerance;
44 }
45
46 TEST_F(DivTest, Float)
47 {
48   Shape base_shape = {2, 3, 1, 1};
49
50   std::vector<int32_t> output_shape = {2, 3, 1, 1};
51
52   std::vector<float> input1_data{0.3f, 2.3f, 0.9f, 0.5f, 0.8f, 1.1f};
53   std::vector<float> input2_data{0.2f, 1.6f, 0.5f, 0.4f, 1.6f, 0.4f};
54   std::vector<float> test_outputs{1.5f, 1.4375f, 1.8f, 1.25f, 0.5f, 2.75f};
55
56   Tensor input1_tensor =
57     makeInputTensor<DataType::FLOAT32>(base_shape, input1_data, _memory_manager.get());
58   Tensor input2_tensor =
59     makeInputTensor<DataType::FLOAT32>(base_shape, input2_data, _memory_manager.get());
60
61   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
62
63   DivParams params{};
64   params.activation = Activation::RELU;
65
66   Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
67   kernel.configure();
68   _memory_manager->allocate_memory(output_tensor);
69   kernel.execute();
70
71   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
72   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
73 }
74
75 TEST_F(DivTest, FloatBroadcast)
76 {
77   Shape input1_shape = {1, 3};
78   Shape input2_shape = {3, 1};
79
80   std::vector<float> input1_data{-0.3f, 2.3f, 0.9f};
81   std::vector<float> input2_data{0.2f, 1.6f, 0.5f};
82   std::vector<float> test_outputs{0.f, 11.5f, 4.5f, 0.f, 1.4375f, 0.5625f, 0.f, 4.6f, 1.8f};
83
84   Tensor input1_tensor =
85     makeInputTensor<DataType::FLOAT32>(input1_shape, input1_data, _memory_manager.get());
86   Tensor input2_tensor =
87     makeInputTensor<DataType::FLOAT32>(input2_shape, input2_data, _memory_manager.get());
88
89   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
90
91   DivParams params{};
92   params.activation = Activation::RELU;
93
94   Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
95   kernel.configure();
96   _memory_manager->allocate_memory(output_tensor);
97   kernel.execute();
98
99   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
100 }
101
102 TEST_F(DivTest, Uint8)
103 {
104   Shape base_shape = {1, 2, 2, 1};
105
106   std::vector<int32_t> output_shape = {1, 2, 2, 1};
107
108   std::vector<float> input1_data = {-0.8f, -0.2f, 0.3f, 0.7f};
109   std::vector<float> input2_data = {-0.8f, 0.4f, 0.8f, 1.0f};
110   std::vector<float> test_outputs{1.0f, 0.f, 0.375f, 0.7f};
111
112   const float kQuantizedTolerance = GetTolerance(-1.0, 1.0);
113
114   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.f, 1.f);
115
116   Tensor input1_tensor = makeInputTensor<DataType::U8>(
117     base_shape, quant_param.first, quant_param.second, input1_data, _memory_manager.get());
118   Tensor input2_tensor = makeInputTensor<DataType::U8>(
119     base_shape, quant_param.first, quant_param.second, input2_data, _memory_manager.get());
120
121   Tensor output_tensor =
122     makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
123
124   DivParams params{};
125   params.activation = Activation::RELU;
126
127   Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
128   kernel.configure();
129   _memory_manager->allocate_memory(output_tensor);
130   kernel.execute();
131
132   EXPECT_THAT(dequantizeTensorData(output_tensor),
133               FloatArrayNear(test_outputs, kQuantizedTolerance));
134   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
135 }
136
137 TEST_F(DivTest, Input_Output_Type_NEG)
138 {
139   Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f}, _memory_manager.get());
140   Tensor input2_tensor = makeInputTensor<DataType::S32>({1}, {2}, _memory_manager.get());
141   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
142
143   DivParams params{};
144   params.activation = Activation::RELU;
145
146   Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
147   EXPECT_ANY_THROW(kernel.configure());
148 }
149
150 TEST_F(DivTest, Invalid_Input_Type_NEG)
151 {
152   Tensor input1_tensor = makeInputTensor<DataType::S64>({1}, {1}, _memory_manager.get());
153   Tensor input2_tensor = makeInputTensor<DataType::S64>({1}, {2}, _memory_manager.get());
154   Tensor output_tensor = makeOutputTensor(DataType::S64);
155
156   DivParams params{};
157   params.activation = Activation::RELU;
158
159   Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
160   kernel.configure();
161   _memory_manager->allocate_memory(output_tensor);
162   EXPECT_ANY_THROW(kernel.execute());
163 }
164
165 } // namespace
166 } // namespace kernels
167 } // namespace luci_interpreter