blob: 5edf9c802ffdfadf0dea53a0ea76a7d2e5c68360 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
5#pragma once
6
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00007#include "WorkloadTestUtils.hpp"
Nina Drozdd41b2592018-11-19 13:03:36 +00008#include "TensorUtils.hpp"
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00009
telsoa014fcda012018-03-09 14:13:49 +000010#include "QuantizeHelper.hpp"
11
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <armnn/ArmNN.hpp>
13
14#include <Permute.hpp>
15
16#include <backendsCommon/CpuTensorHandle.hpp>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000017#include <backendsCommon/IBackendInternal.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000018#include <backendsCommon/WorkloadFactory.hpp>
19#include <backendsCommon/WorkloadInfo.hpp>
20
21#include <test/TensorHelpers.hpp>
22
Matteo Martincigh21350152018-11-28 16:22:22 +000023#include <DataLayoutIndexed.hpp>
24
James Conroy45a9b772018-10-31 11:47:53 +000025#include <boost/numeric/conversion/cast.hpp>
telsoa014fcda012018-03-09 14:13:49 +000026
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000027#include <algorithm>
28#include <string>
29
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +000030template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000031LayerTestResult<T, 4> SimplePooling2dTestImpl(
32 armnn::IWorkloadFactory& workloadFactory,
33 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
34 armnn::Pooling2dDescriptor descriptor,
35 float qScale,
36 int32_t qOffset,
37 const boost::multi_array<T, 4>& input,
38 const boost::multi_array<T, 4>& outputExpected)
telsoa014fcda012018-03-09 14:13:49 +000039{
Matthew Bentham8800c002018-11-19 13:19:28 +000040 const armnn::DataLayout dataLayout = descriptor.m_DataLayout;
Matteo Martincigh21350152018-11-28 16:22:22 +000041 const armnnUtils::DataLayoutIndexed dimensionIndices = dataLayout;
Matthew Bentham8800c002018-11-19 13:19:28 +000042 auto heightIndex = dimensionIndices.GetHeightIndex();
43 auto widthIndex = dimensionIndices.GetWidthIndex();
44 auto channelsIndex = dimensionIndices.GetChannelsIndex();
telsoa014fcda012018-03-09 14:13:49 +000045
James Conroy69482272018-10-19 10:41:35 +010046 unsigned int inputHeight = boost::numeric_cast<unsigned int>(input.shape()[heightIndex]);
47 unsigned int inputWidth = boost::numeric_cast<unsigned int>(input.shape()[widthIndex]);
48 unsigned int inputChannels = boost::numeric_cast<unsigned int>(input.shape()[channelsIndex]);
49 unsigned int inputBatchSize = boost::numeric_cast<unsigned int>(input.shape()[0]);
50
51 unsigned int outputHeight = boost::numeric_cast<unsigned int>(outputExpected.shape()[heightIndex]);
52 unsigned int outputWidth = boost::numeric_cast<unsigned int>(outputExpected.shape()[widthIndex]);
53 unsigned int outputChannels = boost::numeric_cast<unsigned int>(outputExpected.shape()[channelsIndex]);
telsoa014fcda012018-03-09 14:13:49 +000054 unsigned int outputBatchSize = boost::numeric_cast<unsigned int>(outputExpected.shape()[0]);
55
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +000056 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(
57 inputBatchSize, inputChannels, inputHeight, inputWidth, dataLayout, ArmnnType);
58
59 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(
60 outputBatchSize, outputChannels, outputHeight, outputWidth, dataLayout, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +000061
62 // Set quantization parameters if the requested type is a quantized type.
63 if(armnn::IsQuantizedType<T>())
64 {
65 inputTensorInfo.SetQuantizationScale(qScale);
66 inputTensorInfo.SetQuantizationOffset(qOffset);
67 outputTensorInfo.SetQuantizationScale(qScale);
68 outputTensorInfo.SetQuantizationOffset(qOffset);
69 }
70
71 LayerTestResult<T, 4> result(outputTensorInfo);
72
73 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
74 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
75
76 armnn::Pooling2dQueueDescriptor queueDescriptor;
77 queueDescriptor.m_Parameters = descriptor;
James Conroy45a9b772018-10-31 11:47:53 +000078 queueDescriptor.m_Parameters.m_DataLayout = dataLayout;
Francis Murtagh043d0d02018-10-05 14:08:48 +010079
80 armnn::WorkloadInfo workloadInfo;
81 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get());
82 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
83
84 // Don't execute if Pooling is not supported, as an exception will be raised.
David Beck79141b92018-10-23 16:09:36 +010085 armnn::BackendId backend = workloadFactory.GetBackendId();
Francis Murtagh043d0d02018-10-05 14:08:48 +010086 const size_t reasonIfUnsupportedMaxLen = 255;
87 char reasonIfUnsupported[reasonIfUnsupportedMaxLen+1];
David Beck79141b92018-10-23 16:09:36 +010088 result.supported = armnn::IsPooling2dSupported(backend, inputTensorInfo, outputTensorInfo,
Francis Murtagh043d0d02018-10-05 14:08:48 +010089 queueDescriptor.m_Parameters,
90 reasonIfUnsupported, reasonIfUnsupportedMaxLen);
91 if (!result.supported)
92 {
93 return result;
94 }
95
96 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePooling2d(queueDescriptor, workloadInfo);
97
98 inputHandle->Allocate();
99 outputHandle->Allocate();
100
101 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
102
103 workload->Execute();
104
105 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
106
107 result.outputExpected = outputExpected;
108
109 return result;
110}
111
telsoa014fcda012018-03-09 14:13:49 +0000112//
113// Tests max pooling with the following parameters:
114//
115// Pooling size: 3x3
116// Stride: (2,4)
117// input size: 8x13
118// channels: 2
119// batch size: 2
120//
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000121template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000122LayerTestResult<T, 4> SimpleMaxPooling2dSize3x3Stride2x4TestCommon(
123 armnn::IWorkloadFactory& workloadFactory,
124 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
125 bool forceNoPadding,
126 float qScale = 1.0f,
127 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000128{
129 armnn::Pooling2dDescriptor descriptor;
130 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
131 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
132 descriptor.m_StrideX = 2;
133 descriptor.m_StrideY = 4;
134 // forceNoPadding is mainly used for compatibility with ARM Compute.
135 // As of 16/05/2017, it errors if padX or padY are equal to or greater than the pool size.
136 descriptor.m_PadLeft = descriptor.m_PadRight = forceNoPadding ? 0 : 3;
137 descriptor.m_PadTop = descriptor.m_PadBottom = 0;
138 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
139 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
140
141 unsigned int inputWidth = 8;
142 unsigned int inputHeight = 13;
143 unsigned int outputWidth =
144 (inputWidth + descriptor.m_PadLeft + descriptor.m_PadRight + descriptor.m_StrideX - descriptor.m_PoolWidth) /
145 descriptor.m_StrideX;
146 unsigned int outputHeight =
147 (inputHeight + descriptor.m_PadTop + descriptor.m_PadBottom + descriptor.m_StrideY - descriptor.m_PoolHeight) /
148 descriptor.m_StrideY;
149 unsigned int channels = 2;
150 unsigned int batchSize = 2;
151
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000152 armnn::TensorInfo inputTensorInfo({ batchSize, channels, inputHeight, inputWidth }, ArmnnType);
153 armnn::TensorInfo outputTensorInfo({ batchSize, channels, outputHeight, outputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000154
155 // Set quantization parameters if the requested type is a quantized type.
156 if(armnn::IsQuantizedType<T>())
157 {
158 inputTensorInfo.SetQuantizationScale(qScale);
159 inputTensorInfo.SetQuantizationOffset(qOffset);
160 outputTensorInfo.SetQuantizationScale(qScale);
161 outputTensorInfo.SetQuantizationOffset(qOffset);
162 }
163
164 std::vector<float> singleChannelData({
165 0.0f, 4.0f, 8.0f, 1.0f, 6.0f, 4.0f, 5.0f, 8.0f,
166 1.0f, 1.0f, 6.0f, 0.0f, 3.0f, 7.0f, 4.0f, 7.0f,
167 8.0f, 5.0f, 0.0f, 0.0f, 8.0f, 3.0f, 4.0f, 3.0f,
168 8.0f, 2.0f, 5.0f, 4.0f, 1.0f, 9.0f, 2.0f, 0.0f,
169 5.0f, 4.0f, 5.0f, 0.0f, 0.0f, 0.0f, 7.0f, 2.0f,
170 1.0f, 2.0f, 6.0f, 2.0f, 7.0f, 9.0f, 5.0f, 2.0f,
171 9.0f, 7.0f, 3.0f, 1.0f, 3.0f, 4.0f, 8.0f, 3.0f,
172 1.0f, 0.0f, 0.0f, 5.0f, 5.0f, 4.0f, 2.0f, 0.0f,
173 6.0f, 4.0f, 3.0f, 6.0f, 9.0f, 5.0f, 5.0f, 6.0f,
174 8.0f, 7.0f, 9.0f, 6.0f, 1.0f, 4.0f, 1.0f, 9.0f,
175 7.0f, 1.0f, 9.0f, 2.0f, 9.0f, 9.0f, 8.0f, 1.0f,
176 4.0f, 4.0f, 5.0f, 9.0f, 2.0f, 6.0f, 6.0f, 4.0f,
177 3.0f, 5.0f, 4.0f, 0.0f, 1.0f, 5.0f, 9.0f, 7.0f,
178 });
179
telsoa01c577f2c2018-08-31 09:22:23 +0100180 // Constructs input data.
telsoa014fcda012018-03-09 14:13:49 +0000181 std::vector<float> inputData;
182 auto negator = [](float f) { return -f; };
183
telsoa01c577f2c2018-08-31 09:22:23 +0100184 // First image (two channels where the second channel is the negative of the first one).
telsoa014fcda012018-03-09 14:13:49 +0000185 inputData.insert(inputData.end(), singleChannelData.begin(), singleChannelData.end());
186 std::transform(singleChannelData.begin(), singleChannelData.end(), std::back_inserter(inputData), negator);
187
telsoa01c577f2c2018-08-31 09:22:23 +0100188 // Second image (same as first image).
telsoa014fcda012018-03-09 14:13:49 +0000189 inputData.insert(inputData.end(), singleChannelData.begin(), singleChannelData.end());
190 std::transform(singleChannelData.begin(), singleChannelData.end(), std::back_inserter(inputData), negator);
191
192 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, inputData));
193
telsoa01c577f2c2018-08-31 09:22:23 +0100194 // These were calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000195 auto shape(GetTensorShapeAsArray<4>(outputTensorInfo));
196 boost::multi_array<T, 4> outputExpected(shape);
197 if (forceNoPadding)
198 {
199 outputExpected = MakeTensor<T, 4>(outputTensorInfo,
200 QuantizedVector<T>(qScale, qOffset, {
201 8.0f, 8.0f, 8.0f,
202 9.0f, 7.0f, 9.0f,
203 9.0f, 9.0f, 9.0f,
204
205 0.0f, 0.0f, -3.0f,
206 -1.0f, 0.0f, 0.0f,
207 -1.0f, -1.0f, -1.0f,
208
209 8.0f, 8.0f, 8.0f,
210 9.0f, 7.0f, 9.0f,
211 9.0f, 9.0f, 9.0f,
212
213 0.0f, 0.0f, -3.0f,
214 -1.0f, 0.0f, 0.0f,
215 -1.0f, -1.0f, -1.0f
216 }));
217 }
218 else
219 {
220 outputExpected = MakeTensor<T, 4>(outputTensorInfo,
221 QuantizedVector<T>(qScale, qOffset, {
222 0.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f,
223 0.0f, 9.0f, 7.0f, 9.0f, 9.0f, 3.0f,
224 0.0f, 8.0f, 9.0f, 9.0f, 9.0f, 9.0f,
225
226 0.0f, 0.0f, 0.0f, 0.0f,-3.0f, 0.0f,
227 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
228 0.0f,-1.0f,-1.0f,-1.0f,-1.0f, 0.0f,
229
230 0.0f, 8.0f, 8.0f, 8.0f, 8.0f, 8.0f,
231 0.0f, 9.0f, 7.0f, 9.0f, 9.0f, 3.0f,
232 0.0f, 8.0f, 9.0f, 9.0f, 9.0f, 9.0f,
233
234 0.0f, 0.0f, 0.0f, 0.0f,-3.0f, 0.0f,
235 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
236 0.0f,-1.0f,-1.0f,-1.0f,-1.0f, 0.0f
237 }));
238 }
239
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000240 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000241 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000242}
243
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000244template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000245LayerTestResult<T, 4> SimpleMaxPooling2dTestCommon(
246 armnn::IWorkloadFactory& workloadFactory,
247 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Matthew Bentham8800c002018-11-19 13:19:28 +0000248 const armnn::DataLayout dataLayout = armnn::DataLayout::NCHW,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000249 float qScale = 1.0f,
250 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000251{
252 armnn::Pooling2dDescriptor descriptor;
James Conroy45a9b772018-10-31 11:47:53 +0000253 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
telsoa014fcda012018-03-09 14:13:49 +0000254 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
255 descriptor.m_StrideX = descriptor.m_StrideY = 2;
telsoa014fcda012018-03-09 14:13:49 +0000256 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
James Conroy69482272018-10-19 10:41:35 +0100257 descriptor.m_DataLayout = dataLayout;
telsoa014fcda012018-03-09 14:13:49 +0000258
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000259 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
260 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000261
262 // Set quantization parameters if the requested type is a quantized type.
263 if(armnn::IsQuantizedType<T>())
264 {
265 inputTensorInfo.SetQuantizationScale(qScale);
266 inputTensorInfo.SetQuantizationOffset(qOffset);
267 outputTensorInfo.SetQuantizationScale(qScale);
268 outputTensorInfo.SetQuantizationOffset(qOffset);
269 }
270
James Conroy45a9b772018-10-31 11:47:53 +0000271 std::vector<T> inputData(
telsoa014fcda012018-03-09 14:13:49 +0000272 QuantizedVector<T>(qScale, qOffset, {
James Conroy45a9b772018-10-31 11:47:53 +0000273 1.0f, 2.0f, 5.0f, 6.0f,
274 3.0f, 4.0f, 7.0f, 8.0f,
275 9.0f, 10.0f, 13.0f, 14.0f,
276 11.0f, 12.0f, 15.0f, 16.0f,
277
278 17.0f, 18.0f, 21.0f, 22.0f,
279 19.0f, 20.0f, 23.0f, 24.0f,
280 25.0f, 26.0f, 29.0f, 30.0f,
281 27.0f, 28.0f, 31.0f, 32.0f,
telsoa014fcda012018-03-09 14:13:49 +0000282 }));
283
James Conroy45a9b772018-10-31 11:47:53 +0000284 std::vector<T> outputData(
telsoa014fcda012018-03-09 14:13:49 +0000285 QuantizedVector<T>(qScale, qOffset, {
James Conroy45a9b772018-10-31 11:47:53 +0000286 4.0f, 8.0f,
287 12.0f, 16.0f,
288
289 20.0f, 24.0f,
290 28.0f, 32.0f,
telsoa014fcda012018-03-09 14:13:49 +0000291 }));
292
James Conroy45a9b772018-10-31 11:47:53 +0000293 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
Matthew Bentham8800c002018-11-19 13:19:28 +0000294 if (dataLayout == armnn::DataLayout::NHWC)
James Conroy45a9b772018-10-31 11:47:53 +0000295 {
296 std::vector<T> tmp(inputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000297 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000298 inputData = tmp;
299
300 std::vector<T> tmp1(outputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000301 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000302 outputData = tmp1;
303 }
304
305 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
306
307 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputData);
308
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000309 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000310 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000311}
312
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000313template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000314LayerTestResult<T, 4> SimpleAveragePooling2dTestCommon(
315 armnn::IWorkloadFactory& workloadFactory,
316 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Matthew Bentham8800c002018-11-19 13:19:28 +0000317 armnn::DataLayout dataLayout = armnn::DataLayout::NCHW,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000318 float qScale = 1.0f,
319 int32_t qOffset = 0)
Francis Murtagh043d0d02018-10-05 14:08:48 +0100320{
James Conroy45a9b772018-10-31 11:47:53 +0000321 armnn::Pooling2dDescriptor descriptor;
322 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
323 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
324 descriptor.m_StrideX = descriptor.m_StrideY = 2;
325 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
326 descriptor.m_DataLayout = dataLayout;
Francis Murtagh043d0d02018-10-05 14:08:48 +0100327
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000328 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
329 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
Francis Murtagh043d0d02018-10-05 14:08:48 +0100330
James Conroy45a9b772018-10-31 11:47:53 +0000331 // Set quantization parameters if the requested type is a quantized type.
332 if(armnn::IsQuantizedType<T>())
333 {
334 inputTensorInfo.SetQuantizationScale(qScale);
335 inputTensorInfo.SetQuantizationOffset(qOffset);
336 outputTensorInfo.SetQuantizationScale(qScale);
337 outputTensorInfo.SetQuantizationOffset(qOffset);
338 }
Francis Murtagh043d0d02018-10-05 14:08:48 +0100339
James Conroy45a9b772018-10-31 11:47:53 +0000340 std::vector<T> inputData(
341 QuantizedVector<T>(qScale, qOffset, {
342 2.0f, 2.0f, 6.0f, 6.0f,
343 4.0f, 4.0f, 8.0f, 8.0f,
344 10.0f, 12.0f, 14.0f, 16.0f,
345 10.0f, 12.0f, 16.0f, 14.0f,
346
347 18.0f, 20.0f, 24.0f, 22.0f,
348 20.0f, 18.0f, 22.0f, 24.0f,
349 26.0f, 28.0f, 0.0f, 0.0f,
350 26.0f, 28.0f, 0.0f, 0.0f,
351 }));
352
353 std::vector<T> outputData(
354 QuantizedVector<T>(qScale, qOffset, {
355 3.0f, 7.0f,
356 11.0f, 15.0f,
357
358 19.0f, 23.0f,
359 27.0f, 0.0f,
360 }));
361
362 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
Matthew Bentham8800c002018-11-19 13:19:28 +0000363 if (dataLayout == armnn::DataLayout::NHWC)
James Conroy45a9b772018-10-31 11:47:53 +0000364 {
365 std::vector<T> tmp(inputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000366 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000367 inputData = tmp;
368
369 std::vector<T> tmp1(outputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000370 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000371 outputData = tmp1;
372 }
373
374 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
375
376 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputData);
377
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000378 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000379 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
Francis Murtagh043d0d02018-10-05 14:08:48 +0100380}
381
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000382template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000383LayerTestResult<T, 4> LargeTensorsAveragePooling2dTestCommon(
384 armnn::IWorkloadFactory& workloadFactory,
385 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
386 float qScale = 1.0f,
387 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000388{
389 armnn::Pooling2dDescriptor descriptor;
390 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
391 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 100;
392 descriptor.m_StrideX = descriptor.m_StrideY = 5;
393 descriptor.m_PadLeft = 50;
394 descriptor.m_PadRight = 50;
395 descriptor.m_PadTop = 50;
396 descriptor.m_PadBottom = 50;
397 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
398
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000399 armnn::TensorInfo inputTensorInfo({ 5, 3, 52, 60 }, ArmnnType);
400 armnn::TensorInfo outputTensorInfo({ 5, 3, 11, 13 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000401
402 // Set quantization parameters if the requested type is a quantized type.
403 if(armnn::IsQuantizedType<T>())
404 {
405 inputTensorInfo.SetQuantizationScale(qScale);
406 inputTensorInfo.SetQuantizationOffset(qOffset);
407 outputTensorInfo.SetQuantizationScale(qScale);
408 outputTensorInfo.SetQuantizationOffset(qOffset);
409 }
410
411 std::vector<T> inputVec;
412
413 for (unsigned int i = 0 ; i < inputTensorInfo.GetShape().GetNumElements(); ++i)
414 {
415 inputVec.push_back(1);
416 }
417
418 auto input = MakeTensor<T, 4>(inputTensorInfo, inputVec);
419
420 std::vector<T> outputVec;
421
422 for (unsigned int i = 0 ; i < outputTensorInfo.GetShape().GetNumElements(); ++i)
423 {
424 outputVec.push_back(1);
425 }
426
427 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputVec);
428
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000429 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000430 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000431}
432
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000433template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000434LayerTestResult<T, 4> SimpleL2Pooling2dTestCommon(
435 armnn::IWorkloadFactory& workloadFactory,
436 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Matthew Bentham8800c002018-11-19 13:19:28 +0000437 armnn::DataLayout dataLayout = armnn::DataLayout::NCHW,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000438 float qScale = 1.0f,
439 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000440{
441 armnn::Pooling2dDescriptor descriptor;
442 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
443 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
444 descriptor.m_StrideX = descriptor.m_StrideY = 2;
445 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
James Conroy45a9b772018-10-31 11:47:53 +0000446 descriptor.m_DataLayout = dataLayout;
telsoa014fcda012018-03-09 14:13:49 +0000447
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000448 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 4, 4, dataLayout, ArmnnType);
449 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(1, 2, 2, 2, dataLayout, ArmnnType);
James Conroy45a9b772018-10-31 11:47:53 +0000450
451 std::vector<T> inputData(
telsoa014fcda012018-03-09 14:13:49 +0000452 QuantizedVector<T>(qScale, qOffset, {
James Conroy45a9b772018-10-31 11:47:53 +0000453 1.0f, 7.0f, 5.0f, 5.0f,
454 1.0f, 7.0f, 5.0f, 5.0f,
455 3.0f, 3.0f, 1.0f, 1.0f,
456 3.0f, 3.0f, 1.0f, 1.0f,
457
458 1.0f, 7.0f, 0.0f, 0.0f,
459 1.0f, 7.0f, 2.0f, 0.0f,
460 0.0f, 2.0f, 1.0f, 1.0f,
461 0.0f, 0.0f, 1.0f, 1.0f,
telsoa014fcda012018-03-09 14:13:49 +0000462 }));
463
James Conroy45a9b772018-10-31 11:47:53 +0000464 std::vector<T> outputData(
telsoa014fcda012018-03-09 14:13:49 +0000465 QuantizedVector<T>(qScale, qOffset, {
466 5.0f, 5.0f,
James Conroy45a9b772018-10-31 11:47:53 +0000467 3.0f, 1.0f,
468
469 5.0f, 1.0f,
470 1.0f, 1.0f,
telsoa014fcda012018-03-09 14:13:49 +0000471 }));
472
James Conroy45a9b772018-10-31 11:47:53 +0000473 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
Matthew Bentham8800c002018-11-19 13:19:28 +0000474 if (dataLayout == armnn::DataLayout::NHWC)
James Conroy45a9b772018-10-31 11:47:53 +0000475 {
476 std::vector<T> tmp(inputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000477 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000478 inputData = tmp;
479
480 std::vector<T> tmp1(outputData.size());
Matteo Martincighd5b9e642019-01-04 18:01:21 +0000481 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp1.data(), sizeof(T));
James Conroy45a9b772018-10-31 11:47:53 +0000482 outputData = tmp1;
483 }
484
485 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
486
487 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputData);
488
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000489 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000490 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000491}
492
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000493template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000494LayerTestResult<T, 4> L2Pooling2dSize3Stride1TestCommon(
495 armnn::IWorkloadFactory& workloadFactory,
496 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
497 float qScale = 1.0f,
498 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000499{
500 armnn::Pooling2dDescriptor descriptor;
501 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
502 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
503 descriptor.m_StrideX = descriptor.m_StrideY = 1;
504 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
505
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000506 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000507 auto input = MakeTensor<T, 4>(inputTensorInfo,
508 QuantizedVector<T>(qScale, qOffset, {
509 2.0f, 1.0f, 5.0f, 2.0f,
510 1.0f, 2.0f, 2.0f, 1.0f,
511 5.0f, 4.0f, 1.0f, 5.0f,
512 2.0f, 1.0f, 5.0f, 2.0f,
513 }));
514
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000515 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000516 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
517 QuantizedVector<T>(qScale, qOffset, {
518 3.0f, 3.0f,
519 3.0f, 3.0f,
520 }));
521
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000522 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000523 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000524}
525
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000526template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000527LayerTestResult<T, 4> L2Pooling2dSize3Stride3TestCommon(
528 armnn::IWorkloadFactory& workloadFactory,
529 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
530 float qScale = 1.0f,
531 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000532{
533 armnn::Pooling2dDescriptor descriptor;
534 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
535 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
536 descriptor.m_StrideX = descriptor.m_StrideY = 3;
537 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
538
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000539 armnn::TensorInfo inputTensorInfo({ 1, 1, 9, 9 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000540 auto input = MakeTensor<T, 4>(inputTensorInfo,
541 QuantizedVector<T>(qScale, qOffset, {
542 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
543 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
544 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
545 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
546 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
547 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
548 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
549 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
550 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
551 }));
552
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000553 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000554 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
555 QuantizedVector<T>(qScale, qOffset, {
556 3.0f, 3.0f, 3.0f,
557 3.0f, 3.0f, 3.0f,
558 3.0f, 3.0f, 3.0f,
559 }));
560
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000561 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000562 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000563}
564
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000565template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000566LayerTestResult<T, 4> L2Pooling2dSize3Stride4TestCommon(
567 armnn::IWorkloadFactory& workloadFactory,
568 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
569 float qScale = 1.0f,
570 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000571{
572 armnn::Pooling2dDescriptor descriptor;
573 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
574 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
575 descriptor.m_StrideX = descriptor.m_StrideY = 4;
576 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
577
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000578 armnn::TensorInfo inputTensorInfo({ 1, 1, 7, 7 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000579 auto input = MakeTensor<T, 4>(inputTensorInfo,
580 QuantizedVector<T>(qScale, qOffset, {
581 2.0f, 1.0f, 5.0f, 0.0f, 2.0f, 1.0f, 5.0f,
582 1.0f, 2.0f, 2.0f, 0.0f, 1.0f, 2.0f, 2.0f,
583 5.0f, 4.0f, 1.0f, 0.0f, 5.0f, 4.0f, 1.0f,
584 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
585 2.0f, 1.0f, 5.0f, 0.0f, 2.0f, 1.0f, 5.0f,
586 1.0f, 2.0f, 2.0f, 0.0f, 1.0f, 2.0f, 2.0f,
587 5.0f, 4.0f, 1.0f, 0.0f, 5.0f, 4.0f, 1.0f,
588 }));
589
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000590 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000591 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
592 QuantizedVector<T>(qScale, qOffset, {
593 3.0f, 3.0f,
594 3.0f, 3.0f,
595 }));
596
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000597 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000598 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000599}
600
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000601template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000602LayerTestResult<T, 4> L2Pooling2dSize7TestCommon(
603 armnn::IWorkloadFactory& workloadFactory,
604 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
605 float qScale = 1.0f,
606 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000607{
608 armnn::Pooling2dDescriptor descriptor;
609 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
610 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 7;
611 descriptor.m_StrideX = descriptor.m_StrideY = 7;
612 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
613
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000614 armnn::TensorInfo inputTensorInfo({ 1, 1, 7, 7 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000615 auto input = MakeTensor<T, 4>(inputTensorInfo,
616 QuantizedVector<T>(qScale, qOffset, {
617 1.0f, 0.0f, 2.0f, 0.0f, 3.0f, 0.0f, 4.0f,
618 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
619 0.0f, 5.0f, 0.0f, 6.0f, 0.0f, 7.0f, 0.0f,
620 8.0f, 0.0f, 9.0f, 0.0f, 10.0f, 0.0f, 5.0f,
621 0.0f, 5.0f, 0.0f, 2.0f, 0.0f, 1.0f, 1.0f,
622 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
623 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
624 }));
625
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000626 armnn::TensorInfo outputTensorInfo({ 1, 1, 1, 1 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000627 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
628 QuantizedVector<T>(qScale, qOffset, {
629 3.0f,
630 }));
631
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000632 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000633 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000634}
635
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000636template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000637LayerTestResult<T, 4> L2Pooling2dSize9TestCommon(
638 armnn::IWorkloadFactory& workloadFactory,
639 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
640 float qScale = 1.0f,
641 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000642{
643 armnn::Pooling2dDescriptor descriptor;
644 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
645 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 9;
646 descriptor.m_StrideX = descriptor.m_StrideY = 9;
647 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
648
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000649 armnn::TensorInfo inputTensorInfo({ 1, 1, 9, 9 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000650 auto input = MakeTensor<T, 4>(inputTensorInfo,
651 QuantizedVector<T>(qScale, qOffset, {
652 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
653 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
654 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
655 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
656 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
657 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
658 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f, 2.0f, 1.0f, 5.0f,
659 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f, 1.0f, 2.0f, 2.0f,
660 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f, 5.0f, 4.0f, 1.0f,
661 }));
662
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000663 armnn::TensorInfo outputTensorInfo({ 1, 1, 1, 1 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000664 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
665 QuantizedVector<T>(qScale, qOffset, {
666 3.0f,
667 }));
668
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000669 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000670 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000671}
672
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000673template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000674LayerTestResult<T, 4> AsymmetricNonSquarePooling2dTestCommon(
675 armnn::IWorkloadFactory& workloadFactory,
676 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
677 float qScale = 1.0f,
678 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000679{
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000680 armnn::TensorInfo inputTensorInfo({ 1, 1, 1, 3 }, ArmnnType);
681 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000682
683 armnn::Pooling2dDescriptor descriptor;
684 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
685 descriptor.m_PoolWidth = 2;
686 descriptor.m_PoolHeight = 3;
687 descriptor.m_StrideX = 2;
688 descriptor.m_StrideY = 1;
689 descriptor.m_PadLeft = 2;
690 descriptor.m_PadRight = 0;
691 descriptor.m_PadTop = 1;
692 descriptor.m_PadBottom = 2;
693 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
694 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
695
telsoa01c577f2c2018-08-31 09:22:23 +0100696 // Construct input data.
telsoa014fcda012018-03-09 14:13:49 +0000697 auto input = MakeTensor<T, 4>(inputTensorInfo,
698 QuantizedVector<T>(qScale, qOffset, {
699 1.0f, 3.0f, 4.0f,
700 }));
701
telsoa01c577f2c2018-08-31 09:22:23 +0100702 // These were calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000703 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
704 QuantizedVector<T>(qScale, qOffset, {
705 0.0f, 3.0f, 0.0f, 3.0f,
706 }));
707
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000708 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000709 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000710}
711
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000712template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000713LayerTestResult<T, 4> ComparePooling2dTestCommon(
714 armnn::IWorkloadFactory& workloadFactory,
715 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
716 armnn::IWorkloadFactory& refWorkloadFactory,
717 armnn::PoolingAlgorithm poolingType,
718 float qScale = 1.0f,
719 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000720{
721 const unsigned int inputWidth = 16;
722 const unsigned int inputHeight = 32;
723 const unsigned int channelCount = 2;
724 const unsigned int batchSize = 5;
725
726 const unsigned int poolSize = 3;
727 const unsigned int strideX = 2;
728 const unsigned int strideY = 4;
729 const unsigned int padX = 0;
730 const unsigned int padY = 0;
731
732 const unsigned int outputWidth = (inputWidth + 2 * padX + strideX - poolSize) / strideX;
733 const unsigned int outputHeight = (inputHeight + 2 * padY + strideY - poolSize) / strideY;
734
735 armnn::TensorInfo inputTensorInfo;
736 armnn::TensorInfo outputTensorInfo;
737
738 unsigned int inputShape[] = { batchSize, channelCount, inputHeight, inputWidth };
739 unsigned int outputShape[] = { batchSize, channelCount, outputHeight, outputWidth };
740
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000741 inputTensorInfo = armnn::TensorInfo(4, inputShape, ArmnnType);
742 outputTensorInfo = armnn::TensorInfo(4, outputShape, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000743
744 // Set quantization parameters if the requested type is a quantized type.
745 if(armnn::IsQuantizedType<T>())
746 {
747 inputTensorInfo.SetQuantizationScale(qScale);
748 inputTensorInfo.SetQuantizationOffset(qOffset);
749 outputTensorInfo.SetQuantizationScale(qScale);
750 outputTensorInfo.SetQuantizationOffset(qOffset);
751 }
752
753 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 81715);
754
755 LayerTestResult<T, 4> comparisonResult(outputTensorInfo);
756
757 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
758 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
759
760 armnn::Pooling2dQueueDescriptor data;
761 armnn::WorkloadInfo info;
762 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
763 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
764 data.m_Parameters.m_PoolType = poolingType;
765 data.m_Parameters.m_PoolWidth = poolSize;
766 data.m_Parameters.m_PoolHeight = poolSize;
767 data.m_Parameters.m_StrideX = strideX;
768 data.m_Parameters.m_StrideY = strideY;
769 data.m_Parameters.m_PadLeft = padX;
770 data.m_Parameters.m_PadRight = padX;
771 data.m_Parameters.m_PadTop = padY;
772 data.m_Parameters.m_PadBottom = padY;
773 data.m_Parameters.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
774
775 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
776 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refWorkloadFactory.CreateTensorHandle(inputTensorInfo);
777
778 // Don't execute if Pooling is not supported, as an exception will be raised.
David Beck79141b92018-10-23 16:09:36 +0100779 armnn::BackendId backend = workloadFactory.GetBackendId();
telsoa014fcda012018-03-09 14:13:49 +0000780 const size_t reasonIfUnsupportedMaxLen = 255;
781 char reasonIfUnsupported[reasonIfUnsupportedMaxLen+1];
David Beck79141b92018-10-23 16:09:36 +0100782 comparisonResult.supported = armnn::IsPooling2dSupported(backend, inputTensorInfo, outputTensorInfo,
telsoa014fcda012018-03-09 14:13:49 +0000783 data.m_Parameters,
784 reasonIfUnsupported, reasonIfUnsupportedMaxLen);
785 if (!comparisonResult.supported)
786 {
787 return comparisonResult;
788 }
789
790 armnn::Pooling2dQueueDescriptor refData = data;
791 armnn::WorkloadInfo refInfo = info;
792 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
793 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
794
795 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePooling2d(data, info);
796 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreatePooling2d(refData, refInfo);
797
798 outputHandleRef->Allocate();
799 inputHandleRef->Allocate();
800 inputHandle->Allocate();
801 outputHandle->Allocate();
802
803 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
804 CopyDataToITensorHandle(inputHandleRef.get(), &input[0][0][0][0]);
805
806 workload->Execute();
807 workloadRef->Execute();
808
809 CopyDataFromITensorHandle(&comparisonResult.output[0][0][0][0], outputHandle.get());
810 CopyDataFromITensorHandle(&comparisonResult.outputExpected[0][0][0][0], outputHandleRef.get());
811
812 return comparisonResult;
813}
814
815//
816// Tests max pooling with the following parameters:
817//
818// Pooling size: 2x2
819// Stride: (2,2)
820// input size: 4x4
821// channels: 1
822// batch size: 1
823//
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000824template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000825LayerTestResult<T, 4> SimpleMaxPooling2dSize2x2Stride2x2TestCommon(
826 armnn::IWorkloadFactory& workloadFactory,
827 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
828 bool forceNoPadding,
829 float qScale = 1.0f,
830 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000831{
832 armnn::Pooling2dDescriptor descriptor;
833 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
834 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
835 descriptor.m_StrideX = 2;
836 descriptor.m_StrideY = 2;
837 descriptor.m_PadLeft = descriptor.m_PadRight = forceNoPadding ? 0 : 3;
838 descriptor.m_PadTop = descriptor.m_PadBottom = 0;
839 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
840 descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
841
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000842
telsoa014fcda012018-03-09 14:13:49 +0000843 unsigned int inputWidth = 4;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000844
telsoa014fcda012018-03-09 14:13:49 +0000845 unsigned int inputHeight = 4;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000846
telsoa014fcda012018-03-09 14:13:49 +0000847 unsigned int outputWidth =
848 (inputWidth + descriptor.m_PadLeft + descriptor.m_PadRight + descriptor.m_StrideX - descriptor.m_PoolWidth) /
849 descriptor.m_StrideX;
850 unsigned int outputHeight =
851 (inputHeight + descriptor.m_PadTop + descriptor.m_PadBottom + descriptor.m_StrideY - descriptor.m_PoolHeight) /
852 descriptor.m_StrideY;
853 unsigned int channels = 1;
854 unsigned int batchSize = 1;
855
856 std::vector<float> inputData = {
857 510.0f, 222.0f, 780.0f, 654.0f,
858 141.0f, 276.0f, 15.0f, 546.0f,
859 303.0f, 618.0f, 582.0f, 339.0f,
860 438.0f, 564.0f, 573.0f, 402.0f
861 };
862
telsoa01c577f2c2018-08-31 09:22:23 +0100863 // Note that left and right edges will be 0.f, due to the 2x2 max pooling only accessing zeros here.
telsoa014fcda012018-03-09 14:13:49 +0000864 std::vector<float> expectedOutputDataWithPadding = {
865 0.0f, 510.0f, 780.0f, 654.0f, 0.0f,
866 0.0f, 438.0f, 618.0f, 402.0f, 0.0f
867 };
868
869 std::vector<float> expectedOutputDataNoPadding = {
870 510.0f, 780.0f,
871 618.0f, 582.0f
872 };
873
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000874 armnn::TensorInfo inputTensorInfo({ batchSize, channels, inputHeight, inputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000875
876 // Scale and offset should match input - we're just calculating maximum values.
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000877 armnn::TensorInfo outputTensorInfo({ batchSize, channels, outputHeight, outputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000878
879 // Set quantization parameters if the requested type is a quantized type.
880 if(armnn::IsQuantizedType<T>())
881 {
882 inputTensorInfo.SetQuantizationScale(qScale);
883 inputTensorInfo.SetQuantizationOffset(qOffset);
884 outputTensorInfo.SetQuantizationScale(qScale);
885 outputTensorInfo.SetQuantizationOffset(qOffset);
886 }
887
888 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, inputData));
889
890 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
891 forceNoPadding ? QuantizedVector<T>(qScale, qOffset, expectedOutputDataNoPadding) :
892 QuantizedVector<T>(qScale, qOffset, expectedOutputDataWithPadding));
893
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000894 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000895 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +0000896}
897
surmeh01bceff2f2018-03-29 16:29:27 +0100898//
899// Tests max pooling with the following parameters:
900//
901// Pooling size: 3x2
902// Stride: (2,2)
903// input size: 3x2
904// channels: 1
905// batch size: 1
906//
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000907template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
surmeh01bceff2f2018-03-29 16:29:27 +0100908LayerTestResult<T, 4> IgnorePaddingAveragePooling2dSize3x2Stride2x2TestCommon(
909 armnn::IWorkloadFactory& workloadFactory,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000910 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
surmeh01bceff2f2018-03-29 16:29:27 +0100911 bool forceNoPadding,
912 float qScale = 1.0f,
913 int32_t qOffset = 0)
914{
915 armnn::Pooling2dDescriptor descriptor;
916 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
917 descriptor.m_PoolWidth = 3;
918 descriptor.m_PoolHeight = 2;
919 descriptor.m_StrideX = 2;
920 descriptor.m_StrideY = 2;
921 descriptor.m_PadLeft = (forceNoPadding) ? 0 : 1;
922 descriptor.m_PadRight = descriptor.m_PadLeft;
923 descriptor.m_PadTop = 0;
924 descriptor.m_PadBottom = 0;
925 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
926 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
927
928 unsigned int inputWidth = 3;
929 unsigned int inputHeight = 2;
930 unsigned int outputWidth =
931 (inputWidth + descriptor.m_PadLeft + descriptor.m_PadRight + descriptor.m_StrideX - descriptor.m_PoolWidth) /
932 descriptor.m_StrideX;
933 unsigned int outputHeight =
934 (inputHeight + descriptor.m_PadTop + descriptor.m_PadBottom + descriptor.m_StrideY - descriptor.m_PoolHeight) /
935 descriptor.m_StrideY;
936 unsigned int channels = 1;
937 unsigned int batchSize = 1;
938
939 std::vector<float> inputData = {
940 3.0f, 6.0f, 9.0f,
941 12.0f, 15.0f, 18.0f,
942 };
943
944 std::vector<float> expectedOutputDataWithPadding = {
945 6.0f, 8.0f,
946 };
947
948 std::vector<float> expectedOutputDataNoPadding = {
949 10.5f,
950 };
951
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000952 armnn::TensorInfo inputTensorInfo({ batchSize, channels, inputHeight, inputWidth }, ArmnnType);
surmeh01bceff2f2018-03-29 16:29:27 +0100953
954 // Scale and offset should match input - we're just calculating average values.
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000955 armnn::TensorInfo outputTensorInfo({ batchSize, channels, outputHeight, outputWidth }, ArmnnType);
surmeh01bceff2f2018-03-29 16:29:27 +0100956
957 // Set quantization parameters if the requested type is a quantized type.
958 if(armnn::IsQuantizedType<T>())
959 {
960 inputTensorInfo.SetQuantizationScale(qScale);
961 inputTensorInfo.SetQuantizationOffset(qOffset);
962 outputTensorInfo.SetQuantizationScale(qScale);
963 outputTensorInfo.SetQuantizationOffset(qOffset);
964 }
965
966 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, inputData));
967
968 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
969 forceNoPadding ? QuantizedVector<T>(qScale, qOffset, expectedOutputDataNoPadding) :
970 QuantizedVector<T>(qScale, qOffset, expectedOutputDataWithPadding));
971
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000972 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000973 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
surmeh01bceff2f2018-03-29 16:29:27 +0100974}
975
976
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000977template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000978LayerTestResult<T, 4> IgnorePaddingSimpleMaxPooling2dTestCommon(
979 armnn::IWorkloadFactory& workloadFactory,
980 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
981 float qScale = 1.0f,
982 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000983{
984 armnn::Pooling2dDescriptor descriptor;
985 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
986 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
987 descriptor.m_StrideX = descriptor.m_StrideY = 2;
988 descriptor.m_PadLeft = 1;
989 descriptor.m_PadRight = 1;
990 descriptor.m_PadTop = 1;
991 descriptor.m_PadBottom = 1;
992 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
993
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000994 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
995 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000996
997 // Set quantization parameters if the requested type is a quantized type.
998 if(armnn::IsQuantizedType<T>())
999 {
1000 inputTensorInfo.SetQuantizationScale(qScale);
1001 inputTensorInfo.SetQuantizationOffset(qOffset);
1002 outputTensorInfo.SetQuantizationScale(qScale);
1003 outputTensorInfo.SetQuantizationOffset(qOffset);
1004 }
1005
1006 auto input = MakeTensor<T, 4>(inputTensorInfo,
1007 QuantizedVector<T>(qScale, qOffset, {
1008 -1.0f, -2.0f, 3.0f, 4.0f,
1009 -1.0f, -2.0f, 3.0f, 4.0f,
1010 1.0f, 2.0f, -3.0f, -4.0f,
1011 1.0f, 2.0f, -3.0f, -4.0f,
1012 }));
1013
1014 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1015 QuantizedVector<T>(qScale, qOffset, {
1016 -1.0f, 3.0f, 4.0f,
1017 1.0f, 3.0f, 4.0f,
1018 1.0f, 2.0f, -4.0f,
1019 }));
1020
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001021 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001022 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001023}
1024
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001025template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001026LayerTestResult<T, 4> IgnorePaddingMaxPooling2dSize3TestCommon(
1027 armnn::IWorkloadFactory& workloadFactory,
1028 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1029 float qScale = 1.0f,
1030 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001031{
1032 armnn::Pooling2dDescriptor descriptor;
1033 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
1034 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
1035 descriptor.m_StrideX = descriptor.m_StrideY = 1;
1036 descriptor.m_PadLeft = 1;
1037 descriptor.m_PadRight = 1;
1038 descriptor.m_PadTop = 1;
1039 descriptor.m_PadBottom = 1;
1040 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1041
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001042 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
1043 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001044
1045 // Set quantization parameters if the requested type is a quantized type.
1046 if(armnn::IsQuantizedType<T>())
1047 {
1048 inputTensorInfo.SetQuantizationScale(qScale);
1049 inputTensorInfo.SetQuantizationOffset(qOffset);
1050 outputTensorInfo.SetQuantizationScale(qScale);
1051 outputTensorInfo.SetQuantizationOffset(qOffset);
1052 }
1053
1054 auto input = MakeTensor<T, 4>(inputTensorInfo,
1055 QuantizedVector<T>(qScale, qOffset, {
1056 -1.0f, -2.0f, 3.0f, 4.0f,
1057 -1.0f, -2.0f, 3.0f, 4.0f,
1058 1.0f, 2.0f, -3.0f, -4.0f,
1059 1.0f, 2.0f, -3.0f, -4.0f,
1060 }));
1061
1062 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1063 QuantizedVector<T>(qScale, qOffset, {
1064 -1.0f, 3.0f, 4.0f, 4.0f,
1065 2.0f, 3.0f, 4.0f, 4.0f,
1066 2.0f, 3.0f, 4.0f, 4.0f,
1067 2.0f, 2.0f, 2.0f, -3.0f,
1068 }));
1069
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001070 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001071 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001072}
1073
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001074template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001075LayerTestResult<T, 4> IgnorePaddingSimpleAveragePooling2dTestCommon(
1076 armnn::IWorkloadFactory& workloadFactory,
1077 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1078 float qScale = 1.0f,
1079 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001080{
1081 armnn::Pooling2dDescriptor descriptor;
1082 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
1083 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
1084 descriptor.m_StrideX = descriptor.m_StrideY = 2;
1085 descriptor.m_PadLeft = 1;
1086 descriptor.m_PadRight = 1;
1087 descriptor.m_PadTop = 1;
1088 descriptor.m_PadBottom = 1;
1089 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1090
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001091 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
1092 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001093
1094 // Set quantization parameters if the requested type is a quantized type.
1095 if(armnn::IsQuantizedType<T>())
1096 {
1097 inputTensorInfo.SetQuantizationScale(qScale);
1098 inputTensorInfo.SetQuantizationOffset(qOffset);
1099 outputTensorInfo.SetQuantizationScale(qScale);
1100 outputTensorInfo.SetQuantizationOffset(qOffset);
1101 }
1102
1103 auto input = MakeTensor<T, 4>(inputTensorInfo,
1104 QuantizedVector<T>(qScale, qOffset, {
1105 12.0f, 20.0f, 32.0f, 40.0f,
1106 12.0f, 20.0f, 32.0f, 40.0f,
1107 12.0f, 20.0f, 32.0f, 40.0f,
1108 12.0f, 20.0f, 32.0f, 40.0f,
1109 }));
1110
1111 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1112 QuantizedVector<T>(qScale, qOffset, {
1113 3.0f, 13.0f, 10.0f,
1114 6.0f, 26.0f, 20.0f,
1115 3.0f, 13.0f, 10.0f,
1116 }));
1117
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001118 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001119 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001120}
1121
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001122template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001123LayerTestResult<T, 4> IgnorePaddingSimpleAveragePooling2dNoPaddingTestCommon(
1124 armnn::IWorkloadFactory& workloadFactory,
1125 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1126 float qScale = 1.0f,
1127 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001128{
1129 armnn::Pooling2dDescriptor descriptor;
1130 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
1131 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
1132 descriptor.m_StrideX = descriptor.m_StrideY = 2;
1133 descriptor.m_PadLeft = 0;
1134 descriptor.m_PadRight = 0;
1135 descriptor.m_PadTop = 0;
1136 descriptor.m_PadBottom = 0;
1137 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1138 descriptor.m_OutputShapeRounding = armnn::OutputShapeRounding::Ceiling;
1139
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001140 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4}, ArmnnType);
1141 armnn::TensorInfo outputTensorInfo({ 1, 1, 2, 2 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001142
1143 // Set quantization parameters if the requested type is a quantized type.
1144 if(armnn::IsQuantizedType<T>())
1145 {
1146 inputTensorInfo.SetQuantizationScale(qScale);
1147 inputTensorInfo.SetQuantizationOffset(qOffset);
1148 outputTensorInfo.SetQuantizationScale(qScale);
1149 outputTensorInfo.SetQuantizationOffset(qOffset);
1150 }
1151
1152 auto input = MakeTensor<T, 4>(inputTensorInfo,
1153 QuantizedVector<T>(qScale, qOffset, {
1154 1.0f, 2.0f, 3.0f, 4.0f,
1155 1.0f, 2.0f, 3.0f, 4.0f,
1156 1.0f, 2.0f, 3.0f, 4.0f,
1157 1.0f, 2.0f, 3.0f, 4.0f,
1158 }));
1159
1160 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1161 QuantizedVector<T>(qScale, qOffset, {
1162 2.0f, 3.5f,
1163 2.0f, 3.5f
1164 }));
1165
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001166 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001167 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001168}
1169
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001170template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001171LayerTestResult<T, 4> IgnorePaddingAveragePooling2dSize3TestCommon(
1172 armnn::IWorkloadFactory& workloadFactory,
1173 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1174 float qScale = 1.0f,
1175 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001176{
1177 armnn::Pooling2dDescriptor descriptor;
1178 descriptor.m_PoolType = armnn::PoolingAlgorithm::Average;
1179 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
1180 descriptor.m_StrideX = descriptor.m_StrideY = 1;
1181 descriptor.m_PadLeft = 1;
1182 descriptor.m_PadRight = 1;
1183 descriptor.m_PadTop = 1;
1184 descriptor.m_PadBottom = 1;
1185 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1186
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001187 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
1188 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001189
1190 // Set quantization parameters if the requested type is a quantized type.
1191 if(armnn::IsQuantizedType<T>())
1192 {
1193 inputTensorInfo.SetQuantizationScale(qScale);
1194 inputTensorInfo.SetQuantizationOffset(qOffset);
1195 outputTensorInfo.SetQuantizationScale(qScale);
1196 outputTensorInfo.SetQuantizationOffset(qOffset);
1197 }
1198
1199 auto input = MakeTensor<T, 4>(inputTensorInfo,
1200 QuantizedVector<T>(qScale, qOffset, {
1201 9.0f, 27.0f, 18.0f, 36.0f,
1202 18.0f, 9.0f, 18.0f, 9.0f,
1203 27.0f, 18.0f, 9.0f, 27.0f,
1204 9.0f, 27.0f, 9.0f, 18.0f,
1205 }));
1206
1207 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1208 QuantizedVector<T>(qScale, qOffset, {
1209 7.0f, 11.0f, 13.0f, 9.0f,
1210 12.0f, 17.0f, 19.0f, 13.0f,
1211 12.0f, 16.0f, 16.0f, 10.0f,
1212 9.0f, 11.0f, 12.0f, 7.0f,
1213 }));
1214
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001215 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001216 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001217}
1218
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001219template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001220LayerTestResult<T, 4> IgnorePaddingSimpleL2Pooling2dTestCommon(
1221 armnn::IWorkloadFactory& workloadFactory,
1222 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1223 float qScale = 1.0f,
1224 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001225{
1226 armnn::Pooling2dDescriptor descriptor;
1227 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
1228 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2;
1229 descriptor.m_StrideX = descriptor.m_StrideY = 2;
1230 descriptor.m_PadLeft = 1;
1231 descriptor.m_PadRight = 1;
1232 descriptor.m_PadTop = 1;
1233 descriptor.m_PadBottom = 1;
1234 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1235
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001236 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
1237 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001238
1239 // Set quantization parameters if the requested type is a quantized type.
1240 if(armnn::IsQuantizedType<T>())
1241 {
1242 inputTensorInfo.SetQuantizationScale(qScale);
1243 inputTensorInfo.SetQuantizationOffset(qOffset);
1244 outputTensorInfo.SetQuantizationScale(qScale);
1245 outputTensorInfo.SetQuantizationOffset(qOffset);
1246 }
1247
1248 auto input = MakeTensor<T, 4>(inputTensorInfo,
1249 QuantizedVector<T>(qScale, qOffset, {
1250 2.0f, 4.0f, 8.0f, 16.0f,
1251 4.0f, 2.0f, 2.0f, 4.0f,
1252 8.0f, 2.0f, 4.0f, 2.0f,
1253 16.0f, 2.0f, 2.0f, 8.0f,
1254 }));
1255
1256 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1257 QuantizedVector<T>(qScale, qOffset, {
1258 1.0f, 4.4721f, 8.0f,
1259 4.4721f, 2.6457f, 2.236f,
1260 8.0f, 1.4142f, 4.0f,
1261 }));
1262
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001263 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001264 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001265}
1266
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001267template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001268LayerTestResult<T, 4> IgnorePaddingL2Pooling2dSize3TestCommon(
1269 armnn::IWorkloadFactory& workloadFactory,
1270 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1271 float qScale = 1.0f,
1272 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001273{
1274 armnn::Pooling2dDescriptor descriptor;
1275 descriptor.m_PoolType = armnn::PoolingAlgorithm::L2;
1276 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
1277 descriptor.m_StrideX = descriptor.m_StrideY = 1;
1278 descriptor.m_PadLeft = 1;
1279 descriptor.m_PadRight = 1;
1280 descriptor.m_PadTop = 1;
1281 descriptor.m_PadBottom = 1;
1282 descriptor.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
1283
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001284 armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
1285 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001286
1287 // Set quantization parameters if the requested type is a quantized type.
1288 if(armnn::IsQuantizedType<T>())
1289 {
1290 inputTensorInfo.SetQuantizationScale(qScale);
1291 inputTensorInfo.SetQuantizationOffset(qOffset);
1292 outputTensorInfo.SetQuantizationScale(qScale);
1293 outputTensorInfo.SetQuantizationOffset(qOffset);
1294 }
1295
1296 auto input = MakeTensor<T, 4>(inputTensorInfo,
1297 QuantizedVector<T>(qScale, qOffset, {
1298 1.0f, 2.0f, 3.0f, 4.0f,
1299 1.0f, 2.0f, 3.0f, 4.0f,
1300 1.0f, 2.0f, 3.0f, 4.0f,
1301 1.0f, 2.0f, 3.0f, 4.0f,
1302 }));
1303
1304 auto outputExpected = MakeTensor<T, 4>(outputTensorInfo,
1305 QuantizedVector<T>(qScale, qOffset, {
1306 1.0540f, 1.7638f, 2.5385f, 2.3570f,
1307 1.2909f, 2.1602f, 3.1091f, 2.8867f,
1308 1.2909f, 2.1602f, 3.1091f, 2.8867f,
1309 1.0540f, 1.7638f, 2.5385f, 2.3570f,
1310 }));
1311
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001312 return SimplePooling2dTestImpl<ArmnnType>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001313 workloadFactory, memoryManager, descriptor, qScale, qOffset, input, outputExpected);
telsoa014fcda012018-03-09 14:13:49 +00001314}