blob: bb2392ff010b8d66ff9180a13e54cb74ab2f8d53 [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8#include "LayerTestResult.hpp"
9
10#include <Permute.hpp>
11#include <ResolveType.hpp>
12#include <TensorUtils.hpp>
13
14#include <armnn/ArmNN.hpp>
15
16#include <backendsCommon/IBackendInternal.hpp>
17#include <backendsCommon/WorkloadFactory.hpp>
18
19#include <backendsCommon/test/TensorCopyUtils.hpp>
20#include <backendsCommon/test/WorkloadTestUtils.hpp>
21
22#include <test/TensorHelpers.hpp>
23
24//
25// ResizeBilinear
26//
27
28template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
29LayerTestResult<T, 4> ResizeBilinearNopTest(
30 armnn::IWorkloadFactory& workloadFactory,
31 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
32 const armnn::DataLayout dataLayout)
33{
34 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
35 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
36 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
37
38 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
39 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
40 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
41
42 if (armnn::IsQuantizedType<T>())
43 {
44 inputTensorInfo.SetQuantizationScale(1.5f);
45 inputTensorInfo.SetQuantizationOffset(-3);
46 outputTensorInfo.SetQuantizationScale(1.5f);
47 outputTensorInfo.SetQuantizationOffset(-3);
48 }
49
50 std::vector<float> inputData = armnn::IsQuantizedType<T>()
51 ? std::initializer_list<float>
52 {
53 1, 2, 3, 4,
54 2, 3, 4, 5,
55 3, 4, 5, 6,
56 4, 5, 6, 7
57 }
58 : std::initializer_list<float>
59 {
60 1.0f, 2.0f, 3.0f, 4.0f,
61 2.0f, 3.0f, 4.0f, 5.0f,
62 3.0f, 4.0f, 5.0f, 6.0f,
63 4.0f, 5.0f, 6.0f, 7.0f,
64
65 1.0f, 2.0f, 3.0f, 4.0f,
66 2.0f, 3.0f, 4.0f, 5.0f,
67 3.0f, 4.0f, 5.0f, 6.0f,
68 4.0f, 5.0f, 6.0f, 7.0f
69 };
70
71 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
72 if (dataLayout == armnn::DataLayout::NHWC)
73 {
74 std::vector<float> tmp(inputData.size());
75 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
76 inputData = tmp;
77 }
78
79 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
80 inputTensorInfo.GetQuantizationOffset(),
81 inputData));
82
83 LayerTestResult<T, 4> result(outputTensorInfo);
84 result.outputExpected = input;
85
86 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
87 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
88
89 armnn::ResizeQueueDescriptor descriptor;
90 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::Bilinear;
91 descriptor.m_Parameters.m_DataLayout = dataLayout;
92
93 armnn::WorkloadInfo info;
94 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
95 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
96
97 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
98
99 inputHandle->Allocate();
100 outputHandle->Allocate();
101 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
102
103 workload->PostAllocationConfigure();
104 workload->Execute();
105
106 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
107 return result;
108}
109
110template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
111LayerTestResult<T, 4> SimpleResizeBilinearTest(
112 armnn::IWorkloadFactory& workloadFactory,
113 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
114 const armnn::DataLayout dataLayout)
115{
116 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
117 ? armnnUtils::GetTensorInfo(1, 1, 2, 2, dataLayout, ArmnnType)
118 : armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
119
120 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
121 ? armnnUtils::GetTensorInfo(1, 1, 1, 1, dataLayout, ArmnnType)
122 : armnnUtils::GetTensorInfo(1, 2, 1, 1, dataLayout, ArmnnType);
123
124 if (armnn::IsQuantizedType<T>())
125 {
126 inputTensorInfo.SetQuantizationScale(0.1567f);
127 inputTensorInfo.SetQuantizationOffset(1);
128 outputTensorInfo.SetQuantizationScale(0.1567f);
129 outputTensorInfo.SetQuantizationOffset(1);
130 }
131
132 std::vector<float> inputData = armnn::IsQuantizedType<T>()
133 ? std::initializer_list<float>
134 {
135 1, 255,
136 200, 250
137 }
138 : std::initializer_list<float>
139 {
140 1.0f, 255.0f,
141 200.0f, 250.0f,
142
143 250.0f, 200.0f,
144 250.0f, 1.0f
145 };
146
147 // The 'resize bilinear' operation projects the top-left corner of output texels into the input image,
148 // then figures out the interpolants and weights. Note this is different to projecting the centre of the
149 // output texel. Thus, for a input matrix of 2x2, we'll expect the output 1x1 matrix to contain, as
150 // its single element, the value that was at position (0,0) of the input matrix (rather than an average,
151 // which we would expect if projecting the centre).
152
153 std::vector<float> outputData = armnn::IsQuantizedType<T>()
154 ? std::initializer_list<float>
155 {
156 1
157 }
158 : std::initializer_list<float>
159 {
160 1.0f,
161
162 250.0f
163 };
164
165 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
166 if (dataLayout == armnn::DataLayout::NHWC)
167 {
168 std::vector<float> tmp(inputData.size());
169 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
170 inputData = tmp;
171
172 std::vector<float> tmp1(outputData.size());
173 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
174 outputData = tmp1;
175 }
176
177 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
178 inputTensorInfo.GetQuantizationOffset(),
179 inputData));
180
181 LayerTestResult<T, 4> result(outputTensorInfo);
182 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
183 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
184 outputTensorInfo.GetQuantizationOffset(),
185 outputData));
186
187 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
188 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
189
190 armnn::ResizeQueueDescriptor descriptor;
191 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::Bilinear;
192 descriptor.m_Parameters.m_DataLayout = dataLayout;
193
194 armnn::WorkloadInfo info;
195 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
196 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
197
198 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
199
200 inputHandle->Allocate();
201 outputHandle->Allocate();
202 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
203
204 workload->PostAllocationConfigure();
205 workload->Execute();
206
207 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
208 return result;
209}
210
211template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
212LayerTestResult<T, 4> ResizeBilinearSqMinTest(
213 armnn::IWorkloadFactory& workloadFactory,
214 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
215 const armnn::DataLayout dataLayout)
216{
217 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
218 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
219 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
220
221 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
222 ? armnnUtils::GetTensorInfo(1, 1, 2, 2, dataLayout, ArmnnType)
223 : armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
224
225 if (armnn::IsQuantizedType<T>())
226 {
227 inputTensorInfo.SetQuantizationScale(3.141592f);
228 inputTensorInfo.SetQuantizationOffset(3);
229 outputTensorInfo.SetQuantizationScale(3.141592f);
230 outputTensorInfo.SetQuantizationOffset(3);
231 }
232
233 std::vector<float> inputData = armnn::IsQuantizedType<T>()
234 ? std::initializer_list<float>
235 {
236 1, 2, 3, 4,
237 2, 3, 4, 5,
238 3, 4, 5, 6,
239 4, 5, 6, 7
240 }
241 : std::initializer_list<float>
242 {
243 1.0f, 2.0f, 3.0f, 4.0f,
244 2.0f, 3.0f, 4.0f, 5.0f,
245 3.0f, 4.0f, 5.0f, 6.0f,
246 4.0f, 5.0f, 6.0f, 7.0f,
247
248 7.0f, 6.0f, 5.0f, 4.0f,
249 6.0f, 5.0f, 4.0f, 3.0f,
250 5.0f, 4.0f, 3.0f, 2.0f,
251 4.0f, 3.0f, 2.0f, 1.0f
252 };
253
254 std::vector<float> outputData = armnn::IsQuantizedType<T>()
255 ? std::initializer_list<float>
256 {
257 1, 3,
258 3, 5
259 }
260 : std::initializer_list<float>
261 {
262 1.0f, 3.0f,
263 3.0f, 5.0f,
264
265 7.0f, 5.0f,
266 5.0f, 3.0f
267 };
268
269 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
270 if (dataLayout == armnn::DataLayout::NHWC)
271 {
272 std::vector<float> tmp(inputData.size());
273 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
274 inputData = tmp;
275
276 std::vector<float> tmp1(outputData.size());
277 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
278 outputData = tmp1;
279 }
280
281 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
282 inputTensorInfo.GetQuantizationOffset(),
283 inputData));
284
285 LayerTestResult<T, 4> result(outputTensorInfo);
286 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
287 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
288 outputTensorInfo.GetQuantizationOffset(),
289 outputData));
290
291 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
292 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
293
294 armnn::ResizeQueueDescriptor descriptor;
295 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::Bilinear;
296 descriptor.m_Parameters.m_DataLayout = dataLayout;
297
298 armnn::WorkloadInfo info;
299 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
300 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
301
302 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
303
304 inputHandle->Allocate();
305 outputHandle->Allocate();
306 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
307
308 workload->PostAllocationConfigure();
309 workload->Execute();
310
311 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
312 return result;
313}
314
315template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
316LayerTestResult<T, 4> ResizeBilinearMinTest(
317 armnn::IWorkloadFactory& workloadFactory,
318 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
319 const armnn::DataLayout dataLayout)
320{
321 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
322 ? armnnUtils::GetTensorInfo(1, 1, 2, 3, dataLayout, ArmnnType)
323 : armnnUtils::GetTensorInfo(1, 2, 3, 5, dataLayout, ArmnnType);
324
325 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
326 ? armnnUtils::GetTensorInfo(1, 1, 1, 2, dataLayout, ArmnnType)
327 : armnnUtils::GetTensorInfo(1, 2, 2, 3, dataLayout, ArmnnType);
328
329 if (armnn::IsQuantizedType<T>())
330 {
331 inputTensorInfo.SetQuantizationScale(1.5f);
332 inputTensorInfo.SetQuantizationOffset(-1);
333 outputTensorInfo.SetQuantizationScale(1.5f);
334 outputTensorInfo.SetQuantizationOffset(-1);
335 }
336
337 std::vector<float> inputData = armnn::IsQuantizedType<T>()
338 ? std::initializer_list<float>
339 {
340 3.0f, 4.5f, 6.0f, // 1, 2, 3, : Expected quantised values
341 9.0f, 13.5f, 21.0f // 5, 8, 13
342 }
343 : std::initializer_list<float>
344 {
345 1.0f, 2.0f, 3.0f, 5.0f, 8.0f,
346 13.0f, 21.0f, 34.0f, 55.0f, 89.0f,
347 144.0f, 233.0f, 377.0f, 610.0f, 987.0f,
348
349 987.0f, 610.0f, 377.0f, 233.0f, 144.0f,
350 89.0f, 55.0f, 34.0f, 21.0f, 13.0f,
351 8.0f, 5.0f, 3.0f, 2.0f, 1.0f
352 };
353
354 std::vector<float> outputData = armnn::IsQuantizedType<T>()
355 ? std::initializer_list<float>
356 {
357 3.0f, 5.25f // 1, 3
358 }
359 : std::initializer_list<float>
360 {
361 1.0f, 2.6666f, 6.00f,
362 78.5f, 179.3333f, 401.00f,
363
364 987.0f, 454.6670f, 203.33f,
365 48.5f, 22.3333f, 10.00f
366 };
367
368 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
369 if (dataLayout == armnn::DataLayout::NHWC)
370 {
371 std::vector<float> tmp(inputData.size());
372 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
373 inputData = tmp;
374
375 std::vector<float> tmp1(outputData.size());
376 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
377 outputData = tmp1;
378 }
379
380 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
381 inputTensorInfo.GetQuantizationOffset(),
382 inputData));
383
384 LayerTestResult<T, 4> result(outputTensorInfo);
385 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
386 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
387 outputTensorInfo.GetQuantizationOffset(),
388 outputData));
389
390 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
391 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
392
393 armnn::ResizeQueueDescriptor descriptor;
394 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::Bilinear;
395 descriptor.m_Parameters.m_DataLayout = dataLayout;
396
397 armnn::WorkloadInfo info;
398 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
399 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
400
401 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
402
403 inputHandle->Allocate();
404 outputHandle->Allocate();
405 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
406
407 workload->PostAllocationConfigure();
408 workload->Execute();
409
410 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
411 return result;
412}
413
414template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
415LayerTestResult<T, 4> ResizeBilinearMagTest(
416 armnn::IWorkloadFactory& workloadFactory,
417 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
418 const armnn::DataLayout dataLayout)
419{
420 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
421 ? armnnUtils::GetTensorInfo(1, 1, 3, 2, dataLayout, ArmnnType)
422 : armnnUtils::GetTensorInfo(1, 2, 3, 2, dataLayout, ArmnnType);
423
424 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
425 ? armnnUtils::GetTensorInfo(1, 1, 3, 5, dataLayout, ArmnnType)
426 : armnnUtils::GetTensorInfo(1, 2, 3, 5, dataLayout, ArmnnType);
427
428 if (armnn::IsQuantizedType<T>())
429 {
430 inputTensorInfo.SetQuantizationScale(0.010765f);
431 inputTensorInfo.SetQuantizationOffset(7);
432 outputTensorInfo.SetQuantizationScale(0.010132f);
433 outputTensorInfo.SetQuantizationOffset(-18);
434 }
435
436 std::vector<float> inputData = armnn::IsQuantizedType<T>()
437 ? std::initializer_list<float>
438 {
439 0.183005f, 2.379065f, // 24, 228, : Expected quantised values
440 1.054970f, 1.302565f, // 105, 128,
441 2.400595f, 0.688960f // 230, 71
442 }
443 : std::initializer_list<float>
444 {
445 1.0f, 2.0f,
446 13.0f, 21.0f,
447 144.0f, 233.0f,
448
449 233.0f, 144.0f,
450 21.0f, 13.0f,
451 2.0f, 1.0f
452 };
453
454 std::vector<float> outputData = armnn::IsQuantizedType<T>()
455 ? std::initializer_list<float>
456 {
457 0.18300501f, 1.06142902f, 1.93985295f, 2.37906504f, 2.37906504f,
458 1.05497003f, 1.15400803f, 1.25304604f, 1.30256498f, 1.30256498f,
459 2.40059495f, 1.71594095f, 1.03128707f, 0.68896002f, 0.68896002f
460 // 0, 87, 173, 217, 217, : Expected quantised values
461 // 86, 96, 106, 111, 111,
462 // 219, 151, 84, 50, 50
463 }
464 : std::initializer_list<float>
465 {
466 1.0f, 1.4f, 1.8f, 2.0f, 2.0f,
467 13.0f, 16.2f, 19.4f, 21.0f, 21.0f,
468 144.0f, 179.6f, 215.2f, 233.0f, 233.0f,
469
470 233.0f, 197.4f, 161.8f, 144.0f, 144.0f,
471 21.0f, 17.8f, 14.6f, 13.0f, 13.0f,
472 2.0f, 1.6f, 1.2f, 1.0f, 1.0f
473 };
474
475 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
476 if (dataLayout == armnn::DataLayout::NHWC)
477 {
478 std::vector<float> tmp(inputData.size());
479 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
480 inputData = tmp;
481
482 std::vector<float> tmp1(outputData.size());
483 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
484 outputData = tmp1;
485 }
486
487 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
488 inputTensorInfo.GetQuantizationOffset(),
489 inputData));
490
491 LayerTestResult<T, 4> result(outputTensorInfo);
492 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
493 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
494 outputTensorInfo.GetQuantizationOffset(),
495 outputData));
496
497 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
498 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
499
500 armnn::ResizeQueueDescriptor descriptor;
501 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::Bilinear;
502 descriptor.m_Parameters.m_DataLayout = dataLayout;
503
504 armnn::WorkloadInfo info;
505 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
506 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
507
508 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
509
510 inputHandle->Allocate();
511 outputHandle->Allocate();
512 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
513
514 workload->PostAllocationConfigure();
515 workload->Execute();
516
517 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
518 return result;
519}
520
521//
522// ResizeNearestNeighbor
523//
524
525template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
526LayerTestResult<T, 4> ResizeNearestNeighborNopTest(
527 armnn::IWorkloadFactory& workloadFactory,
528 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
529 const armnn::DataLayout dataLayout)
530{
531 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
532 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
533 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
534
535 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
536 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
537 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
538
539 if (armnn::IsQuantizedType<T>())
540 {
541 inputTensorInfo.SetQuantizationScale(1.5f);
542 inputTensorInfo.SetQuantizationOffset(-3);
543 outputTensorInfo.SetQuantizationScale(1.5f);
544 outputTensorInfo.SetQuantizationOffset(-3);
545 }
546
547 std::vector<float> inputData = armnn::IsQuantizedType<T>()
548 ? std::initializer_list<float>
549 {
550 1, 2, 3, 4,
551 2, 3, 4, 5,
552 3, 4, 5, 6,
553 4, 5, 6, 7
554 }
555 : std::initializer_list<float>
556 {
557 1.0f, 2.0f, 3.0f, 4.0f,
558 2.0f, 3.0f, 4.0f, 5.0f,
559 3.0f, 4.0f, 5.0f, 6.0f,
560 4.0f, 5.0f, 6.0f, 7.0f,
561
562 1.0f, 2.0f, 3.0f, 4.0f,
563 2.0f, 3.0f, 4.0f, 5.0f,
564 3.0f, 4.0f, 5.0f, 6.0f,
565 4.0f, 5.0f, 6.0f, 7.0f
566 };
567
568 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
569 if (dataLayout == armnn::DataLayout::NHWC)
570 {
571 std::vector<float> tmp(inputData.size());
572 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
573 inputData = tmp;
574 }
575
576 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
577 inputTensorInfo.GetQuantizationOffset(),
578 inputData));
579
580 LayerTestResult<T, 4> result(outputTensorInfo);
581 result.outputExpected = input;
582
583 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
584 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
585
586 armnn::ResizeQueueDescriptor descriptor;
587 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::NearestNeighbor;
588 descriptor.m_Parameters.m_DataLayout = dataLayout;
589 armnn::WorkloadInfo info;
590 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
591 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
592
593 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
594
595 inputHandle->Allocate();
596 outputHandle->Allocate();
597 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
598
599 workload->PostAllocationConfigure();
600 workload->Execute();
601
602 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
603 return result;
604}
605
606template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
607LayerTestResult<T, 4> SimpleResizeNearestNeighborTest(
608 armnn::IWorkloadFactory& workloadFactory,
609 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
610 const armnn::DataLayout dataLayout)
611{
612 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
613 ? armnnUtils::GetTensorInfo(1, 1, 2, 2, dataLayout, ArmnnType)
614 : armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
615
616 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
617 ? armnnUtils::GetTensorInfo(1, 1, 1, 1, dataLayout, ArmnnType)
618 : armnnUtils::GetTensorInfo(1, 2, 1, 1, dataLayout, ArmnnType);
619
620 if (armnn::IsQuantizedType<T>())
621 {
622 inputTensorInfo.SetQuantizationScale(0.1567f);
623 inputTensorInfo.SetQuantizationOffset(1);
624 outputTensorInfo.SetQuantizationScale(0.1567f);
625 outputTensorInfo.SetQuantizationOffset(1);
626 }
627
628 std::vector<float> inputData = armnn::IsQuantizedType<T>()
629 ? std::initializer_list<float>
630 {
631 1, 255,
632 200, 250
633 }
634 : std::initializer_list<float>
635 {
636 1.0f, 255.0f,
637 200.0f, 250.0f,
638
639 250.0f, 200.0f,
640 250.0f, 1.0f
641 };
642
643 // The 'resize' operation projects the top-left corner of output texels into the input image,
644 // then figures out the interpolants and weights. Note this is different to projecting the centre of the
645 // output texel. Thus, for a input matrix of 2x2, we'll expect the output 1x1 matrix to contain, as
646 // its single element, the value that was at position (0,0) of the input matrix (rather than an average,
647 // which we would expect if projecting the centre).
648
649 std::vector<float> outputData = armnn::IsQuantizedType<T>()
650 ? std::initializer_list<float>
651 {
652 1
653 }
654 : std::initializer_list<float>
655 {
656 1.0f,
657
658 250.0f
659 };
660
661 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
662 if (dataLayout == armnn::DataLayout::NHWC)
663 {
664 std::vector<float> tmp(inputData.size());
665 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
666 inputData = tmp;
667
668 std::vector<float> tmp1(outputData.size());
669 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
670 outputData = tmp1;
671 }
672
673 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
674 inputTensorInfo.GetQuantizationOffset(),
675 inputData));
676
677 LayerTestResult<T, 4> result(outputTensorInfo);
678 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
679 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
680 outputTensorInfo.GetQuantizationOffset(),
681 outputData));
682
683 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
684 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
685
686 armnn::ResizeQueueDescriptor descriptor;
687 descriptor.m_Parameters.m_DataLayout = dataLayout;
688 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::NearestNeighbor;
689 armnn::WorkloadInfo info;
690 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
691 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
692
693 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
694
695 inputHandle->Allocate();
696 outputHandle->Allocate();
697 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
698
699 workload->PostAllocationConfigure();
700 workload->Execute();
701
702 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
703 return result;
704}
705
706template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
707LayerTestResult<T, 4> ResizeNearestNeighborSqMinTest(
708 armnn::IWorkloadFactory& workloadFactory,
709 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
710 const armnn::DataLayout dataLayout)
711{
712 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
713 ? armnnUtils::GetTensorInfo(1, 1, 4, 4, dataLayout, ArmnnType)
714 : armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
715
716 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
717 ? armnnUtils::GetTensorInfo(1, 1, 2, 2, dataLayout, ArmnnType)
718 : armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
719
720 if (armnn::IsQuantizedType<T>())
721 {
722 inputTensorInfo.SetQuantizationScale(3.141592f);
723 inputTensorInfo.SetQuantizationOffset(3);
724 outputTensorInfo.SetQuantizationScale(3.141592f);
725 outputTensorInfo.SetQuantizationOffset(3);
726 }
727
728 std::vector<float> inputData = armnn::IsQuantizedType<T>()
729 ? std::initializer_list<float>
730 {
731 1, 2, 3, 4,
732 2, 3, 4, 5,
733 3, 4, 5, 6,
734 4, 5, 6, 7
735 }
736 : std::initializer_list<float>
737 {
738 1.0f, 2.0f, 3.0f, 4.0f,
739 2.0f, 3.0f, 4.0f, 5.0f,
740 3.0f, 4.0f, 5.0f, 6.0f,
741 4.0f, 5.0f, 6.0f, 7.0f,
742
743 7.0f, 6.0f, 5.0f, 4.0f,
744 6.0f, 5.0f, 4.0f, 3.0f,
745 5.0f, 4.0f, 3.0f, 2.0f,
746 4.0f, 3.0f, 2.0f, 1.0f
747 };
748
749 std::vector<float> outputData = armnn::IsQuantizedType<T>()
750 ? std::initializer_list<float>
751 {
752 1, 3,
753 3, 5
754 }
755 : std::initializer_list<float>
756 {
757 1.0f, 3.0f,
758 3.0f, 5.0f,
759
760 7.0f, 5.0f,
761 5.0f, 3.0f
762 };
763
764 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
765 if (dataLayout == armnn::DataLayout::NHWC)
766 {
767 std::vector<float> tmp(inputData.size());
768 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
769 inputData = tmp;
770
771 std::vector<float> tmp1(outputData.size());
772 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
773 outputData = tmp1;
774 }
775
776 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
777 inputTensorInfo.GetQuantizationOffset(),
778 inputData));
779
780 LayerTestResult<T, 4> result(outputTensorInfo);
781 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
782 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
783 outputTensorInfo.GetQuantizationOffset(),
784 outputData));
785
786 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
787 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
788
789 armnn::ResizeQueueDescriptor descriptor;
790 descriptor.m_Parameters.m_DataLayout = dataLayout;
791 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::NearestNeighbor;
792 armnn::WorkloadInfo info;
793 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
794 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
795
796 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
797
798 inputHandle->Allocate();
799 outputHandle->Allocate();
800 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
801
802 workload->PostAllocationConfigure();
803 workload->Execute();
804
805 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
806 return result;
807}
808
809template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
810LayerTestResult<T, 4> ResizeNearestNeighborMinTest(
811 armnn::IWorkloadFactory& workloadFactory,
812 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
813 const armnn::DataLayout dataLayout)
814{
815 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
816 ? armnnUtils::GetTensorInfo(1, 1, 2, 3, dataLayout, ArmnnType)
817 : armnnUtils::GetTensorInfo(1, 2, 3, 5, dataLayout, ArmnnType);
818
819 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
820 ? armnnUtils::GetTensorInfo(1, 1, 1, 2, dataLayout, ArmnnType)
821 : armnnUtils::GetTensorInfo(1, 2, 2, 3, dataLayout, ArmnnType);
822
823 if (armnn::IsQuantizedType<T>())
824 {
825 inputTensorInfo.SetQuantizationScale(1.5f);
826 inputTensorInfo.SetQuantizationOffset(-1);
827 outputTensorInfo.SetQuantizationScale(1.5f);
828 outputTensorInfo.SetQuantizationOffset(-1);
829 }
830
831 std::vector<float> inputData = armnn::IsQuantizedType<T>()
832 ? std::initializer_list<float>
833 {
834 3.0f, 4.5f, 6.0f, // 1, 2, 3, : Expected quantised values
835 9.0f, 13.5f, 21.0f // 5, 8, 13
836 }
837 : std::initializer_list<float>
838 {
839 1.0f, 2.0f, 3.0f, 5.0f, 8.0f,
840 13.0f, 21.0f, 34.0f, 55.0f, 89.0f,
841 144.0f, 233.0f, 377.0f, 610.0f, 987.0f,
842
843 987.0f, 610.0f, 377.0f, 233.0f, 144.0f,
844 89.0f, 55.0f, 34.0f, 21.0f, 13.0f,
845 8.0f, 5.0f, 3.0f, 2.0f, 1.0f
846 };
847
848 std::vector<float> outputData = armnn::IsQuantizedType<T>()
849 ? std::initializer_list<float>
850 {
851 3.0f, 4.5f // 1, 3
852 }
853 : std::initializer_list<float>
854 {
855 1.f, 2.f, 5.f,
856 13.f, 21.f, 55.f,
857
858 987.f, 610.f, 233.f,
859 89.f, 55.f, 21.f
860 };
861
862 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
863 if (dataLayout == armnn::DataLayout::NHWC)
864 {
865 std::vector<float> tmp(inputData.size());
866 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
867 inputData = tmp;
868
869 std::vector<float> tmp1(outputData.size());
870 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
871 outputData = tmp1;
872 }
873
874 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
875 inputTensorInfo.GetQuantizationOffset(),
876 inputData));
877
878 LayerTestResult<T, 4> result(outputTensorInfo);
879 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
880 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
881 outputTensorInfo.GetQuantizationOffset(),
882 outputData));
883
884 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
885 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
886
887 armnn::ResizeQueueDescriptor descriptor;
888 descriptor.m_Parameters.m_DataLayout = dataLayout;
889 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::NearestNeighbor;
890 armnn::WorkloadInfo info;
891 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
892 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
893
894 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
895
896 inputHandle->Allocate();
897 outputHandle->Allocate();
898 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
899
900 workload->PostAllocationConfigure();
901 workload->Execute();
902
903 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
904 return result;
905}
906
907template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
908LayerTestResult<T, 4> ResizeNearestNeighborMagTest(
909 armnn::IWorkloadFactory& workloadFactory,
910 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
911 const armnn::DataLayout dataLayout,
912 float inQuantScale,
913 int32_t inQuantOffset,
914 float outQuantScale,
915 int32_t outQuantOffset)
916{
917 armnn::TensorInfo inputTensorInfo = armnn::IsQuantizedType<T>()
918 ? armnnUtils::GetTensorInfo(1, 1, 3, 2, dataLayout, ArmnnType)
919 : armnnUtils::GetTensorInfo(1, 2, 3, 2, dataLayout, ArmnnType);
920
921 armnn::TensorInfo outputTensorInfo = armnn::IsQuantizedType<T>()
922 ? armnnUtils::GetTensorInfo(1, 1, 3, 5, dataLayout, ArmnnType)
923 : armnnUtils::GetTensorInfo(1, 2, 3, 5, dataLayout, ArmnnType);
924
925 if (armnn::IsQuantizedType<T>())
926 {
927 inputTensorInfo.SetQuantizationScale(inQuantScale);
928 inputTensorInfo.SetQuantizationOffset(inQuantOffset);
929 outputTensorInfo.SetQuantizationScale(outQuantScale);
930 outputTensorInfo.SetQuantizationOffset(outQuantOffset);
931 }
932
933 std::vector<float> inputData = armnn::IsQuantizedType<T>()
934 ? std::initializer_list<float>
935 {
936 0.183005f, 2.379065f, // 24, 228, : expected quantised values
937 1.054970f, 1.302565f, // 105, 128,
938 2.400595f, 0.688960f // 230, 71
939 }
940 : std::initializer_list<float>
941 {
942 1.0f, 2.0f,
943 13.0f, 21.0f,
944 144.0f, 233.0f,
945
946 233.0f, 144.0f,
947 21.0f, 13.0f,
948 2.0f, 1.0f
949 };
950
951 std::vector<float> outputData = armnn::IsQuantizedType<T>()
952 ? std::initializer_list<float>
953 {
954 0.183005f, 0.183005f, 0.183005f, 2.379065f, 2.379065f,
955 1.054970f, 1.054970f, 1.054970f, 1.302565f, 1.302565f,
956 2.400595f, 2.400595f, 2.400595f, 0.688960f, 0.688960f
957 }
958 : std::initializer_list<float>
959 {
960 1.f, 1.f, 1.f, 2.f, 2.f,
961 13.f, 13.f, 13.f, 21.f, 21.f,
962 144.f, 144.f, 144.f, 233.f, 233.f,
963
964 233.f, 233.f, 233.f, 144.f, 144.f,
965 21.f, 21.f, 21.f, 13.f, 13.f,
966 2.f, 2.f, 2.f, 1.f, 1.f
967 };
968
969 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
970 if (dataLayout == armnn::DataLayout::NHWC)
971 {
972 std::vector<float> tmp(inputData.size());
973 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
974 inputData = tmp;
975
976 std::vector<float> tmp1(outputData.size());
977 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(float));
978 outputData = tmp1;
979 }
980
981 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(),
982 inputTensorInfo.GetQuantizationOffset(),
983 inputData));
984
985 LayerTestResult<T, 4> result(outputTensorInfo);
986 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo,
987 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(),
988 outputTensorInfo.GetQuantizationOffset(),
989 outputData));
990
991 std::unique_ptr <armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
992 std::unique_ptr <armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
993
994 armnn::ResizeQueueDescriptor descriptor;
995 descriptor.m_Parameters.m_DataLayout = dataLayout;
996 descriptor.m_Parameters.m_Method = armnn::ResizeMethod::NearestNeighbor;
997 armnn::WorkloadInfo info;
998 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
999 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
1000
1001 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResize(descriptor, info);
1002
1003 inputHandle->Allocate();
1004 outputHandle->Allocate();
1005 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
1006
1007 workload->PostAllocationConfigure();
1008 workload->Execute();
1009
1010 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
1011 return result;
1012}