• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <CommonTestUtils.hpp>
9 
10 #include <armnnUtils/QuantizeHelper.hpp>
11 #include <ResolveType.hpp>
12 
13 
14 namespace
15 {
16 
CreateArgMinMaxNetwork(const armnn::TensorInfo & inputTensorInfo,const armnn::TensorInfo & outputTensorInfo,armnn::ArgMinMaxFunction function,int axis)17 armnn::INetworkPtr CreateArgMinMaxNetwork(const armnn::TensorInfo& inputTensorInfo,
18                                           const armnn::TensorInfo& outputTensorInfo,
19                                           armnn::ArgMinMaxFunction function,
20                                           int axis)
21 {
22     armnn::INetworkPtr network(armnn::INetwork::Create());
23 
24     armnn::ArgMinMaxDescriptor descriptor;
25     descriptor.m_Function = function;
26     descriptor.m_Axis = axis;
27 
28     armnn::IConnectableLayer* inputLayer  = network->AddInputLayer(0, "Input");
29     armnn::IConnectableLayer* argMinMaxLayer  = network->AddArgMinMaxLayer(descriptor, "ArgMinMax");
30     armnn::IConnectableLayer* outputLayer = network->AddOutputLayer(0, "Output");
31 
32     Connect(inputLayer, argMinMaxLayer, inputTensorInfo, 0, 0);
33     Connect(argMinMaxLayer, outputLayer, outputTensorInfo, 0, 0);
34 
35     return network;
36 }
37 
38 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinMaxEndToEndImpl(const armnn::TensorShape & inputShape,const armnn::TensorShape & outputShape,const std::vector<float> & inputData,const std::vector<int32_t> & expectedOutputData,armnn::ArgMinMaxFunction function,int axis,const std::vector<armnn::BackendId> & backends)39 void ArgMinMaxEndToEndImpl(const armnn::TensorShape& inputShape,
40                            const armnn::TensorShape& outputShape,
41                            const std::vector<float>& inputData,
42                            const std::vector<int32_t>& expectedOutputData,
43                            armnn::ArgMinMaxFunction function,
44                            int axis,
45                            const std::vector<armnn::BackendId>& backends)
46 {
47     const float qScale  = armnn::IsQuantizedType<T>() ? 2.0f : 1.0f;
48     const int32_t qOffset = armnn::IsQuantizedType<T>() ? 2 : 0;
49 
50     armnn::TensorInfo inputTensorInfo(inputShape, ArmnnType, qScale, qOffset, true);
51     armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Signed32);
52 
53     // quantize data
54     std::vector<T> qInputData = armnnUtils::QuantizedVector<T>(inputData, qScale, qOffset);
55 
56     armnn::INetworkPtr network = CreateArgMinMaxNetwork(inputTensorInfo,
57                                                         outputTensorInfo,
58                                                         function,
59                                                         axis);
60 
61     EndToEndLayerTestImpl<ArmnnType, armnn::DataType::Signed32>(std::move(network),
62                                                                 { { 0, qInputData } },
63                                                                 { { 0, expectedOutputData } },
64                                                                 backends);
65 }
66 
67 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMaxEndToEndSimple(const std::vector<armnn::BackendId> & backends)68 void ArgMaxEndToEndSimple(const std::vector<armnn::BackendId>& backends)
69 {
70     const armnn::TensorShape inputShape{ 1, 1, 1, 5 };
71     const armnn::TensorShape outputShape{ 1, 1, 1 };
72 
73     std::vector<float> inputData({ 6.0f, 2.0f, 8.0f, 10.0f, 9.0f });
74     std::vector<int32_t> expectedOutputData({ 3 });
75 
76     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
77                                      outputShape,
78                                      inputData,
79                                      expectedOutputData,
80                                      armnn::ArgMinMaxFunction::Max,
81                                      -1,
82                                      backends);
83 }
84 
85 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinEndToEndSimple(const std::vector<armnn::BackendId> & backends)86 void ArgMinEndToEndSimple(const std::vector<armnn::BackendId>& backends)
87 {
88     const armnn::TensorShape inputShape{ 1, 1, 1, 5 };
89     const armnn::TensorShape outputShape{ 1, 1, 1 };
90 
91     std::vector<float> inputData({ 6.0f, 2.0f, 8.0f, 10.0f, 9.0f });
92     std::vector<int32_t> expectedOutputData({ 1 });
93 
94     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
95                                      outputShape,
96                                      inputData,
97                                      expectedOutputData,
98                                      armnn::ArgMinMaxFunction::Min,
99                                      3,
100                                      backends);
101 }
102 
103 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMaxAxis0EndToEnd(const std::vector<armnn::BackendId> & backends)104 void ArgMaxAxis0EndToEnd(const std::vector<armnn::BackendId>& backends)
105 {
106     const armnn::TensorShape inputShape{ 3, 2, 1, 4 };
107     const armnn::TensorShape outputShape{ 2, 1, 4 };
108 
109     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
110                                       8.0f,   7.0f,   6.0f,   6.0f,
111                                     100.0f,  20.0f, 300.0f,  40.0f,
112                                     500.0f, 476.0f, 450.0f, 426.0f,
113                                      50.0f,  60.0f,  70.0f,  80.0f,
114                                      10.0f, 200.0f,  30.0f, 400.0f });
115 
116     std::vector<int32_t> expectedOutputData({ 1, 2, 1, 2,
117                                               1, 1, 1, 1 });
118 
119     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
120                                      outputShape,
121                                      inputData,
122                                      expectedOutputData,
123                                      armnn::ArgMinMaxFunction::Max,
124                                      0,
125                                      backends);
126 }
127 
128 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinAxis0EndToEnd(const std::vector<armnn::BackendId> & backends)129 void ArgMinAxis0EndToEnd(const std::vector<armnn::BackendId>& backends)
130 {
131     const armnn::TensorShape inputShape{ 3, 2, 1, 4 };
132     const armnn::TensorShape outputShape{ 2, 1, 4 };
133 
134     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
135                                       8.0f,   7.0f,   6.0f,   6.0f,
136                                     100.0f,  20.0f, 300.0f,  40.0f,
137                                     500.0f, 476.0f, 450.0f, 426.0f,
138                                      50.0f,  60.0f,  70.0f,  80.0f,
139                                      10.0f, 200.0f,  30.0f, 400.0f });
140 
141     std::vector<int32_t> expectedOutputData({ 0, 0, 0, 0,
142                                               0, 0, 0, 0 });
143 
144     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
145                                      outputShape,
146                                      inputData,
147                                      expectedOutputData,
148                                      armnn::ArgMinMaxFunction::Min,
149                                      0,
150                                      backends);
151 }
152 
153 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMaxAxis1EndToEnd(const std::vector<armnn::BackendId> & backends)154 void ArgMaxAxis1EndToEnd(const std::vector<armnn::BackendId>& backends)
155 {
156     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
157     const armnn::TensorShape outputShape{ 1, 2, 4 };
158 
159     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
160                                       8.0f,   7.0f,   6.0f,   6.0f,
161                                     100.0f,  20.0f, 300.0f,  40.0f,
162                                     500.0f, 476.0f, 450.0f, 426.0f,
163                                      50.0f,  60.0f,  70.0f,  80.0f,
164                                      10.0f, 200.0f,  30.0f, 400.0f });
165 
166     std::vector<int32_t> expectedOutputData({ 1, 2, 1, 2,
167                                               1, 1, 1, 1 });
168 
169     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
170                                      outputShape,
171                                      inputData,
172                                      expectedOutputData,
173                                      armnn::ArgMinMaxFunction::Max,
174                                      1,
175                                      backends);
176 }
177 
178 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinAxis1EndToEnd(const std::vector<armnn::BackendId> & backends)179 void ArgMinAxis1EndToEnd(const std::vector<armnn::BackendId>& backends)
180 {
181     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
182     const armnn::TensorShape outputShape{ 1, 2, 4 };
183 
184     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
185                                       8.0f,   7.0f,   6.0f,   6.0f,
186                                     100.0f,  20.0f, 300.0f,  40.0f,
187                                     500.0f, 476.0f, 450.0f, 426.0f,
188                                      50.0f,  60.0f,  70.0f,  80.0f,
189                                      10.0f, 200.0f,  30.0f, 400.0f });
190 
191     std::vector<int32_t> expectedOutputData({ 0, 0, 0, 0,
192                                               0, 0, 0, 0 });
193 
194     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
195                                      outputShape,
196                                      inputData,
197                                      expectedOutputData,
198                                      armnn::ArgMinMaxFunction::Min,
199                                      1,
200                                      backends);
201 }
202 
203 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMaxAxis2EndToEnd(const std::vector<armnn::BackendId> & backends)204 void ArgMaxAxis2EndToEnd(const std::vector<armnn::BackendId>& backends)
205 {
206     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
207     const armnn::TensorShape outputShape{ 1, 3, 4 };
208 
209     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
210                                       8.0f,   7.0f,   6.0f,   6.0f,
211                                     100.0f,  20.0f, 300.0f,  40.0f,
212                                     500.0f, 476.0f, 450.0f, 426.0f,
213                                      10.0f, 200.0f,  30.0f, 400.0f,
214                                      50.0f,  60.0f,  70.0f,  80.0f });
215 
216     std::vector<int32_t> expectedOutputData({ 1, 1, 1, 1,
217                                               1, 1, 1, 1,
218                                               1, 0, 1, 0});
219 
220     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
221                                      outputShape,
222                                      inputData,
223                                      expectedOutputData,
224                                      armnn::ArgMinMaxFunction::Max,
225                                      2,
226                                      backends);
227 }
228 
229 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinAxis2EndToEnd(const std::vector<armnn::BackendId> & backends)230 void ArgMinAxis2EndToEnd(const std::vector<armnn::BackendId>& backends)
231 {
232     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
233     const armnn::TensorShape outputShape{ 1, 3, 4 };
234 
235     std::vector<float> inputData({    1.0f,   2.0f,   3.0f,   4.0f,
236                                       8.0f,   7.0f,   6.0f,   6.0f,
237                                     100.0f,  20.0f, 300.0f,  40.0f,
238                                     500.0f, 476.0f, 450.0f, 426.0f,
239                                      10.0f, 200.0f,  30.0f, 400.0f,
240                                      50.0f,  60.0f,  70.0f,  80.0f });
241 
242     std::vector<int32_t> expectedOutputData({ 0, 0, 0, 0,
243                                               0, 0, 0, 0,
244                                               0, 1, 0, 1 });
245 
246     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
247                                      outputShape,
248                                      inputData,
249                                      expectedOutputData,
250                                      armnn::ArgMinMaxFunction::Min,
251                                      2,
252                                      backends);
253 }
254 
255 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMaxAxis3EndToEnd(const std::vector<armnn::BackendId> & backends)256 void ArgMaxAxis3EndToEnd(const std::vector<armnn::BackendId>& backends)
257 {
258     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
259     const armnn::TensorShape outputShape{ 1, 3, 2 };
260 
261     std::vector<float> inputData({    1.0f,   3.0f,   6.0f,   7.0f,
262                                       8.0f,   7.0f,   6.0f,   6.0f,
263                                     100.0f,  20.0f, 300.0f,  40.0f,
264                                     500.0f, 476.0f, 450.0f, 426.0f,
265                                      10.0f, 200.0f,  30.0f, 400.0f,
266                                      50.0f,  60.0f,  70.0f,  80.0f });
267 
268     std::vector<int32_t> expectedOutputData({ 3, 0,
269                                               2, 0,
270                                               3, 3});
271 
272     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
273                                      outputShape,
274                                      inputData,
275                                      expectedOutputData,
276                                      armnn::ArgMinMaxFunction::Max,
277                                      3,
278                                      backends);
279 }
280 
281 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
ArgMinAxis3EndToEnd(const std::vector<armnn::BackendId> & backends)282 void ArgMinAxis3EndToEnd(const std::vector<armnn::BackendId>& backends)
283 {
284     const armnn::TensorShape inputShape{ 1, 3, 2, 4 };
285     const armnn::TensorShape outputShape{ 1, 3, 2 };
286 
287     std::vector<float> inputData({    1.0f,   3.0f,   6.0f,   7.0f,
288                                      18.0f,  16.0f,  14.0f,  12.0f,
289                                     100.0f,  20.0f, 300.0f,  40.0f,
290                                     500.0f, 476.0f, 450.0f, 426.0f,
291                                      10.0f, 200.0f,  30.0f, 400.0f,
292                                      50.0f,  60.0f,  70.0f,  80.0f });
293 
294     std::vector<int32_t> expectedOutputData({ 0, 3,
295                                               1, 3,
296                                               0, 0 });
297 
298     ArgMinMaxEndToEndImpl<ArmnnType>(inputShape,
299                                      outputShape,
300                                      inputData,
301                                      expectedOutputData,
302                                      armnn::ArgMinMaxFunction::Min,
303                                      3,
304                                      backends);
305 }
306 
307 } // anonymous namespace
308