blob: 3befc7c585bdc0066b8924d7997eaad6f8a34148 [file] [log] [blame]
Tamás Nyíri7b885b32021-10-26 14:47:57 +01001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6
7#include "Pooling3dTestImpl.hpp"
8
9#include <QuantizeHelper.hpp>
10#include <ResolveType.hpp>
11
12#include <armnnUtils/TensorUtils.hpp>
13#include <armnnUtils/DataLayoutIndexed.hpp>
14#include <armnnUtils/Permute.hpp>
15
16#include <armnn/utility/IgnoreUnused.hpp>
17#include <armnn/utility/NumericCast.hpp>
18
19#include <armnn/BackendHelper.hpp>
20#include <backendsCommon/WorkloadInfo.hpp>
21
Sadik Armagana097d2a2021-11-24 15:47:28 +000022#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000023#include <armnnTestUtils/WorkloadTestUtils.hpp>
Tamás Nyíri7b885b32021-10-26 14:47:57 +010024
Sadik Armagana097d2a2021-11-24 15:47:28 +000025#include <TensorHelpers.hpp>
Tamás Nyíri7b885b32021-10-26 14:47:57 +010026
27namespace
28{
29
30using namespace armnnUtils;
31
32template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
33LayerTestResult<T, 5> SimplePooling3dTestImpl(
34 armnn::IWorkloadFactory& workloadFactory,
35 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
36 const armnn::ITensorHandleFactory& tensorHandleFactory,
37 armnn::Pooling3dDescriptor descriptor,
38 float qScale,
39 int32_t qOffset,
40 const std::vector<T>& input,
41 const std::vector<T>& outputExpected,
42 const armnn::TensorShape& inputShape,
43 const armnn::TensorShape& outputShape)
44{
45 IgnoreUnused(memoryManager);
46 const armnn::DataLayout dataLayout = descriptor.m_DataLayout;
47 const armnnUtils::DataLayoutIndexed dimensionIndices = dataLayout;
48 auto heightIndex = dimensionIndices.GetHeightIndex();
49 auto widthIndex = dimensionIndices.GetWidthIndex();
50 auto depthIndex = dimensionIndices.GetDepthIndex();
51 auto channelsIndex = dimensionIndices.GetChannelsIndex();
52
53 unsigned int inputDepth = armnn::numeric_cast<unsigned int>(inputShape[depthIndex]);
54 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(inputShape[heightIndex]);
55 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(inputShape[widthIndex]);
56 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(inputShape[channelsIndex]);
57 unsigned int inputBatchSize = armnn::numeric_cast<unsigned int>(inputShape[0]);
58
59 unsigned int outputDepth = armnn::numeric_cast<unsigned int>(outputShape[depthIndex]);
60 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(outputShape[heightIndex]);
61 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(outputShape[widthIndex]);
62 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(outputShape[channelsIndex]);
63 unsigned int outputBatchSize = armnn::numeric_cast<unsigned int>(outputShape[0]);
64
65 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(
66 inputBatchSize, inputChannels, inputDepth, inputHeight, inputWidth, dataLayout, ArmnnType);
67
68 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(
69 outputBatchSize, outputChannels, outputDepth, outputHeight, outputWidth, dataLayout, ArmnnType);
70
71 // Set quantization parameters if the requested type is a quantized type.
72 if (armnn::IsQuantizedType<T>())
73 {
74 inputTensorInfo.SetQuantizationScale(qScale);
75 inputTensorInfo.SetQuantizationOffset(qOffset);
76 outputTensorInfo.SetQuantizationScale(qScale);
77 outputTensorInfo.SetQuantizationOffset(qOffset);
78 }
79
80 LayerTestResult<T, 5> result(outputTensorInfo);
81 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
82
83 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
84 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
85
86 armnn::Pooling3dQueueDescriptor queueDescriptor;
87 queueDescriptor.m_Parameters = descriptor;
88 queueDescriptor.m_Parameters.m_DataLayout = dataLayout;
89
90 armnn::WorkloadInfo workloadInfo;
91 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get());
92 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
93
94 // Don't execute if Pooling is not supported, as an exception will be raised.
95 armnn::BackendId backend = workloadFactory.GetBackendId();
96 std::string reasonIfUnsupported;
97 armnn::LayerSupportHandle handle = armnn::GetILayerSupportByBackendId(backend);
98 result.m_Supported = handle.IsPooling3dSupported(inputTensorInfo,
99 outputTensorInfo,
100 queueDescriptor.m_Parameters,
101 reasonIfUnsupported);
102 if (!result.m_Supported)
103 {
104 return result;
105 }
106
107 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePooling3d(queueDescriptor, workloadInfo);
108
109 inputHandle->Allocate();
110 outputHandle->Allocate();
111
112 CopyDataToITensorHandle(inputHandle.get(), input.data());
113
114 workload->Execute();
115
116 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
117
118 result.m_ActualData = actualOutput;
119 result.m_ExpectedData = outputExpected;
120
121 return result;
122}
123
124//
125// Tests max pooling with the following parameters:
126//
127// Pooling size: 2x2x2
128// Stride: (1,1,1)
129// input size: 3x3x3
130// channels: 2
131// batch size: 2
132//
133template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
134LayerTestResult<T, 5> SimpleMaxPooling3dSize2x2x2Stride1x1x1TestCommon(
135 armnn::IWorkloadFactory& workloadFactory,
136 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
137 const armnn::ITensorHandleFactory& tensorHandleFactory,
138 float qScale = 1.0f,
139 int32_t qOffset = 0)
140{
141 armnn::Pooling3dDescriptor descriptor;
142 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
143 descriptor.m_PoolWidth = 2;
144 descriptor.m_PoolHeight = 2;
145 descriptor.m_PoolDepth = 2;
146 descriptor.m_StrideX = 1;
147 descriptor.m_StrideY = 1;
148 descriptor.m_StrideZ = 1;
149 descriptor.m_PadLeft = descriptor.m_PadRight = 0;
150 descriptor.m_PadTop = descriptor.m_PadBottom = 0;
151 descriptor.m_PadFront = descriptor.m_PadBack = 0;
152 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
153 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
154
155 unsigned int inputWidth = 3;
156 unsigned int inputHeight = 3;
157 unsigned int inputDepth = 3;
158 unsigned int outputWidth =
159 (inputWidth + descriptor.m_PadLeft + descriptor.m_PadRight + descriptor.m_StrideX - descriptor.m_PoolWidth) /
160 descriptor.m_StrideX;
161 unsigned int outputHeight =
162 (inputHeight + descriptor.m_PadTop + descriptor.m_PadBottom + descriptor.m_StrideY - descriptor.m_PoolHeight) /
163 descriptor.m_StrideY;
164 unsigned int outputDepth =
165 (inputDepth + descriptor.m_PadFront + descriptor.m_PadBack + descriptor.m_StrideZ - descriptor.m_PoolDepth) /
166 descriptor.m_StrideZ;
167 unsigned int channels = 2;
168 unsigned int batchSize = 2;
169
170 armnn::TensorInfo inputTensorInfo({ batchSize, channels, inputDepth, inputHeight, inputWidth }, ArmnnType);
171 armnn::TensorInfo outputTensorInfo({ batchSize, channels, outputDepth, outputHeight, outputWidth }, ArmnnType);
172
173 // Set quantization parameters if the requested type is a quantized type.
174 if(armnn::IsQuantizedType<T>())
175 {
176 inputTensorInfo.SetQuantizationScale(qScale);
177 inputTensorInfo.SetQuantizationOffset(qOffset);
178 outputTensorInfo.SetQuantizationScale(qScale);
179 outputTensorInfo.SetQuantizationOffset(qOffset);
180 }
181
182 std::vector<float> singleChannelData({
183 1.0f, 1.0f, 1.0f,
184 1.0f, 1.0f, 1.0f,
185 1.0f, 1.0f, 1.0f,
186
187 1.0f, 1.0f, 1.0f,
188 1.0f, 1.0f, 1.0f,
189 1.0f, 1.0f, 1.0f,
190
191 1.0f, 1.0f, 1.0f,
192 1.0f, 1.0f, 1.0f,
193 1.0f, 1.0f, 1.0f,
194 });
195
196 // Constructs input data.
197 std::vector<float> inputData;
198 auto negator = [](float f) { return -f; };
199
200 // First image (two channels where the second channel is the negative of the first one).
201 inputData.insert(inputData.end(), singleChannelData.begin(), singleChannelData.end());
202 std::transform(singleChannelData.begin(), singleChannelData.end(), std::back_inserter(inputData), negator);
203
204 // Second image (same as first image).
205 inputData.insert(inputData.end(), singleChannelData.begin(), singleChannelData.end());
206 std::transform(singleChannelData.begin(), singleChannelData.end(), std::back_inserter(inputData), negator);
207
208 auto input = QuantizedVector<T>(inputData, qScale, qOffset);
209
210 // These were calculated manually.
211 std::vector<T> outputExpected = QuantizedVector<T>(
212 {
213 1.0f, 1.0f,
214 1.0f, 1.0f,
215
216 1.0f, 1.0f,
217 1.0f, 1.0f,
218
219 -1.0f, -1.0f,
220 -1.0f, -1.0f,
221
222 -1.0f, -1.0f,
223 -1.0f, -1.0f,
224
225
226 1.0f, 1.0f,
227 1.0f, 1.0f,
228
229 1.0f, 1.0f,
230 1.0f, 1.0f,
231
232 -1.0f, -1.0f,
233 -1.0f, -1.0f,
234
235 -1.0f, -1.0f,
236 -1.0f, -1.0f,
237 },
238 qScale, qOffset);
239
240 return SimplePooling3dTestImpl<ArmnnType>(
241 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
242 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
243}
244
245template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
246LayerTestResult<T, 5> SimpleMaxPooling3dTestCommon(
247 armnn::IWorkloadFactory& workloadFactory,
248 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
249 const armnn::ITensorHandleFactory& tensorHandleFactory,
250 const armnn::DataLayout dataLayout = armnn::DataLayout::NCDHW,
251 float qScale = 1.0f,
252 int32_t qOffset = 0)
253{
254 armnn::Pooling3dDescriptor descriptor;
255 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
256 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
257 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
258 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
259 descriptor.m_DataLayout = dataLayout;
260
261 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 4, 4, 4, dataLayout, ArmnnType);
262 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 2, 2, 2, dataLayout, ArmnnType);
263
264 // Set quantization parameters if the requested type is a quantized type.
265 if(armnn::IsQuantizedType<T>())
266 {
267 inputTensorInfo.SetQuantizationScale(qScale);
268 inputTensorInfo.SetQuantizationOffset(qOffset);
269 outputTensorInfo.SetQuantizationScale(qScale);
270 outputTensorInfo.SetQuantizationOffset(qOffset);
271 }
272
273 std::vector<T> inputData(
274 QuantizedVector<T>({
275 1.0f, 2.0f, 5.0f, 6.0f,
276 3.0f, 4.0f, 7.0f, 8.0f,
277 9.0f, 10.0f, 13.0f, 14.0f,
278 11.0f, 12.0f, 15.0f, 16.0f,
279
280 17.0f, 18.0f, 21.0f, 22.0f,
281 19.0f, 20.0f, 23.0f, 24.0f,
282 25.0f, 26.0f, 29.0f, 30.0f,
283 27.0f, 28.0f, 31.0f, 32.0f,
284
285 33.0f, 34.0f, 37.0f, 38.0f,
286 35.0f, 36.0f, 39.0f, 40.0f,
287 41.0f, 42.0f, 45.0f, 46.0f,
288 43.0f, 44.0f, 47.0f, 48.0f,
289
290 49.0f, 50.0f, 53.0f, 54.0f,
291 51.0f, 52.0f, 55.0f, 56.0f,
292 57.0f, 58.0f, 61.0f, 62.0f,
293 59.0f, 60.0f, 63.0f, 64.0f,
294 },
295 qScale, qOffset));
296
297 std::vector<T> outputData(
298 QuantizedVector<T>({
299 20.0f, 24.0f,
300 28.0f, 32.0f,
301
302 52.0f, 56.0f,
303 60.0f, 64.0f,
304 },
305 qScale, qOffset));
306
307 const armnn::PermutationVector NCDHWToNDHWC = { 0, 4, 1, 2, 3 };
308 if (dataLayout == armnn::DataLayout::NDHWC)
309 {
310 std::vector<T> tmp(inputData.size());
311 armnnUtils::Permute(inputTensorInfo.GetShape(), NCDHWToNDHWC, inputData.data(), tmp.data(), sizeof(T));
312 inputData = tmp;
313
314 std::vector<T> tmp1(outputData.size());
315 armnnUtils::Permute(outputTensorInfo.GetShape(), NCDHWToNDHWC, outputData.data(), tmp1.data(), sizeof(T));
316 outputData = tmp1;
317 }
318
319 return SimplePooling3dTestImpl<ArmnnType>(
320 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
321 inputData, outputData, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
322}
323
324template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
325LayerTestResult<T, 5> IgnorePaddingSimpleMaxPooling3dTestCommon(
326 armnn::IWorkloadFactory& workloadFactory,
327 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
328 const armnn::ITensorHandleFactory& tensorHandleFactory,
329 float qScale = 1.0f,
330 int32_t qOffset = 0)
331{
332 armnn::Pooling3dDescriptor descriptor;
333 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
334 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
335 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
336 descriptor.m_PadLeft = 1;
337 descriptor.m_PadRight = 1;
338 descriptor.m_PadTop = 1;
339 descriptor.m_PadBottom = 1;
340 descriptor.m_PadFront = 1;
341 descriptor.m_PadBack = 1;
342 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
343
344 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4, 4 }, ArmnnType);
345 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3, 3 }, ArmnnType);
346
347 // Set quantization parameters if the requested type is a quantized type.
348 if(armnn::IsQuantizedType<T>())
349 {
350 inputTensorInfo.SetQuantizationScale(qScale);
351 inputTensorInfo.SetQuantizationOffset(qOffset);
352 outputTensorInfo.SetQuantizationScale(qScale);
353 outputTensorInfo.SetQuantizationOffset(qOffset);
354 }
355
356 auto input = QuantizedVector<T>(
357 {
358 -1.0f, -2.0f, 3.0f, 4.0f,
359 -1.0f, -2.0f, 3.0f, 4.0f,
360 1.0f, 2.0f, -3.0f, -4.0f,
361 1.0f, 2.0f, -3.0f, -4.0f,
362
363 -1.0f, -2.0f, 3.0f, 4.0f,
364 -1.0f, -2.0f, 3.0f, 4.0f,
365 1.0f, 2.0f, -3.0f, -4.0f,
366 1.0f, 2.0f, -3.0f, -4.0f,
367
368 -1.0f, -2.0f, 3.0f, 4.0f,
369 -1.0f, -2.0f, 3.0f, 4.0f,
370 1.0f, 2.0f, -3.0f, -4.0f,
371 1.0f, 2.0f, -3.0f, -4.0f,
372
373 -1.0f, -2.0f, 3.0f, 4.0f,
374 -1.0f, -2.0f, 3.0f, 4.0f,
375 1.0f, 2.0f, -3.0f, -4.0f,
376 1.0f, 2.0f, -3.0f, -4.0f,
377 },
378 qScale, qOffset);
379
380 auto outputExpected = QuantizedVector<T>(
381 {
382 -1.0f, 3.0f, 4.0f,
383 1.0f, 3.0f, 4.0f,
384 1.0f, 2.0f, -4.0f,
385
386 -1.0f, 3.0f, 4.0f,
387 1.0f, 3.0f, 4.0f,
388 1.0f, 2.0f, -4.0f,
389
390 -1.0f, 3.0f, 4.0f,
391 1.0f, 3.0f, 4.0f,
392 1.0f, 2.0f, -4.0f,
393 },
394 qScale, qOffset);
395
396 return SimplePooling3dTestImpl<ArmnnType>(
397 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
398 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
399}
400
401template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
402LayerTestResult<T, 5> SimpleAveragePooling3dTestCommon(
403 armnn::IWorkloadFactory& workloadFactory,
404 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
405 const armnn::ITensorHandleFactory& tensorHandleFactory,
406 armnn::DataLayout dataLayout = armnn::DataLayout::NCDHW,
407 float qScale = 1.0f,
408 int32_t qOffset = 0)
409{
410 armnn::Pooling3dDescriptor descriptor;
411 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
412 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
413 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
414 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
415 descriptor.m_DataLayout = dataLayout;
416
417 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 4, 4, 4, dataLayout, ArmnnType);
418 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 2, 2, 2, dataLayout, ArmnnType);
419
420 // Set quantization parameters if the requested type is a quantized type.
421 if(armnn::IsQuantizedType<T>())
422 {
423 inputTensorInfo.SetQuantizationScale(qScale);
424 inputTensorInfo.SetQuantizationOffset(qOffset);
425 outputTensorInfo.SetQuantizationScale(qScale);
426 outputTensorInfo.SetQuantizationOffset(qOffset);
427 }
428
429 std::vector<T> inputData(
430 QuantizedVector<T>({
431 1.0f, 2.0f, 5.0f, 6.0f,
432 3.0f, 4.0f, 7.0f, 8.0f,
433 9.0f, 10.0f, 13.0f, 14.0f,
434 11.0f, 12.0f, 15.0f, 16.0f,
435
436 17.0f, 18.0f, 21.0f, 22.0f,
437 19.0f, 20.0f, 23.0f, 24.0f,
438 25.0f, 26.0f, 29.0f, 30.0f,
439 27.0f, 28.0f, 31.0f, 32.0f,
440
441 33.0f, 34.0f, 37.0f, 38.0f,
442 35.0f, 36.0f, 39.0f, 40.0f,
443 41.0f, 42.0f, 45.0f, 46.0f,
444 43.0f, 44.0f, 47.0f, 48.0f,
445
446 49.0f, 50.0f, 53.0f, 54.0f,
447 51.0f, 52.0f, 55.0f, 56.0f,
448 57.0f, 58.0f, 61.0f, 62.0f,
449 59.0f, 60.0f, 63.0f, 64.0f,
450 },
451 qScale, qOffset));
452
453 std::vector<T> outputData(
454 QuantizedVector<T>({
455 10.5f, 14.5f,
456 18.5f, 22.5f,
457
458 42.5f, 46.5f,
459 50.5f, 54.5f,
460 },
461 qScale, qOffset));
462
463 const armnn::PermutationVector NCDHWToNDHWC = { 0, 4, 1, 2, 3 };
464 if (dataLayout == armnn::DataLayout::NDHWC)
465 {
466 std::vector<T> tmp(inputData.size());
467 armnnUtils::Permute(inputTensorInfo.GetShape(), NCDHWToNDHWC, inputData.data(), tmp.data(), sizeof(T));
468 inputData = tmp;
469
470 std::vector<T> tmp1(outputData.size());
471 armnnUtils::Permute(outputTensorInfo.GetShape(), NCDHWToNDHWC, outputData.data(), tmp1.data(), sizeof(T));
472 outputData = tmp1;
473 }
474
475 return SimplePooling3dTestImpl<ArmnnType>(
476 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
477 inputData, outputData, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
478}
479
480template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
481LayerTestResult<T, 5> LargeTensorsAveragePooling3dTestCommon(
482 armnn::IWorkloadFactory& workloadFactory,
483 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
484 const armnn::ITensorHandleFactory& tensorHandleFactory,
485 float qScale = 1.0f,
486 int32_t qOffset = 0)
487{
488 armnn::Pooling3dDescriptor descriptor;
489 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
490 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 100;
491 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 5;
492 descriptor.m_PadLeft = 50;
493 descriptor.m_PadRight = 50;
494 descriptor.m_PadTop = 50;
495 descriptor.m_PadBottom = 50;
496 descriptor.m_PadFront = 50;
497 descriptor.m_PadBack = 50;
498 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
499
500 armnn::TensorInfo inputTensorInfo({ 5, 3, 52, 60, 68 }, ArmnnType);
501 armnn::TensorInfo outputTensorInfo({ 5, 3, 11, 13, 15 }, ArmnnType);
502
503 // Set quantization parameters if the requested type is a quantized type.
504 if(armnn::IsQuantizedType<T>())
505 {
506 inputTensorInfo.SetQuantizationScale(qScale);
507 inputTensorInfo.SetQuantizationOffset(qOffset);
508 outputTensorInfo.SetQuantizationScale(qScale);
509 outputTensorInfo.SetQuantizationOffset(qOffset);
510 }
511
512 std::vector<T> input;
513
514 for (unsigned int i = 0 ; i < inputTensorInfo.GetShape().GetNumElements(); ++i)
515 {
516 input.push_back(1);
517 }
518
519 std::vector<T> outputExpected;
520
521 for (unsigned int i = 0 ; i < outputTensorInfo.GetShape().GetNumElements(); ++i)
522 {
523 outputExpected.push_back(1);
524 }
525
526 return SimplePooling3dTestImpl<ArmnnType>(
527 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
528 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
529}
530
531template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
532LayerTestResult<T, 5> IgnorePaddingSimpleAveragePooling3dTestCommon(
533 armnn::IWorkloadFactory& workloadFactory,
534 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
535 const armnn::ITensorHandleFactory& tensorHandleFactory,
536 float qScale = 1.0f,
537 int32_t qOffset = 0)
538{
539 armnn::Pooling3dDescriptor descriptor;
540 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
541 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
542 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
543 descriptor.m_PadLeft = 1;
544 descriptor.m_PadRight = 1;
545 descriptor.m_PadTop = 1;
546 descriptor.m_PadBottom = 1;
547 descriptor.m_PadFront = 1;
548 descriptor.m_PadBack = 1;
549 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
550
551 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4, 4 }, ArmnnType);
552 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3, 3 }, ArmnnType);
553
554 // Set quantization parameters if the requested type is a quantized type.
555 if(armnn::IsQuantizedType<T>())
556 {
557 inputTensorInfo.SetQuantizationScale(qScale);
558 inputTensorInfo.SetQuantizationOffset(qOffset);
559 outputTensorInfo.SetQuantizationScale(qScale);
560 outputTensorInfo.SetQuantizationOffset(qOffset);
561 }
562
563 auto input = QuantizedVector<T>(
564 {
565 12.0f, 20.0f, 32.0f, 40.0f,
566 12.0f, 20.0f, 32.0f, 40.0f,
567 12.0f, 20.0f, 32.0f, 40.0f,
568 12.0f, 20.0f, 32.0f, 40.0f,
569
570 24.0f, 40.0f, 64.0f, 80.0f,
571 24.0f, 40.0f, 64.0f, 80.0f,
572 24.0f, 40.0f, 64.0f, 80.0f,
573 24.0f, 40.0f, 64.0f, 80.0f,
574
575 36.0f, 60.0f, 96.0f, 120.0f,
576 36.0f, 60.0f, 96.0f, 120.0f,
577 36.0f, 60.0f, 96.0f, 120.0f,
578 36.0f, 60.0f, 96.0f, 120.0f,
579
580 48.0f, 80.0f, 128.0f, 160.0f,
581 48.0f, 80.0f, 128.0f, 160.0f,
582 48.0f, 80.0f, 128.0f, 160.0f,
583 48.0f, 80.0f, 128.0f, 160.0f,
584 },
585 qScale, qOffset);
586
587 auto outputExpected = QuantizedVector<T>(
588 {
589 1.5f, 6.5f, 5.0f,
590 3.0f, 13.0f, 10.0f,
591 1.5f, 6.5f, 5.0f,
592
593 7.5f, 32.5f, 25.0f,
594 15.0f, 65.0f, 50.0f,
595 7.5f, 32.5f, 25.0f,
596
597 6.0f, 26.0f, 20.0f,
598 12.0f, 52.0f, 40.0f,
599 6.0f, 26.0f, 20.0f,
600 },
601 qScale, qOffset);
602
603 return SimplePooling3dTestImpl<ArmnnType>(
604 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
605 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
606}
607
608template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
609LayerTestResult<T, 5> SimpleL2Pooling3dTestCommon(
610 armnn::IWorkloadFactory& workloadFactory,
611 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
612 const armnn::ITensorHandleFactory& tensorHandleFactory,
613 armnn::DataLayout dataLayout = armnn::DataLayout::NCDHW,
614 float qScale = 1.0f,
615 int32_t qOffset = 0)
616{
617 armnn::Pooling3dDescriptor descriptor;
618 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
619 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
620 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
621 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
622 descriptor.m_DataLayout = dataLayout;
623
624 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 4, 4, 4, dataLayout, ArmnnType);
625 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 1, 2, 2, 2, dataLayout, ArmnnType);
626
627 // Set quantization parameters if the requested type is a quantized type.
628 if(armnn::IsQuantizedType<T>())
629 {
630 inputTensorInfo.SetQuantizationScale(qScale);
631 inputTensorInfo.SetQuantizationOffset(qOffset);
632 outputTensorInfo.SetQuantizationScale(qScale);
633 outputTensorInfo.SetQuantizationOffset(qOffset);
634 }
635
636 std::vector<T> inputData(
637 QuantizedVector<T>({
638 1.0f, 2.0f, 5.0f, 6.0f,
639 3.0f, 4.0f, 7.0f, 8.0f,
640 9.0f, 10.0f, 13.0f, 14.0f,
641 11.0f, 12.0f, 15.0f, 16.0f,
642
643 17.0f, 18.0f, 21.0f, 22.0f,
644 19.0f, 20.0f, 23.0f, 24.0f,
645 25.0f, 26.0f, 29.0f, 30.0f,
646 27.0f, 28.0f, 31.0f, 32.0f,
647
648 33.0f, 34.0f, 37.0f, 38.0f,
649 35.0f, 36.0f, 39.0f, 40.0f,
650 41.0f, 42.0f, 45.0f, 46.0f,
651 43.0f, 44.0f, 47.0f, 48.0f,
652
653 49.0f, 50.0f, 53.0f, 54.0f,
654 51.0f, 52.0f, 55.0f, 56.0f,
655 57.0f, 58.0f, 61.0f, 62.0f,
656 59.0f, 60.0f, 63.0f, 64.0f,
657 },
658 qScale, qOffset));
659
660 std::vector<T> outputData(
661 QuantizedVector<T>({
662 13.2476412995f, 16.5981926727f,
663 20.1866292382f, 23.9060661758f,
664
665 43.2608367926f, 47.1963981677f,
666 51.1419592898f, 55.0953718564f,
667 },
668 qScale, qOffset));
669
670 const armnn::PermutationVector NCDHWToNDHWC = { 0, 4, 1, 2, 3 };
671 if (dataLayout == armnn::DataLayout::NDHWC)
672 {
673 std::vector<T> tmp(inputData.size());
674 armnnUtils::Permute(inputTensorInfo.GetShape(), NCDHWToNDHWC, inputData.data(), tmp.data(), sizeof(T));
675 inputData = tmp;
676
677 std::vector<T> tmp1(outputData.size());
678 armnnUtils::Permute(outputTensorInfo.GetShape(), NCDHWToNDHWC, outputData.data(), tmp1.data(), sizeof(T));
679 outputData = tmp1;
680 }
681
682 return SimplePooling3dTestImpl<ArmnnType>(
683 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
684 inputData, outputData, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
685}
686
687template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
688LayerTestResult<T, 5> IgnorePaddingSimpleL2Pooling3dTestCommon(
689 armnn::IWorkloadFactory& workloadFactory,
690 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
691 const armnn::ITensorHandleFactory& tensorHandleFactory,
692 float qScale = 1.0f,
693 int32_t qOffset = 0)
694{
695 armnn::Pooling3dDescriptor descriptor;
696 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
697 descriptor.m_PoolWidth = descriptor.m_PoolHeight = descriptor.m_PoolDepth = 2;
698 descriptor.m_StrideX = descriptor.m_StrideY = descriptor.m_StrideZ = 2;
699 descriptor.m_PadLeft = 1;
700 descriptor.m_PadRight = 1;
701 descriptor.m_PadTop = 1;
702 descriptor.m_PadBottom = 1;
703 descriptor.m_PadFront = 1;
704 descriptor.m_PadBack = 1;
705 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
706
707 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4, 4 }, ArmnnType);
708 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3, 3 }, ArmnnType);
709
710 // Set quantization parameters if the requested type is a quantized type.
711 if(armnn::IsQuantizedType<T>())
712 {
713 inputTensorInfo.SetQuantizationScale(qScale);
714 inputTensorInfo.SetQuantizationOffset(qOffset);
715 outputTensorInfo.SetQuantizationScale(qScale);
716 outputTensorInfo.SetQuantizationOffset(qOffset);
717 }
718
719 auto input = QuantizedVector<T>(
720 {
721 1.0f, 2.0f, 3.0f, 4.0f,
722 1.0f, 2.0f, 3.0f, 4.0f,
723 1.0f, 2.0f, 3.0f, 4.0f,
724 1.0f, 2.0f, 3.0f, 4.0f,
725
726 2.0f, 3.0f, 4.0f, 5.0f,
727 2.0f, 3.0f, 4.0f, 5.0f,
728 2.0f, 3.0f, 4.0f, 5.0f,
729 2.0f, 3.0f, 4.0f, 5.0f,
730
731 3.0f, 4.0f, 5.0f, 6.0f,
732 3.0f, 4.0f, 5.0f, 6.0f,
733 3.0f, 4.0f, 5.0f, 6.0f,
734 3.0f, 4.0f, 5.0f, 6.0f,
735
736 4.0f, 5.0f, 6.0f, 7.0f,
737 4.0f, 5.0f, 6.0f, 7.0f,
738 4.0f, 5.0f, 6.0f, 7.0f,
739 4.0f, 5.0f, 6.0f, 7.0f,
740 },
741 qScale, qOffset);
742
743 float v111 = float(sqrt(pow(1,2)/8.0f));
744 float v112 = float(sqrt((pow(2,2)+pow(3,2))/8.0f));
745 float v113 = float(sqrt(pow(4,2)/8));
746
747 float v121 = float(sqrt((2*pow(1,2))/8.0f));
748 float v122 = float(sqrt((2*pow(2,2)+2*pow(3,2))/8.0f));
749 float v123 = float(sqrt((2*pow(4,2))/8.0f));
750
751 float v131 = v111;
752 float v132 = v112;
753 float v133 = v113;
754
755 float v211 = float(sqrt((pow(2,2)+pow(3,2))/8.0f));
756 float v212 = float(sqrt((pow(3,2)+2*pow(4,2)+pow(5,2))/8.0f));
757 float v213 = float(sqrt((pow(5,2)+pow(6,2))/8.0f));
758
759 float v221 = float(sqrt((2*pow(2,2)+2*pow(3,2))/8.0f));
760 float v222 = float(sqrt((2*pow(3,2)+4*pow(4,2)+2*pow(5,2))/8.0f));
761 float v223 = float(sqrt((2*pow(5,2)+2*pow(6,2))/8.0f));
762
763 float v231 = v211;
764 float v232 = v212;
765 float v233 = v213;
766
767 float v311 = float(sqrt(pow(4,2)/8.0f));
768 float v312 = float(sqrt((pow(5,2)+pow(6,2))/8.0f));
769 float v313 = float(sqrt(pow(7,2)/8));
770
771 float v321 = float(sqrt((2*pow(4,2))/8.0f));
772 float v322 = float(sqrt((2*pow(5,2)+2*pow(6,2))/8.0f));
773 float v323 = float(sqrt((2*pow(7,2))/8.0f));
774
775 float v331 = v311;
776 float v332 = v312;
777 float v333 = v313;
778
779 auto outputExpected = QuantizedVector<T>(
780 {
781 v111, v112, v113,
782 v121, v122, v123,
783 v131, v132, v133,
784
785 v211, v212, v213,
786 v221, v222, v223,
787 v231, v232, v233,
788
789 v311, v312, v313,
790 v321, v322, v323,
791 v331, v332, v333,
792 },
793 qScale, qOffset);
794
795 return SimplePooling3dTestImpl<ArmnnType>(
796 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
797 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
798}
799
800template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
801LayerTestResult<T, 5> AsymmetricNonSquareMaxPooling3dTestCommon(
802 armnn::IWorkloadFactory& workloadFactory,
803 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
804 const armnn::ITensorHandleFactory& tensorHandleFactory,
805 float qScale = 1.0f,
806 int32_t qOffset = 0)
807{
808 armnn::TensorInfo inputTensorInfo({ 1, 1, 1, 3, 1 }, ArmnnType);
809 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2, 1 }, ArmnnType);
810
811 armnn::Pooling3dDescriptor descriptor;
812 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
813 descriptor.m_PoolWidth = 1;
814 descriptor.m_PoolHeight = 2;
815 descriptor.m_PoolDepth = 3;
816 descriptor.m_StrideX = 0;
817 descriptor.m_StrideY = 2;
818 descriptor.m_StrideZ = 1;
819 descriptor.m_PadLeft = 0;
820 descriptor.m_PadRight = 0;
821 descriptor.m_PadTop = 2;
822 descriptor.m_PadBottom = 0;
823 descriptor.m_PadFront = 1;
824 descriptor.m_PadBack = 2;
825 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
826 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
827
828 // Construct input data.
829 auto input = QuantizedVector<T>(
830 {
831 1.0f, 3.0f, 4.0f,
832 },
833 qScale, qOffset);
834
835 // These were calculated manually.
836 auto outputExpected = QuantizedVector<T>(
837 {
838 0.0f, 3.0f, 0.0f, 3.0f,
839 },
840 qScale, qOffset);
841
842 return SimplePooling3dTestImpl<ArmnnType>(
843 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
844 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
845}
846
847template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
848LayerTestResult<T, 5> AsymmetricNonSquareAveragePooling3dTestCommon(
849 armnn::IWorkloadFactory& workloadFactory,
850 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
851 const armnn::ITensorHandleFactory& tensorHandleFactory,
852 float qScale = 1.0f,
853 int32_t qOffset = 0)
854{
855 armnn::TensorInfo inputTensorInfo({ 1, 1, 1, 3, 1 }, ArmnnType);
856 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2, 1 }, ArmnnType);
857
858 armnn::Pooling3dDescriptor descriptor;
859 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
860 descriptor.m_PoolWidth = 1;
861 descriptor.m_PoolHeight = 2;
862 descriptor.m_PoolDepth = 3;
863 descriptor.m_StrideX = 0;
864 descriptor.m_StrideY = 2;
865 descriptor.m_StrideZ = 1;
866 descriptor.m_PadLeft = 0;
867 descriptor.m_PadRight = 0;
868 descriptor.m_PadTop = 2;
869 descriptor.m_PadBottom = 0;
870 descriptor.m_PadFront = 1;
871 descriptor.m_PadBack = 2;
872 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
873 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
874
875 // Construct input data.
876 auto input = QuantizedVector<T>(
877 {
878 1.0f, 3.0f, 4.0f,
879 },
880 qScale, qOffset);
881
882 // These were calculated manually.
883 auto outputExpected = QuantizedVector<T>(
884 {
885 0.0f, 2.0f, 0.0f, 2.0f,
886 },
887 qScale, qOffset);
888
889 return SimplePooling3dTestImpl<ArmnnType>(
890 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
891 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
892}
893
894template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
895LayerTestResult<T, 5> AsymmetricNonSquareL2Pooling3dTestCommon(
896 armnn::IWorkloadFactory& workloadFactory,
897 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
898 const armnn::ITensorHandleFactory& tensorHandleFactory,
899 float qScale = 1.0f,
900 int32_t qOffset = 0)
901{
902 armnn::TensorInfo inputTensorInfo({ 1, 1, 1, 3, 1 }, ArmnnType);
903 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2, 1 }, ArmnnType);
904
905 armnn::Pooling3dDescriptor descriptor;
906 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
907 descriptor.m_PoolWidth = 1;
908 descriptor.m_PoolHeight = 2;
909 descriptor.m_PoolDepth = 3;
910 descriptor.m_StrideX = 0;
911 descriptor.m_StrideY = 2;
912 descriptor.m_StrideZ = 1;
913 descriptor.m_PadLeft = 0;
914 descriptor.m_PadRight = 0;
915 descriptor.m_PadTop = 2;
916 descriptor.m_PadBottom = 0;
917 descriptor.m_PadFront = 1;
918 descriptor.m_PadBack = 2;
919 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
920 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
921
922 // Construct input data.
923 auto input = QuantizedVector<T>(
924 {
925 1.0f, 3.0f, 4.0f,
926 },
927 qScale, qOffset);
928
929 // These were calculated manually.
930 auto outputExpected = QuantizedVector<T>(
931 {
932 0.0f, 2.2360679775f, 0.0f, 2.2360679775f,
933 },
934 qScale, qOffset);
935
936 return SimplePooling3dTestImpl<ArmnnType>(
937 workloadFactory, memoryManager, tensorHandleFactory, descriptor, qScale, qOffset,
938 input, outputExpected, inputTensorInfo.GetShape(), outputTensorInfo.GetShape());
939}
940
941template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
942LayerTestResult<T, 5> ComparePooling3dTestCommon(
943 armnn::IWorkloadFactory& workloadFactory,
944 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
945 armnn::IWorkloadFactory& refWorkloadFactory,
946 const armnn::ITensorHandleFactory& tensorHandleFactory,
947 const armnn::ITensorHandleFactory& refTensorHandleFactory,
948 armnn::PoolingAlgorithm poolingType,
949 float qScale = 1.0f,
950 int32_t qOffset = 0)
951{
952 IgnoreUnused(memoryManager);
953 const unsigned int inputWidth = 16;
954 const unsigned int inputHeight = 32;
955 const unsigned int inputDepth = 48;
956 const unsigned int channelCount = 2;
957 const unsigned int batchSize = 5;
958
959 const unsigned int poolSize = 3;
960 const unsigned int strideX = 2;
961 const unsigned int strideY = 4;
962 const unsigned int strideZ = 6;
963 const unsigned int padX = 0;
964 const unsigned int padY = 0;
965 const unsigned int padZ = 0;
966
967 const unsigned int outputWidth = (inputWidth + 2 * padX + strideX - poolSize) / strideX;
968 const unsigned int outputHeight = (inputHeight + 2 * padY + strideY - poolSize) / strideY;
969 const unsigned int outputDepth = (inputDepth + 2 * padZ + strideZ - poolSize) / strideZ;
970
971 armnn::TensorInfo inputTensorInfo;
972 armnn::TensorInfo outputTensorInfo;
973
974 unsigned int inputShape[] = { batchSize, channelCount, inputHeight, inputWidth, inputDepth };
975 unsigned int outputShape[] = { batchSize, channelCount, outputHeight, outputWidth, outputDepth };
976
977 inputTensorInfo = armnn::TensorInfo(5, inputShape, ArmnnType);
978 outputTensorInfo = armnn::TensorInfo(5, outputShape, ArmnnType);
979
980 // Set quantization parameters if the requested type is a quantized type.
981 if(armnn::IsQuantizedType<T>())
982 {
983 inputTensorInfo.SetQuantizationScale(qScale);
984 inputTensorInfo.SetQuantizationOffset(qOffset);
985 outputTensorInfo.SetQuantizationScale(qScale);
986 outputTensorInfo.SetQuantizationOffset(qOffset);
987 }
988
989 std::vector<T> input = MakeRandomTensor<T>(inputTensorInfo, 81715);
990 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
991 std::vector<T> expectedOutput(outputTensorInfo.GetNumElements());
992
993 LayerTestResult<T, 5> comparisonResult(outputTensorInfo);
994
995 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
996 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
997
998 armnn::Pooling3dQueueDescriptor data;
999 armnn::WorkloadInfo info;
1000 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1001 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1002 data.m_Parameters.m_PoolType = poolingType;
1003 data.m_Parameters.m_PoolWidth = poolSize;
1004 data.m_Parameters.m_PoolHeight = poolSize;
1005 data.m_Parameters.m_PoolDepth = poolSize;
1006 data.m_Parameters.m_StrideX = strideX;
1007 data.m_Parameters.m_StrideY = strideY;
1008 data.m_Parameters.m_StrideZ = strideZ;
1009 data.m_Parameters.m_PadLeft = padX;
1010 data.m_Parameters.m_PadRight = padX;
1011 data.m_Parameters.m_PadTop = padY;
1012 data.m_Parameters.m_PadBottom = padY;
1013 data.m_Parameters.m_PadFront = padZ;
1014 data.m_Parameters.m_PadBack = padZ;
1015 data.m_Parameters.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
1016
1017 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1018 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1019
1020 // Don't execute if Pooling is not supported, as an exception will be raised.
1021 armnn::BackendId backend = workloadFactory.GetBackendId();
1022 std::string reasonIfUnsupported;
1023 armnn::LayerSupportHandle handle = armnn::GetILayerSupportByBackendId(backend);
1024 comparisonResult.m_Supported = handle.IsPooling3dSupported(inputTensorInfo,
1025 outputTensorInfo,
1026 data.m_Parameters,
1027 reasonIfUnsupported);
1028 if (!comparisonResult.m_Supported)
1029 {
1030 return comparisonResult;
1031 }
1032
1033 armnn::Pooling3dQueueDescriptor refData = data;
1034 armnn::WorkloadInfo refInfo = info;
1035 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
1036 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1037
1038 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePooling3d(data, info);
1039 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreatePooling3d(refData, refInfo);
1040
1041 outputHandleRef->Allocate();
1042 inputHandleRef->Allocate();
1043 inputHandle->Allocate();
1044 outputHandle->Allocate();
1045
1046 CopyDataToITensorHandle(inputHandle.get(), input.data());
1047 CopyDataToITensorHandle(inputHandleRef.get(), input.data());
1048
1049 workload->Execute();
1050 workloadRef->Execute();
1051
1052 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1053 CopyDataFromITensorHandle(expectedOutput.data(), outputHandleRef.get());
1054
1055 comparisonResult.m_ActualData = actualOutput;
1056 comparisonResult.m_ExpectedData = expectedOutput;
1057
1058 return comparisonResult;
1059}
1060
1061
1062} // anonymous namespace
1063
1064LayerTestResult<float, 5> SimpleMaxPooling3dSize2x2x2Stride1x1x1Test(
1065 armnn::IWorkloadFactory& workloadFactory,
1066 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1067 const armnn::ITensorHandleFactory& tensorHandleFactory)
1068{
1069 return SimpleMaxPooling3dSize2x2x2Stride1x1x1TestCommon<armnn::DataType::Float32>(
1070 workloadFactory, memoryManager, tensorHandleFactory);
1071}
1072
1073LayerTestResult<uint8_t, 5> SimpleMaxPooling3dSize2x2x2Stride1x1x1Uint8Test(
1074 armnn::IWorkloadFactory& workloadFactory,
1075 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1076 const armnn::ITensorHandleFactory& tensorHandleFactory)
1077{
1078 return SimpleMaxPooling3dSize2x2x2Stride1x1x1TestCommon<armnn::DataType::QAsymmU8>(
1079 workloadFactory, memoryManager, tensorHandleFactory, 0.1f, 128);
1080}
1081
1082LayerTestResult<int16_t, 5> SimpleMaxPooling3dSize2x2x2Stride1x1x1Int16Test(
1083 armnn::IWorkloadFactory& workloadFactory,
1084 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1085 const armnn::ITensorHandleFactory& tensorHandleFactory)
1086{
1087 return SimpleMaxPooling3dSize2x2x2Stride1x1x1TestCommon<armnn::DataType::QSymmS16>(
1088 workloadFactory, memoryManager, tensorHandleFactory);
1089}
1090
1091LayerTestResult<float, 5> SimpleMaxPooling3dTest(
1092 armnn::IWorkloadFactory& workloadFactory,
1093 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1094 const armnn::ITensorHandleFactory& tensorHandleFactory,
1095 const armnn::DataLayout dataLayout)
1096{
1097 return SimpleMaxPooling3dTestCommon<armnn::DataType::Float32>(
1098 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1099}
1100
1101LayerTestResult<uint8_t, 5> SimpleMaxPooling3dUint8Test(
1102 armnn::IWorkloadFactory& workloadFactory,
1103 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1104 const armnn::ITensorHandleFactory& tensorHandleFactory,
1105 const armnn::DataLayout dataLayout)
1106{
1107 return SimpleMaxPooling3dTestCommon<armnn::DataType::QAsymmU8>(
1108 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1109}
1110
1111LayerTestResult<int16_t, 5> SimpleMaxPooling3dInt16Test(
1112 armnn::IWorkloadFactory& workloadFactory,
1113 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1114 const armnn::ITensorHandleFactory& tensorHandleFactory,
1115 const armnn::DataLayout dataLayout)
1116{
1117 return SimpleMaxPooling3dTestCommon<armnn::DataType::QSymmS16>(
1118 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1119}
1120
1121LayerTestResult<float, 5> IgnorePaddingSimpleMaxPooling3dTest(
1122 armnn::IWorkloadFactory& workloadFactory,
1123 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1124 const armnn::ITensorHandleFactory& tensorHandleFactory)
1125{
1126 return IgnorePaddingSimpleMaxPooling3dTestCommon<armnn::DataType::Float32>(
1127 workloadFactory, memoryManager, tensorHandleFactory);
1128}
1129
1130LayerTestResult<uint8_t, 5> IgnorePaddingSimpleMaxPooling3dUint8Test(
1131 armnn::IWorkloadFactory& workloadFactory,
1132 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1133 const armnn::ITensorHandleFactory& tensorHandleFactory)
1134{
1135 return IgnorePaddingSimpleMaxPooling3dTestCommon<armnn::DataType::QAsymmU8>(
1136 workloadFactory, memoryManager, tensorHandleFactory, 1.0f, -5);
1137}
1138
1139LayerTestResult<int16_t, 5> IgnorePaddingSimpleMaxPooling3dInt16Test(
1140 armnn::IWorkloadFactory& workloadFactory,
1141 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1142 const armnn::ITensorHandleFactory& tensorHandleFactory)
1143{
1144 return IgnorePaddingSimpleMaxPooling3dTestCommon<armnn::DataType::QSymmS16>(
1145 workloadFactory, memoryManager, tensorHandleFactory);
1146}
1147
1148LayerTestResult<float, 5> SimpleAveragePooling3dTest(
1149 armnn::IWorkloadFactory& workloadFactory,
1150 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1151 const armnn::ITensorHandleFactory& tensorHandleFactory,
1152 const armnn::DataLayout dataLayout)
1153{
1154 return SimpleAveragePooling3dTestCommon<armnn::DataType::Float32>(
1155 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1156}
1157
1158LayerTestResult<uint8_t, 5> SimpleAveragePooling3dUint8Test(
1159 armnn::IWorkloadFactory& workloadFactory,
1160 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1161 const armnn::ITensorHandleFactory& tensorHandleFactory,
1162 const armnn::DataLayout dataLayout)
1163{
1164 return SimpleAveragePooling3dTestCommon<armnn::DataType::QAsymmU8>(
1165 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1166}
1167
1168LayerTestResult<int16_t, 5> SimpleAveragePooling3dInt16Test(
1169 armnn::IWorkloadFactory& workloadFactory,
1170 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1171 const armnn::ITensorHandleFactory& tensorHandleFactory,
1172 const armnn::DataLayout dataLayout)
1173{
1174 return SimpleAveragePooling3dTestCommon<armnn::DataType::QSymmS16>(
1175 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1176}
1177
1178LayerTestResult<float, 5> SimpleL2Pooling3dTest(
1179 armnn::IWorkloadFactory& workloadFactory,
1180 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1181 const armnn::ITensorHandleFactory& tensorHandleFactory,
1182 const armnn::DataLayout dataLayout)
1183{
1184 return SimpleL2Pooling3dTestCommon<armnn::DataType::Float32>(
1185 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1186}
1187
1188LayerTestResult<uint8_t, 5> SimpleL2Pooling3dUint8Test(
1189 armnn::IWorkloadFactory& workloadFactory,
1190 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1191 const armnn::ITensorHandleFactory& tensorHandleFactory,
1192 const armnn::DataLayout dataLayout)
1193{
1194 return SimpleL2Pooling3dTestCommon<armnn::DataType::QAsymmU8>(
1195 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1196}
1197
1198LayerTestResult<int16_t, 5> SimpleL2Pooling3dInt16Test(
1199 armnn::IWorkloadFactory& workloadFactory,
1200 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1201 const armnn::ITensorHandleFactory& tensorHandleFactory,
1202 const armnn::DataLayout dataLayout)
1203{
1204 return SimpleL2Pooling3dTestCommon<armnn::DataType::QSymmS16>(
1205 workloadFactory, memoryManager, tensorHandleFactory, dataLayout);
1206}
1207
1208LayerTestResult<float, 5> LargeTensorsAveragePooling3dTest(
1209 armnn::IWorkloadFactory& workloadFactory,
1210 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1211 const armnn::ITensorHandleFactory& tensorHandleFactory)
1212{
1213 return LargeTensorsAveragePooling3dTestCommon<armnn::DataType::Float32>(
1214 workloadFactory, memoryManager, tensorHandleFactory);
1215}
1216
1217LayerTestResult<uint8_t, 5> LargeTensorsAveragePooling3dUint8Test(
1218 armnn::IWorkloadFactory& workloadFactory,
1219 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1220 const armnn::ITensorHandleFactory& tensorHandleFactory)
1221{
1222 return LargeTensorsAveragePooling3dTestCommon<armnn::DataType::QAsymmU8>(
1223 workloadFactory, memoryManager, tensorHandleFactory, 0.5, -1);
1224}
1225
1226LayerTestResult<int16_t, 5> LargeTensorsAveragePooling3dInt16Test(
1227 armnn::IWorkloadFactory& workloadFactory,
1228 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1229 const armnn::ITensorHandleFactory& tensorHandleFactory)
1230{
1231 return LargeTensorsAveragePooling3dTestCommon<armnn::DataType::QSymmS16>(
1232 workloadFactory, memoryManager, tensorHandleFactory);
1233}
1234
1235LayerTestResult<float, 5> IgnorePaddingSimpleAveragePooling3dTest(
1236 armnn::IWorkloadFactory& workloadFactory,
1237 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1238 const armnn::ITensorHandleFactory& tensorHandleFactory)
1239{
1240 return IgnorePaddingSimpleAveragePooling3dTestCommon<armnn::DataType::Float32>(
1241 workloadFactory, memoryManager, tensorHandleFactory);
1242}
1243
1244LayerTestResult<uint8_t, 5> IgnorePaddingSimpleAveragePooling3dUint8Test(
1245 armnn::IWorkloadFactory& workloadFactory,
1246 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1247 const armnn::ITensorHandleFactory& tensorHandleFactory)
1248{
1249 return IgnorePaddingSimpleAveragePooling3dTestCommon<armnn::DataType::QAsymmU8>(
1250 workloadFactory, memoryManager, tensorHandleFactory, 1.0f, -5);
1251}
1252
1253LayerTestResult<int16_t, 5> IgnorePaddingSimpleAveragePooling3dInt16Test(
1254 armnn::IWorkloadFactory& workloadFactory,
1255 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1256 const armnn::ITensorHandleFactory& tensorHandleFactory)
1257{
1258 return IgnorePaddingSimpleAveragePooling3dTestCommon<armnn::DataType::QSymmS16>(
1259 workloadFactory, memoryManager, tensorHandleFactory);
1260}
1261
1262LayerTestResult<float, 5> IgnorePaddingSimpleL2Pooling3dTest(
1263 armnn::IWorkloadFactory& workloadFactory,
1264 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1265 const armnn::ITensorHandleFactory& tensorHandleFactory)
1266{
1267 return IgnorePaddingSimpleL2Pooling3dTestCommon<armnn::DataType::Float32>(
1268 workloadFactory, memoryManager, tensorHandleFactory);
1269}
1270
1271LayerTestResult<uint8_t, 5> IgnorePaddingSimpleL2Pooling3dUint8Test(
1272 armnn::IWorkloadFactory& workloadFactory,
1273 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1274 const armnn::ITensorHandleFactory& tensorHandleFactory)
1275{
1276 return IgnorePaddingSimpleL2Pooling3dTestCommon<armnn::DataType::QAsymmU8>(
1277 workloadFactory, memoryManager, tensorHandleFactory, 1.0f, -5);
1278}
1279
1280LayerTestResult<int16_t, 5> IgnorePaddingSimpleL2Pooling3dInt16Test(
1281 armnn::IWorkloadFactory& workloadFactory,
1282 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1283 const armnn::ITensorHandleFactory& tensorHandleFactory)
1284{
1285 return IgnorePaddingSimpleL2Pooling3dTestCommon<armnn::DataType::QSymmS16>(
1286 workloadFactory, memoryManager, tensorHandleFactory);
1287}
1288
1289LayerTestResult<float, 5> AsymmetricNonSquareMaxPooling3dTest(
1290 armnn::IWorkloadFactory& workloadFactory,
1291 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1292 const armnn::ITensorHandleFactory& tensorHandleFactory)
1293{
1294 return AsymmetricNonSquareMaxPooling3dTestCommon<armnn::DataType::Float32>(
1295 workloadFactory, memoryManager, tensorHandleFactory);
1296}
1297
1298LayerTestResult<uint8_t, 5> AsymmetricNonSquareMaxPooling3dUint8Test(
1299 armnn::IWorkloadFactory& workloadFactory,
1300 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1301 const armnn::ITensorHandleFactory& tensorHandleFactory)
1302{
1303 return AsymmetricNonSquareMaxPooling3dTestCommon<armnn::DataType::QAsymmU8>(
1304 workloadFactory, memoryManager, tensorHandleFactory);
1305}
1306
1307LayerTestResult<int16_t, 5> AsymmetricNonSquareMaxPooling3dInt16Test(
1308 armnn::IWorkloadFactory& workloadFactory,
1309 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1310 const armnn::ITensorHandleFactory& tensorHandleFactory)
1311{
1312 return AsymmetricNonSquareMaxPooling3dTestCommon<armnn::DataType::QSymmS16>(
1313 workloadFactory, memoryManager, tensorHandleFactory);
1314}
1315
1316LayerTestResult<float, 5> AsymmetricNonSquareAveragePooling3dTest(
1317 armnn::IWorkloadFactory& workloadFactory,
1318 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1319 const armnn::ITensorHandleFactory& tensorHandleFactory)
1320{
1321 return AsymmetricNonSquareAveragePooling3dTestCommon<armnn::DataType::Float32>(
1322 workloadFactory, memoryManager, tensorHandleFactory);
1323}
1324
1325LayerTestResult<uint8_t, 5> AsymmetricNonSquareAveragePooling3dUint8Test(
1326 armnn::IWorkloadFactory& workloadFactory,
1327 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1328 const armnn::ITensorHandleFactory& tensorHandleFactory)
1329{
1330 return AsymmetricNonSquareAveragePooling3dTestCommon<armnn::DataType::QAsymmU8>(
1331 workloadFactory, memoryManager, tensorHandleFactory);
1332}
1333
1334LayerTestResult<int16_t, 5> AsymmetricNonSquareAveragePooling3dInt16Test(
1335 armnn::IWorkloadFactory& workloadFactory,
1336 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1337 const armnn::ITensorHandleFactory& tensorHandleFactory)
1338{
1339 return AsymmetricNonSquareAveragePooling3dTestCommon<armnn::DataType::QSymmS16>(
1340 workloadFactory, memoryManager, tensorHandleFactory);
1341}
1342
1343LayerTestResult<float, 5> AsymmetricNonSquareL2Pooling3dTest(
1344 armnn::IWorkloadFactory& workloadFactory,
1345 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1346 const armnn::ITensorHandleFactory& tensorHandleFactory)
1347{
1348 return AsymmetricNonSquareL2Pooling3dTestCommon<armnn::DataType::Float32>(
1349 workloadFactory, memoryManager, tensorHandleFactory);
1350}
1351
1352LayerTestResult<uint8_t, 5> AsymmetricNonSquareL2Pooling3dUint8Test(
1353 armnn::IWorkloadFactory& workloadFactory,
1354 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1355 const armnn::ITensorHandleFactory& tensorHandleFactory)
1356{
1357 return AsymmetricNonSquareL2Pooling3dTestCommon<armnn::DataType::QAsymmU8>(
1358 workloadFactory, memoryManager, tensorHandleFactory);
1359}
1360
1361LayerTestResult<int16_t, 5> AsymmetricNonSquareL2Pooling3dInt16Test(
1362 armnn::IWorkloadFactory& workloadFactory,
1363 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1364 const armnn::ITensorHandleFactory& tensorHandleFactory)
1365{
1366 return AsymmetricNonSquareL2Pooling3dTestCommon<armnn::DataType::QSymmS16>(
1367 workloadFactory, memoryManager, tensorHandleFactory);
1368}
1369
1370LayerTestResult<float, 5> ComparePooling3dTest(
1371 armnn::IWorkloadFactory& workloadFactory,
1372 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1373 armnn::IWorkloadFactory& refWorkloadFactory,
1374 const armnn::ITensorHandleFactory& tensorHandleFactory,
1375 const armnn::ITensorHandleFactory& refTensorHandleFactory,
1376 armnn::PoolingAlgorithm poolingType)
1377{
1378 return ComparePooling3dTestCommon<armnn::DataType::Float32>(
1379 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, poolingType);
1380}
1381
1382LayerTestResult<uint8_t, 5> ComparePooling3dUint8Test(
1383 armnn::IWorkloadFactory& workloadFactory,
1384 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1385 armnn::IWorkloadFactory& refWorkloadFactory,
1386 const armnn::ITensorHandleFactory& tensorHandleFactory,
1387 const armnn::ITensorHandleFactory& refTensorHandleFactory,
1388 armnn::PoolingAlgorithm poolingType)
1389{
1390 return ComparePooling3dTestCommon<armnn::DataType::QAsymmU8>(
1391 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory,
1392 poolingType, 0.1f, 128);
1393}
1394
1395LayerTestResult<int16_t, 5> ComparePooling3dInt16Test(
1396 armnn::IWorkloadFactory& workloadFactory,
1397 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1398 armnn::IWorkloadFactory& refWorkloadFactory,
1399 const armnn::ITensorHandleFactory& tensorHandleFactory,
1400 const armnn::ITensorHandleFactory& refTensorHandleFactory,
1401 armnn::PoolingAlgorithm poolingType)
1402{
1403 return ComparePooling3dTestCommon<armnn::DataType::QSymmS16>(
1404 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, poolingType);
1405}