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