Imported Upstream version 1.18.0
[platform/core/ml/nnfw.git] / tests / nnfw_api / src / one_op_tests / ArgMinMax.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "GenModelTest.h"
18
19 #include <memory>
20
21 struct ArgMinMaxVariationParam
22 {
23   TestCaseData tcd;
24   bool is_argmax = true;
25   circle::TensorType input_type = circle::TensorType::TensorType_FLOAT32;
26   float scale = 0.0f;
27   int64_t zero_point = 0;
28 };
29
30 class ArgMinMaxVariation : public GenModelTest,
31                            public ::testing::WithParamInterface<ArgMinMaxVariationParam>
32 {
33 };
34
35 // Input shape: {1, 2, 2, 1}
36 // Reduce axis: 1
37 // Output shape: {1, 2, 1}
38 // Output type: Int32
39 // Test with different input type and value
40 INSTANTIATE_TEST_CASE_P(
41   GenModelTest, ArgMinMaxVariation,
42   ::testing::Values(
43     // ArgMax, float input
44     ArgMinMaxVariationParam{TestCaseData{}.addInput<float>({1, 4, 2, 3}).addOutput<int32_t>({1, 0}),
45                             true},
46     // ArgMax, int32 input
47     ArgMinMaxVariationParam{
48       TestCaseData{}.addInput<int32_t>({1, 4, 2, 3}).addOutput<int32_t>({1, 0}), true,
49       circle::TensorType::TensorType_INT32},
50     // ArgMax, uint8 input
51     ArgMinMaxVariationParam{
52       TestCaseData{}.addInput<uint8_t>({1, 4, 2, 3}).addOutput<int32_t>({1, 0}), true,
53       circle::TensorType::TensorType_UINT8, 1.0, 1},
54     // ArgMax, int8 input
55     ArgMinMaxVariationParam{
56       TestCaseData{}.addInput<int8_t>({1, 4, 2, 3}).addOutput<int32_t>({1, 0}), true,
57       circle::TensorType::TensorType_INT8, 1.0, 1},
58     // ArgMin, float input
59     ArgMinMaxVariationParam{TestCaseData{}.addInput<float>({1, 4, 2, 3}).addOutput<int32_t>({0, 1}),
60                             false},
61     // ArgMin, int32 input
62     ArgMinMaxVariationParam{
63       TestCaseData{}.addInput<int32_t>({1, 4, 2, 3}).addOutput<int32_t>({0, 1}), false,
64       circle::TensorType::TensorType_INT32},
65     // ArgMin, uint8 input
66     ArgMinMaxVariationParam{
67       TestCaseData{}.addInput<uint8_t>({1, 4, 2, 3}).addOutput<int32_t>({0, 1}), false,
68       circle::TensorType::TensorType_UINT8, 1.0, 1},
69     // ArgMin, int8 input
70     ArgMinMaxVariationParam{
71       TestCaseData{}.addInput<int8_t>({1, 4, 2, 3}).addOutput<int32_t>({0, 1}), false,
72       circle::TensorType::TensorType_INT8, 1.0, 1}));
73
74 TEST_P(ArgMinMaxVariation, Test)
75 {
76   auto &param = GetParam();
77
78   CircleGen cgen;
79   const auto output_type = circle::TensorType::TensorType_INT32;
80   std::vector<int32_t> axis_data{1};
81   uint32_t axis_buf = cgen.addBuffer(axis_data);
82   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
83   int in = cgen.addTensor({{1, 2, 2, 1}, param.input_type}, param.scale, param.zero_point);
84   int out = cgen.addTensor({{1, 2, 1}, output_type});
85   param.is_argmax ? cgen.addOperatorArgMax({{in, axis}, {out}}, output_type)
86                   : cgen.addOperatorArgMin({{in, axis}, {out}}, output_type);
87   cgen.setInputsAndOutputs({in}, {out});
88
89   _context = std::make_unique<GenModelTestContext>(cgen.finish());
90   _context->addTestCase(param.tcd);
91   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
92
93   SUCCEED();
94 }
95
96 TEST_F(GenModelTest, OneOp_ArgMax_Int64_AxisToConst)
97 {
98   CircleGen cgen;
99   const auto output_type = circle::TensorType::TensorType_INT64;
100   std::vector<int32_t> axis_data{1};
101   uint32_t axis_buf = cgen.addBuffer(axis_data);
102   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
103   int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
104   int out = cgen.addTensor({{1, 2, 1}, output_type});
105   cgen.addOperatorArgMax({{in, axis}, {out}}, output_type);
106   cgen.setInputsAndOutputs({in}, {out});
107
108   _context = std::make_unique<GenModelTestContext>(cgen.finish());
109   _context->addTestCase(TestCaseData{}.addInput<float>({1, 4, 2, 3}).addOutput<int64_t>({1, 0}));
110   _context->setBackends({"acl_cl", "cpu"});
111
112   SUCCEED();
113 }
114
115 TEST_F(GenModelTest, OneOp_ArgMax_AxisToVar)
116 {
117   CircleGen cgen;
118   const auto output_type = circle::TensorType::TensorType_INT32;
119   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32});
120   int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
121   int out = cgen.addTensor({{1, 2, 1}, output_type});
122   cgen.addOperatorArgMax({{in, axis}, {out}}, output_type);
123   cgen.setInputsAndOutputs({in, axis}, {out});
124
125   _context = std::make_unique<GenModelTestContext>(cgen.finish());
126   _context->addTestCase(TestCaseData{}
127                           .addInput<float>({1, 4, 2, 3})
128                           .addInput<int32_t>({-3})
129                           .addOutput<int32_t>({1, 0}));
130   _context->setBackends({"cpu"});
131
132   SUCCEED();
133 }
134
135 TEST_P(ArgMinMaxVariation, neg_InvalidAxis0)
136 {
137   auto &param = GetParam();
138
139   CircleGen cgen;
140   const auto output_type = circle::TensorType::TensorType_INT32;
141   std::vector<int32_t> axis_data{4};
142   uint32_t axis_buf = cgen.addBuffer(axis_data);
143   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
144   int in = cgen.addTensor({{1, 2, 2, 1}, param.input_type}, param.scale, param.zero_point);
145   int out = cgen.addTensor({{1, 2, 1}, output_type});
146   param.is_argmax ? cgen.addOperatorArgMax({{in, axis}, {out}}, output_type)
147                   : cgen.addOperatorArgMin({{in, axis}, {out}}, output_type);
148   cgen.setInputsAndOutputs({in}, {out});
149
150   _context = std::make_unique<GenModelTestContext>(cgen.finish());
151   _context->expectFailCompile();
152   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
153
154   SUCCEED();
155 }
156
157 TEST_P(ArgMinMaxVariation, neg_InvalidAxis1)
158 {
159   auto &param = GetParam();
160
161   CircleGen cgen;
162   const auto output_type = circle::TensorType::TensorType_INT32;
163   std::vector<int32_t> axis_data{-3};
164   uint32_t axis_buf = cgen.addBuffer(axis_data);
165   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
166   int in = cgen.addTensor({{2, 2}, param.input_type}, param.scale, param.zero_point);
167   int out = cgen.addTensor({{2}, output_type});
168   param.is_argmax ? cgen.addOperatorArgMax({{in, axis}, {out}}, output_type)
169                   : cgen.addOperatorArgMin({{in, axis}, {out}}, output_type);
170   cgen.setInputsAndOutputs({in}, {out});
171
172   _context = std::make_unique<GenModelTestContext>(cgen.finish());
173   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
174   _context->expectFailCompile();
175
176   SUCCEED();
177 }
178
179 TEST_F(GenModelTest, neg_OneOp_ArgMax_InType)
180 {
181   CircleGen cgen;
182   const auto output_type = circle::TensorType::TensorType_INT32;
183   std::vector<int32_t> axis_data{4};
184   uint32_t axis_buf = cgen.addBuffer(axis_data);
185   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
186   int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_BOOL});
187   int out = cgen.addTensor({{1, 2, 1}, output_type});
188   cgen.addOperatorArgMax({{in, axis}, {out}}, output_type);
189   cgen.setInputsAndOutputs({in}, {out});
190
191   _context = std::make_unique<GenModelTestContext>(cgen.finish());
192   _context->expectFailModelLoad();
193
194   SUCCEED();
195 }
196
197 TEST_P(ArgMinMaxVariation, neg_AxisType)
198 {
199   auto &param = GetParam();
200
201   CircleGen cgen;
202   const auto output_type = circle::TensorType::TensorType_INT32;
203   std::vector<float> axis_data{4};
204   uint32_t axis_buf = cgen.addBuffer(axis_data);
205   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32, axis_buf});
206   int in = cgen.addTensor({{1, 2, 2, 1}, param.input_type}, param.scale, param.zero_point);
207   int out = cgen.addTensor({{1, 2, 1}, output_type});
208   param.is_argmax ? cgen.addOperatorArgMax({{in, axis}, {out}}, output_type)
209                   : cgen.addOperatorArgMin({{in, axis}, {out}}, output_type);
210   cgen.setInputsAndOutputs({in}, {out});
211
212   _context = std::make_unique<GenModelTestContext>(cgen.finish());
213   _context->expectFailModelLoad();
214
215   SUCCEED();
216 }
217
218 TEST_F(GenModelTest, neg_OneOp_ArgMax_OutType)
219 {
220   CircleGen cgen;
221   const auto output_type = circle::TensorType::TensorType_FLOAT32;
222   std::vector<int32_t> axis_data{4};
223   uint32_t axis_buf = cgen.addBuffer(axis_data);
224   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
225   int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
226   int out = cgen.addTensor({{1, 2, 1}, output_type});
227   cgen.addOperatorArgMax({{in, axis}, {out}}, output_type);
228   cgen.setInputsAndOutputs({in}, {out});
229
230   _context = std::make_unique<GenModelTestContext>(cgen.finish());
231   _context->expectFailModelLoad();
232
233   SUCCEED();
234 }
235
236 TEST_P(ArgMinMaxVariation, neg_paramType)
237 {
238   auto &param = GetParam();
239
240   CircleGen cgen;
241   const auto output_type = circle::TensorType::TensorType_INT32;
242   const auto output_param = circle::TensorType::TensorType_INT64;
243   std::vector<int32_t> axis_data{4};
244   uint32_t axis_buf = cgen.addBuffer(axis_data);
245   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
246   int in = cgen.addTensor({{1, 2, 2, 1}, param.input_type}, param.scale, param.zero_point);
247   int out = cgen.addTensor({{1, 2, 1}, output_type});
248   param.is_argmax ? cgen.addOperatorArgMax({{in, axis}, {out}}, output_param)
249                   : cgen.addOperatorArgMin({{in, axis}, {out}}, output_param);
250   cgen.setInputsAndOutputs({in}, {out});
251
252   _context = std::make_unique<GenModelTestContext>(cgen.finish());
253   _context->expectFailModelLoad();
254
255   SUCCEED();
256 }