blob: 0982d01e2e912aed443e80f4f07f5351da4c2fa9 [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "Conv2dTestImpl.hpp"
7
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01008#include <QuantizeHelper.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +00009#include <armnnUtils/TensorUtils.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010010
Jan Eilers8eb25602020-03-09 12:13:48 +000011#include <armnn/utility/IgnoreUnused.hpp>
Matthew Sloyan171214c2020-09-09 09:07:37 +010012#include <armnn/utility/NumericCast.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000013#include <armnnUtils/DataLayoutIndexed.hpp>
14#include <armnnUtils/Permute.hpp>
15
Colm Donelan0c479742021-12-10 12:43:54 +000016#include <armnn/backends/TensorHandle.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010017
Sadik Armagana097d2a2021-11-24 15:47:28 +000018#include <armnnTestUtils/DataLayoutUtils.hpp>
19#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000020#include <armnnTestUtils/WorkloadTestUtils.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010021
Sadik Armagana097d2a2021-11-24 15:47:28 +000022#include <TensorHelpers.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010023
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010024#include <string>
25
26//
27// Static data
28//
29
30// 2-channel bias used by a number of Conv2d tests.
31static std::vector<float> Bias2({0, 2});
32
33static std::vector<float> Bias4({1, 2, 3, 4});
34
35static std::vector<float> Bias8({1, 2, 3, 4, 1, 2, 3, 4});
36
37// 3-channel 16x8 image used as common input data for a number of Conv2d tests.
38static std::vector<float> ConvInput3x8x16({
39 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
40 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
41 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
42 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
43 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
44 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
45 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
46 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
47 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
56 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
58 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
63});
64
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010065using namespace armnnUtils;
66
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010067//
68// Helper templates
69//
70
71// Helper template that returns either Bias2 or an empty vector depending on whether bias is enabled.
72template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Sadik Armagan483c8112021-06-01 09:24:52 +010073std::vector<T> GetBias2(bool biasEnabled, float qScale)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010074{
75 if(biasEnabled)
76 {
Sadik Armagan483c8112021-06-01 09:24:52 +010077 return QuantizedVector<T>(Bias2, qScale, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010078 }
79 else
80 {
Sadik Armagan483c8112021-06-01 09:24:52 +010081 return std::vector<T>();
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010082 }
83}
84
85// Helper template that returns either Bias4 or an empty vector depending on whether bias is enabled.
86template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Sadik Armagan483c8112021-06-01 09:24:52 +010087std::vector<T> GetBias4(bool biasEnabled, float qScale)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010088{
89 if(biasEnabled)
90 {
Sadik Armagan483c8112021-06-01 09:24:52 +010091 return QuantizedVector<T>(Bias4, qScale, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010092 }
93 else
94 {
Sadik Armagan483c8112021-06-01 09:24:52 +010095 return std::vector<T>();
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010096 }
97}
98
99// Helper template that returns either Bias8 or an empty vector depending on whether bias is enabled.
100template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Sadik Armagan483c8112021-06-01 09:24:52 +0100101std::vector<T> GetBias8(bool biasEnabled, float qScale)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100102{
103 if(biasEnabled)
104 {
Sadik Armagan483c8112021-06-01 09:24:52 +0100105 return QuantizedVector<T>(Bias8, qScale, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100106 }
107 else
108 {
Sadik Armagan483c8112021-06-01 09:24:52 +0100109 return std::vector<T>();
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100110 }
111}
112
113// Helper template that returns either Bias4 or an empty vector depending on whether bias is enabled.
114template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Sadik Armagan483c8112021-06-01 09:24:52 +0100115std::vector<T> GetBias(bool biasEnabled, float qScale, armnn::TensorInfo outputInfo, armnn::DataLayout layout)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100116{
117 const armnnUtils::DataLayoutIndexed dataLayoutIndexed(layout);
118 const unsigned int channelsIndex = dataLayoutIndexed.GetChannelsIndex();
119 const unsigned int outputChannels = outputInfo.GetShape()[channelsIndex];
120
121 switch (outputChannels)
122 {
123 case 2:
124 default:
125 {
126 return GetBias2<ArmnnType>(biasEnabled, qScale);
127 }
128 case 4:
129 {
130 return GetBias4<ArmnnType>(biasEnabled, qScale);
131 }
132 case 8:
133 {
134 return GetBias8<ArmnnType>(biasEnabled, qScale);
135 }
136 }
137}
138
139//
140// Implementation templates
141//
142
143// Mapping from input type to bias type for fully connected layers.
144// float => float, uint8_t => int32_t
145template<typename T>
146struct FullyConnectedBiasTypeForInputType;
147
148template<>
149struct FullyConnectedBiasTypeForInputType<float>
150{
151 using Type = float;
152};
153
154template<>
155struct FullyConnectedBiasTypeForInputType<uint8_t>
156{
157 using Type = int32_t;
158};
159
160// Modifies a std::vector in-place using a specified bias.
161template<typename T, typename B>
162void ApplyBias(std::vector<T>& v, float vScale, int32_t vOffset,
163 const std::vector<B>& bias, float bScale, int32_t bOffset, uint32_t w, uint32_t h)
164{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100165 ARMNN_ASSERT_MSG((armnn::IsQuantizedType<T>() && vScale != 0.0f) || (!armnn::IsQuantizedType<T>()),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100166 "Invalid type and parameter combination.");
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100167 ARMNN_ASSERT_MSG((armnn::IsQuantizedType<B>() && bScale != 0.0f) || (!armnn::IsQuantizedType<B>()),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100168 "Invalid type and parameter combination.");
169
170 // Note we need to dequantize and re-quantize the image value and the bias.
171 for (uint32_t i = 0; i < bias.size(); ++i)
172 {
173 float dBias = SelectiveDequantize(bias[i], bScale, bOffset);
174 for (uint32_t y = 0; y < h; ++y)
175 {
176 for (uint32_t x = 0; x < w; ++x)
177 {
178 uint32_t offset = (i * h + y) * w + x;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100179 ARMNN_ASSERT(offset < v.size());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100180 T& outRef = v[offset];
181 float dOutput = SelectiveDequantize(outRef, vScale, vOffset);
182 outRef = SelectiveQuantize<T>(dOutput + dBias, vScale, vOffset);
183 }
184 }
185 }
186}
187
188//
189// Convolution2d implementations
190//
191
192template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
193 typename T = armnn::ResolveType<ArmnnType>, typename B = armnn::ResolveType<ArmnnBType>>
194LayerTestResult<T, 4> SimpleConvolution2dTestImpl(
195 armnn::IWorkloadFactory& workloadFactory,
196 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100197 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +0100198 const std::vector<T>& originalInput,
199 const std::vector<T>& originalKernel,
200 const std::vector<B>& bias,
201 const std::vector<T>& originalOutputExpected,
202 const armnn::TensorShape& originalInputShape,
203 const armnn::TensorShape& originalKernelShape,
204 const armnn::TensorShape& originalOutputExpectedShape,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100205 float qScale,
206 int32_t qOffset,
207 const armnn::DataLayout layout = armnn::DataLayout::NCHW,
208 uint32_t padLeft = 0,
209 uint32_t padTop = 0,
210 uint32_t padRight = 0,
211 uint32_t padBottom = 0,
212 uint32_t strideX = 1,
213 uint32_t strideY = 1,
214 uint32_t dilationX = 1,
215 uint32_t dilationY = 1)
216{
Jan Eilers8eb25602020-03-09 12:13:48 +0000217 armnn::IgnoreUnused(memoryManager);
Sadik Armagan483c8112021-06-01 09:24:52 +0100218 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(originalInputShape[2]);
219 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(originalInputShape[3]);
220 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(originalInputShape[1]);
221 unsigned int inputNum = armnn::numeric_cast<unsigned int>(originalInputShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100222
Sadik Armagan483c8112021-06-01 09:24:52 +0100223 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[2]);
224 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[3]);
225 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[1]);
226 unsigned int outputNum = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100227
Sadik Armagan483c8112021-06-01 09:24:52 +0100228 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(originalKernelShape[2]);
229 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(originalKernelShape[3]);
230 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(originalKernelShape[1]);
231 unsigned int kernelDepthMul = armnn::numeric_cast<unsigned int>(originalKernelShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100232
233 bool biasEnabled = bias.size() > 0;
234
235 // This function currently assumes 1 batch of input/output (and duplicates this into 2 batches).
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100236 ARMNN_ASSERT(inputNum == 1);
237 ARMNN_ASSERT(outputNum == 1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100238
239 // If a bias is used, its size must equal the number of output channels.
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100240 ARMNN_ASSERT(!biasEnabled || bias.size() == outputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100241
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100242 // Note these tensors will use two (identical) batches.
243 armnn::TensorInfo inputTensorInfo =
244 armnnUtils::GetTensorInfo(2*inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
245 armnn::TensorInfo outputTensorInfo =
246 armnnUtils::GetTensorInfo(2*outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
247 armnn::TensorInfo kernelDesc =
248 armnnUtils::GetTensorInfo(kernelDepthMul, kernelChannels, kernelHeight, kernelWidth, layout, ArmnnType);
249 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
250
251 // Set quantization parameters if the requested type is a quantized type.
252 if(armnn::IsQuantizedType<T>())
253 {
254 inputTensorInfo.SetQuantizationScale(qScale);
255 inputTensorInfo.SetQuantizationOffset(qOffset);
256 outputTensorInfo.SetQuantizationScale(qScale);
257 outputTensorInfo.SetQuantizationOffset(qOffset);
258 kernelDesc.SetQuantizationScale(qScale);
259 kernelDesc.SetQuantizationOffset(qOffset);
260 biasDesc.SetQuantizationScale(qScale*qScale);
261 biasDesc.SetQuantizationOffset(0);
262 }
263
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100264 // Construct input data - two batches of the same input image.
265 std::vector<T> inputImage;
266 inputImage.assign(originalInput.data(), originalInput.data() + 1*inputChannels*inputHeight*inputWidth);
267 std::vector<T> inputData;
268 inputData.insert(inputData.end(), inputImage.begin(), inputImage.end());
269 inputData.insert(inputData.end(), inputImage.begin(), inputImage.end());
270
271 // at this point if we require it permute the input data
272 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
273 if (layout == armnn::DataLayout::NHWC)
274 {
275 std::vector<T> tmp(inputData.size());
276 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
277 inputData = tmp;
278 }
279
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100280 std::vector<T> outputImage;
281 outputImage.assign(originalOutputExpected.data(),
282 originalOutputExpected.data() + outputChannels*outputHeight*outputWidth);
283
284 // Apply bias to output image if it is enabled.
285 if(biasEnabled)
286 {
287 std::vector<T> biasV;
288 biasV.assign(bias.data(), bias.data() + outputChannels);
289 ApplyBias(outputImage, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
290 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
291 outputWidth, outputHeight);
292 }
293
Sadik Armagan483c8112021-06-01 09:24:52 +0100294 // Data will be copied from outputHandle
295 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
296
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100297 // Construct expected output data - two identical images.
Sadik Armagan483c8112021-06-01 09:24:52 +0100298 std::vector<T> expectedOutput;
299 expectedOutput.insert(expectedOutput.end(), outputImage.begin(), outputImage.end());
300 expectedOutput.insert(expectedOutput.end(), outputImage.begin(), outputImage.end());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100301
302 // at this point if we require it permute the expected output
303 if (layout == armnn::DataLayout::NHWC)
304 {
Sadik Armagan483c8112021-06-01 09:24:52 +0100305 std::vector<T> tmp(expectedOutput.size());
306 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, expectedOutput.data(), tmp.data(), sizeof(T));
307 expectedOutput = tmp;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100308 }
Keith Davisf500d6c2020-08-31 08:32:55 +0100309
310 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
311 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
312
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100313 armnn::Convolution2dQueueDescriptor data;
314 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +0100315 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
316 armnn::ScopedTensorHandle biasTensor(biasDesc);
Sadik Armagan483c8112021-06-01 09:24:52 +0100317
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100318 // Permute the kernel if necessary
Sadik Armagan483c8112021-06-01 09:24:52 +0100319 std::vector<T> kernel = originalKernel;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100320 if (layout == armnn::DataLayout::NHWC)
321 {
322 armnnUtils::Permute(kernelDesc.GetShape(), NCHWToNHWC, originalKernel.data(), kernel.data(), sizeof(T));
323 }
Sadik Armagan483c8112021-06-01 09:24:52 +0100324 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100325
326 if(biasEnabled)
327 {
Sadik Armagan483c8112021-06-01 09:24:52 +0100328 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100329 }
330
331 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
332 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
333
334 data.m_Weight = &weightsTensor;
335 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - can be a source of bugs.
336 data.m_Parameters.m_StrideX = strideX;
337 data.m_Parameters.m_StrideY = strideY;
338 data.m_Parameters.m_PadLeft = padLeft;
339 data.m_Parameters.m_PadRight = padRight;
340 data.m_Parameters.m_PadTop = padTop;
341 data.m_Parameters.m_PadBottom = padBottom;
342 data.m_Parameters.m_BiasEnabled = biasEnabled;
343 data.m_Parameters.m_DataLayout = layout;
344 data.m_Parameters.m_DilationX = dilationX;
345 data.m_Parameters.m_DilationY = dilationY;
346
347 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateConvolution2d(data, info);
348 inputHandle->Allocate();
349 outputHandle->Allocate();
350
Sadik Armagan483c8112021-06-01 09:24:52 +0100351 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100352
353 ExecuteWorkload(*workload, memoryManager);
354
Sadik Armagan483c8112021-06-01 09:24:52 +0100355 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100356
Sadik Armagan483c8112021-06-01 09:24:52 +0100357 return LayerTestResult<T, 4>(actualOutput,
358 expectedOutput,
359 outputHandle->GetShape(),
360 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100361}
362
363template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +0100364 typename T = armnn::ResolveType<ArmnnType>, typename B = armnn::ResolveType<ArmnnBType>,
365 armnn::DataType OutType = ArmnnType, typename O = armnn::ResolveType<OutType>>
366LayerTestResult<O, 4> SimpleConvolution2dNhwcTestImpl(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100367 armnn::IWorkloadFactory& workloadFactory,
368 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100369 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +0100370 const std::vector<T>& input,
371 const std::vector<T>& kernel,
372 const std::vector<B>& bias,
373 const std::vector<O>& outputExpected,
374 const armnn::TensorShape& inputShape,
375 const armnn::TensorShape& kernelShape,
376 const armnn::TensorShape& outputExpectedShape,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100377 const armnn::DataLayout dataLayout,
378 float qScale,
379 int32_t qOffset,
380 uint32_t padLeft = 1,
381 uint32_t padTop = 1,
382 uint32_t padRight = 1,
383 uint32_t padBottom = 1,
384 uint32_t strideX = 1,
385 uint32_t strideY = 1)
386{
Jan Eilers8eb25602020-03-09 12:13:48 +0000387 armnn::IgnoreUnused(qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100388 unsigned int inputNum = armnn::numeric_cast<unsigned int>(inputShape[0]);
389 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(inputShape[3]);
390 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(inputShape[1]);
391 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(inputShape[2]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100392
Sadik Armagan483c8112021-06-01 09:24:52 +0100393 unsigned int kernelChanMul = armnn::numeric_cast<unsigned int>(kernelShape[0]);
394 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(kernelShape[3]);
395 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(kernelShape[1]);
396 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(kernelShape[2]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100397
Sadik Armagan483c8112021-06-01 09:24:52 +0100398 unsigned int outputNum = armnn::numeric_cast<unsigned int>(outputExpectedShape[0]);
399 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(outputExpectedShape[3]);
400 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(outputExpectedShape[1]);
401 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100402
403 bool biasEnabled = bias.size() > 0;
404
405 // Creates the tensors.
406 armnn::TensorInfo inputTensorInfo({inputNum, inputHeight, inputWidth, inputChannels}, ArmnnType);
407 armnn::TensorInfo outputTensorInfo({outputNum, outputHeight, outputWidth, outputChannels},
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +0100408 OutType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100409 armnn::TensorInfo kernelDesc({kernelChanMul, kernelHeight, kernelWidth, kernelChannels}, ArmnnType);
410 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
411
412 // Construct the input data.
413 std::vector<T> inputData;
414 inputData.assign(input.data(), input.data() + inputHeight*inputWidth*inputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100415
416 // Construct the output data, with bias applied, as appropriate.
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +0100417 std::vector<O> outputData;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100418 outputData.assign(outputExpected.data(), outputExpected.data() + outputHeight*outputWidth*outputChannels);
419
Sadik Armagan483c8112021-06-01 09:24:52 +0100420 std::vector<O> actualOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100421
422 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
423 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
424
James Conroy1f58f032021-04-27 17:13:27 +0100425 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
Sadik Armagan483c8112021-06-01 09:24:52 +0100426 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100427
James Conroy1f58f032021-04-27 17:13:27 +0100428 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100429
430 armnn::Convolution2dQueueDescriptor data;
431
432 data.m_Weight = &weightsTensor;
433 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - can be a source of bugs.
434 data.m_Parameters.m_StrideX = strideX;
435 data.m_Parameters.m_StrideY = strideY;
436 data.m_Parameters.m_PadLeft = padLeft;
437 data.m_Parameters.m_PadRight = padRight;
438 data.m_Parameters.m_PadTop = padTop;
439 data.m_Parameters.m_PadBottom = padBottom;
440 data.m_Parameters.m_BiasEnabled = biasEnabled;
441 data.m_Parameters.m_DataLayout = dataLayout;
442
443 armnn::WorkloadInfo info;
444 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
445 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
446
447 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateConvolution2d(data, info);
448 inputHandle->Allocate();
449 outputHandle->Allocate();
450
Sadik Armagan483c8112021-06-01 09:24:52 +0100451 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100452
453 ExecuteWorkload(*workload, memoryManager);
454
Sadik Armagan483c8112021-06-01 09:24:52 +0100455 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100456
Sadik Armagan483c8112021-06-01 09:24:52 +0100457 return LayerTestResult<O, 4>(actualOutput,
458 outputData,
459 outputHandle->GetShape(),
460 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100461}
462
463template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
464LayerTestResult<T,4> Convolution1dTestImpl(
465 armnn::IWorkloadFactory& workloadFactory,
466 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100467 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100468 float qScale,
469 int32_t qOffset,
470 bool biasEnabled)
471{
472 using B = armnn::ResolveType<ArmnnBType>;
473 // Until we have a specialist 1D convolution layer, we can fake one using
474 // 2D convolution with the final dimension set to 1.
475 // I don't anticipate this being particularly slow, given that convolution is implemented
476 // as a matrix multiplication, at which point dimension doesn't matter.
477
478 unsigned int batchSize = 1;
479 unsigned int inputChannels = 2;
480 unsigned int outputChannels = 3;
481 unsigned int inputSize = 5; // The 1D size (could view as 'width' or 'height').
482 unsigned int kernelSize = 3;
483 unsigned int padSize = 2;
484 unsigned int stride = 1;
485 unsigned int outputSize = 7; // (inputSize + 2 * padSize - kernelSize + 1) / stride.
486
487 armnn::TensorInfo inputInfo({batchSize, inputChannels, inputSize, 1}, ArmnnType);
488 armnn::TensorInfo outputInfo({batchSize, outputChannels, outputSize, 1}, ArmnnType);
489 armnn::TensorInfo kernelInfo({outputChannels, inputChannels, kernelSize, 1}, ArmnnType);
490 armnn::TensorInfo biasInfo({outputChannels}, ArmnnBType);
491
492 // Set quantization parameters if the requested type is a quantized type.
493 if(armnn::IsQuantizedType<T>())
494 {
495 inputInfo.SetQuantizationScale(qScale);
496 inputInfo.SetQuantizationOffset(qOffset);
497 outputInfo.SetQuantizationScale(qScale);
498 outputInfo.SetQuantizationOffset(qOffset);
499 kernelInfo.SetQuantizationScale(qScale);
500 kernelInfo.SetQuantizationOffset(qOffset);
501 biasInfo.SetQuantizationScale(inputInfo.GetQuantizationScale()*kernelInfo.GetQuantizationScale());
502 biasInfo.SetQuantizationOffset(0);
503 }
504
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100505 std::vector<T> inputData = QuantizedVector<T>(
506 {
507 5.0f, -2.0f, 2.5f, 0.0f, 1.0f,
508 -3.0f, 3.2f, 5.0f, 2.0f, 3.0f,
509 },
510 inputInfo.GetQuantizationScale(),
511 inputInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100512
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100513 std::vector<T> kernelData = QuantizedVector<T>(
514 {
515 1.0f, 0.0f, 0.0f,
516 0.0f, 2.0f, -1.5f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100517
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100518 0.0f, 0.0f, 0.0f,
519 0.2f, 0.2f, 0.2f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100520
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100521 0.5f, 0.0f, 0.5f,
522 0.0f, -1.0f, 0.0f
523 },
524 kernelInfo.GetQuantizationScale(),
525 kernelInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100526
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100527 std::vector<B> biasData =
528 QuantizedVector<B>({ 1.0f, 0.0f, 0.0f }, biasInfo.GetQuantizationScale(), biasInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100529
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100530 std::vector<T> outputData = QuantizedVector<T>(
531 {
532 4.5f, -10.8f, 5.0f + 6.4f - 7.5f, -2.0f + 10.0f -3.0f, 2.5f + 4.0f - 4.5f, 6.0f, 1.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100533 -0.6f, -0.6f + 0.64f, -0.6f + 0.64f + 1.0f, 0.64f + 1.0f + 0.4f, 1.0f + 0.4f + 0.6f, 0.4f + 0.6f, 0.6f,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100534 2.5f, -1.0f + 3.0f, 1.25f - 3.2f + 2.5f, -1.0f - 5.0f, 1.25f + 0.5f - 2.0f, -3.0f, 0.5f
535 },
536 outputInfo.GetQuantizationScale(),
537 outputInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100538
Sadik Armagan483c8112021-06-01 09:24:52 +0100539 std::vector<T> actualOutput(outputInfo.GetNumElements());
540
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100541 // Optionally apply bias to output image.
542 if(biasEnabled)
543 {
544 ApplyBias(outputData, outputInfo.GetQuantizationScale(), outputInfo.GetQuantizationOffset(),
545 biasData, biasInfo.GetQuantizationScale(), biasInfo.GetQuantizationOffset(),
546 1, outputSize);
547 }
Keith Davisf500d6c2020-08-31 08:32:55 +0100548
549 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
550 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
551
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100552 armnn::Convolution2dQueueDescriptor data;
553 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +0100554 armnn::ScopedTensorHandle weightsTensor(kernelInfo);
555 armnn::ScopedTensorHandle biasTensor(biasInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100556
557 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
558 AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
559
560 AddInputToWorkload(data, info, inputInfo, inputHandle.get());
561 AddOutputToWorkload(data, info, outputInfo, outputHandle.get());
562
563 data.m_Weight = &weightsTensor;
564 data.m_Bias = &biasTensor;
565 data.m_Parameters.m_StrideX = 1;
566 data.m_Parameters.m_StrideY = stride;
567 data.m_Parameters.m_PadLeft = 0;
568 data.m_Parameters.m_PadRight = 0;
569 data.m_Parameters.m_PadTop = padSize;
570 data.m_Parameters.m_PadBottom = padSize;
571 data.m_Parameters.m_BiasEnabled = biasEnabled;
572
573 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateConvolution2d(data, info);
574 inputHandle->Allocate();
575 outputHandle->Allocate();
576
577 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
578
579 ExecuteWorkload(*workload, memoryManager);
580
Sadik Armagan483c8112021-06-01 09:24:52 +0100581 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
582
583 return LayerTestResult<T, 4>(actualOutput,
584 outputData,
585 outputHandle->GetShape(),
586 outputInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100587}
588
589template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
590LayerTestResult<T, 4> SimpleConvolution2d3x3NhwcTestCommon(
591 armnn::IWorkloadFactory& workloadFactory,
592 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100593 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100594 float qScale,
595 int32_t qOffset,
596 bool biasEnabled,
597 armnn::DataLayout dataLayout)
598{
Jan Eilers8eb25602020-03-09 12:13:48 +0000599 armnn::IgnoreUnused(biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100600 // Use common single-batch 5x5 image.
601
Sadik Armagan483c8112021-06-01 09:24:52 +0100602 armnn::TensorInfo inputDesc({ 1, 3, 4, 1 }, ArmnnType);
603 std::vector<T> input =
604 {
605 1, 5, 2, 3,
606 8, 7, 3, 6,
607 3, 3, 9, 1
608 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100609
610 // Use a 2-element batch of 3-channel 3x3 kernels.
Sadik Armagan483c8112021-06-01 09:24:52 +0100611 armnn::TensorInfo kernelDesc({ 1, 3, 3, 1 }, ArmnnType);
612 std::vector<T> kernel =
613 {
614 4, 5, 6,
615 0, 0, 0,
616 3, 2, 1
617 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100618
619 // Expected output is 1 batch of a 5x5 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100620 armnn::TensorInfo outputDesc({ 1, 3, 4, 1 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100621 const std::vector<float> outputData =
Sadik Armagan483c8112021-06-01 09:24:52 +0100622 {
623 23, 41, 33, 21,
624 44, 65, 76, 52,
625 82, 85, 79, 42
626 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100627
628 return SimpleConvolution2dNhwcTestImpl<ArmnnType, ArmnnType>(
629 workloadFactory,
630 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100631 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100632 input,
633 kernel,
Sadik Armagan483c8112021-06-01 09:24:52 +0100634 std::vector<T>(),
635 outputData,
636 inputDesc.GetShape(),
637 kernelDesc.GetShape(),
638 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100639 dataLayout,
640 qScale,
641 qOffset);
642}
643
644template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
645LayerTestResult<T, 4> SimpleConvolution2d3x3Stride2x2TestCommon(
646 armnn::IWorkloadFactory& workloadFactory,
647 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100648 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100649 float qScale,
650 int32_t qOffset,
651 bool biasEnabled,
652 const armnn::DataLayout& dataLayout)
653{
Jan Eilers8eb25602020-03-09 12:13:48 +0000654 armnn::IgnoreUnused(biasEnabled);
Derek Lambertic374ff02019-12-10 21:57:35 +0000655
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100656 // Input is a single-batch, 1 channel, 5x5 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100657 armnn::TensorInfo inputDesc({ 1, 5, 5, 1 }, ArmnnType);
658 std::vector<T> input =
659 {
660 1, 5, 2, 3, 5,
661 8, 7, 3, 6, 3,
662 3, 3, 9, 1, 9,
663 4, 1, 8, 1, 3,
664 6, 8, 1, 9, 2
665 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100666
667 // Use a 3x3 kernel.
Sadik Armagan483c8112021-06-01 09:24:52 +0100668 armnn::TensorInfo kernelDesc({ 1, 3, 3, 1 }, ArmnnType);
669 std::vector<T> kernel =
670 {
671 4, 5, 6,
672 0, 0, 0,
673 3, 2, 1
674 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100675
676 // Expected output is a single-batch, 1 channel, 3x3 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100677 armnn::TensorInfo outputDesc({ 1, 3, 3, 1 }, ArmnnType);
678 std::vector<T> outputData =
679 {
680 23, 33, 24,
681 91, 99, 48,
682 26, 50, 19
683 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100684
685 uint32_t padLeft = 1;
686 uint32_t padTop = 1;
687 uint32_t padRight = 1;
688 uint32_t padBottom = 1;
689 uint32_t strideX = 2;
690 uint32_t strideY = 2;
691
692 return SimpleConvolution2dNhwcTestImpl<ArmnnType, ArmnnType>(
693 workloadFactory,
694 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100695 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100696 input,
697 kernel,
Sadik Armagan483c8112021-06-01 09:24:52 +0100698 std::vector<T>(),
699 outputData,
700 inputDesc.GetShape(),
701 kernelDesc.GetShape(),
702 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100703 dataLayout,
704 qScale,
705 qOffset,
706 padLeft,
707 padTop,
708 padRight,
709 padBottom,
710 strideX,
711 strideY);
712}
713
714template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
715LayerTestResult<T, 4> SimpleConvolution2d3x5TestCommon(
716 armnn::IWorkloadFactory& workloadFactory,
717 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100718 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100719 float qScale,
720 int32_t qOffset,
721 bool biasEnabled,
722 const armnn::DataLayout layout)
723{
724 // Use common single-batch 3-channel 16x8 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100725 armnn::TensorInfo inputDesc({ 1, 3, 8, 16 }, ArmnnType);
726 std::vector<T> input = QuantizedVector<T>(ConvInput3x8x16, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100727
728 // Use a 2-element batch with 3-channel 3x5 kernels.
Sadik Armagan483c8112021-06-01 09:24:52 +0100729 armnn::TensorInfo kernelDesc({ 2, 3, 5, 3 }, ArmnnType);
730 std::vector<T> kernel = QuantizedVector<T>({
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100731 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100732 1, -1, 1,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100733 1, 1, 1,
734 1, 1, 1,
735 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100736
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100737 0, 0, 0,
738 0, 0, 0,
739 0, 0, 0,
740 0, 0, 0,
741 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100742
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100743 2, 2, 2,
744 2, 2, 2,
745 2, 2, 2,
746 2, 2, 2,
747 2, 2, 2,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100748
749
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100750 0, 0, 0,
751 0, 0, 0,
752 0, 0, 0,
753 0, 0, 0,
754 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100755
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100756 1, 1, 1,
757 1, 1, 1,
758 1, 1, 1,
759 1, 1, 1,
760 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100761
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100762 0, 0, 0,
763 0, 0, 0,
764 0, 0, 0,
765 0, 0, 0,
766 0, 0, 0
767 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100768 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100769
770 // Expected output is 2 batch elements of a 1-channel 14x4 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100771 armnn::TensorInfo outputDesc({ 1, 2, 4, 14 }, ArmnnType);
772 std::vector<T> expectedOutput = QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100773 -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
774 -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
775 -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f,
776 -23.5f, -23.5f, -23.5f,
777 -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f,
778 -23.5f, -23.5f, -23.5f,
779
780 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
781 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
782 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
783 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100784 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100785 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100786
787 return SimpleConvolution2dTestImpl<ArmnnType, ArmnnBType>(
788 workloadFactory,
789 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100790 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100791 input,
792 kernel,
793 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
794 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +0100795 inputDesc.GetShape(),
796 kernelDesc.GetShape(),
797 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100798 qScale,
799 qOffset,
800 layout);
801}
802
803template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
804 typename T = armnn::ResolveType<ArmnnType>>
805LayerTestResult<T, 4> SimpleConvolution2d3x3TestCommon(
806 armnn::IWorkloadFactory& workloadFactory,
807 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100808 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100809 float qScale,
810 int32_t qOffset,
811 bool biasEnabled,
812 const armnn::DataLayout layout)
813{
814 // Use a 3x3 kernel, which exercises ArmCompute's direct convolution path.
815
816 // Use common single-batch 3-channel 16x8 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100817 armnn::TensorInfo inputDesc({ 1, 3, 8, 16 }, ArmnnType);
818 std::vector<unsigned int> inputShape = { 1, 3, 8, 16 };
819 std::vector<T> input = QuantizedVector<T>(ConvInput3x8x16, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100820
821 // Use a 2-element batch of 3-channel 3x3 kernels.
Sadik Armagan483c8112021-06-01 09:24:52 +0100822 armnn::TensorInfo kernelDesc({ 2, 3, 3, 3 }, ArmnnType);
823 std::vector<T> kernel = QuantizedVector<T>({
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100824 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100825 1, -1, 1,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100826 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100827
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100828 0, 0, 0,
829 0, 0, 0,
830 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100831
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100832 2, 2, 2,
833 2, 2, 2,
834 2, 2, 2,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100835
836
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100837 0, 0, 0,
838 0, 0, 0,
839 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100840
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100841 1, 1, 1,
842 1, 1, 1,
843 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100844
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100845 0, 0, 0,
846 0, 0, 0,
847 0, 0, 0
848 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100849 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100850
851 // Expected output is 1 batch of a 2-channel 14x6 image.
Sadik Armagan483c8112021-06-01 09:24:52 +0100852 armnn::TensorInfo outputDesc({ 1, 2, 6, 14 }, ArmnnType);
853 std::vector<T> expectedOutput = QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100854 -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
855 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
856 -14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,
857 -14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,
858 -14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,
859 -14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,-14.5f,
860
861 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
862 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
863 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
864 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
865 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
866 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100867 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100868 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100869
870 return SimpleConvolution2dTestImpl<ArmnnType, ArmnnBType>(
871 workloadFactory,
872 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100873 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100874 input,
875 kernel,
876 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
877 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +0100878 inputDesc.GetShape(),
879 kernelDesc.GetShape(),
880 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100881 qScale,
882 qOffset,
883 layout);
884}
885
886template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
887 typename T = armnn::ResolveType<ArmnnType>>
888LayerTestResult<T, 4> Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTestCommon(
889 armnn::IWorkloadFactory& workloadFactory,
890 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100891 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100892 const armnn::DataLayout layout,
893 float qScale,
894 int32_t qOffset)
895{
896 // Use a single-batch 1-channel 3x3 image as input.
Sadik Armagan483c8112021-06-01 09:24:52 +0100897 armnn::TensorInfo inputDesc({ 1, 1, 3, 3 }, ArmnnType);
898 std::vector<T> input =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100899 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100900 11,21,31,
901 12,22,32,
902 13,23,33
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100903 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100904 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100905
906 // Use 1 batch of a 1-channel 2x2 kernel.
Sadik Armagan483c8112021-06-01 09:24:52 +0100907 armnn::TensorInfo kernelDesc({ 1, 1, 2, 2 }, ArmnnType);
908 std::vector<T> kernel =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100909 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100910 -11,-21,
911 -12,-22,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100912 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100913 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100914
915// Expected output is 1 batch of a 1-channel 6x8 image.
916// Manually calculated like this:
917//[-11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ..]
918//[-11*0 -21*0 -12*0 -22*11 ; -11*0 -21*0 -12*11 -22*21 ; -11*0 -21*0 -12*21 -22*31 ; -11*0 -21*0 -12*31 -22*0 ..]
919//[-11*0 -21*11 -12*0 -22*12 ; -11*11 -21*21 -12*12 -22*22 ; -11*21 -21*31 -12*22 -22*32 ; -11*31 -21*0 -12*32 -22*0 ..]
920//[-11*0 -21*12 -12*0 -22*13 ; -11*12 -21*22 -12*13 -22*23 ; -11*22 -21*32 -12*23 -22*33 ; -11*32 -21*0 -12*33 -22*0 ..]
921//[-11*0 -21*13 -12*0 -22*0 ; -11*13 -21*23 -12*0 -22*0 ; -11*23 -21*33 -12*0 -22*0 ; -11*33 -21*0 -12*0 -22*0 ..]
922//[-11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ; -11*0 -21*0 -12*0 -22*0 ..]
923//[..... ..... ..... ..... ; ..... ..... ..... ..... ; ..... ..... ..... ..... ; ..... ..... ..... ..... ..]
Sadik Armagan483c8112021-06-01 09:24:52 +0100924 armnn::TensorInfo outputDesc({ 1, 1, 8, 6 }, ArmnnType);
925 std::vector<T> expectedOutput =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100926 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100927 0, 0, 0, 0, 0, 0,
928 -242, -594, -934, -372, 0, 0,
929 -495, -1190, -1850, -725, 0, 0,
930 -538, -1256, -1916, -748, 0, 0,
931 -273, -626, -946, -363, 0, 0,
932 0, 0, 0, 0, 0, 0,
933 0, 0, 0, 0, 0, 0,
934 0, 0, 0, 0, 0, 0
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100935 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100936 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100937
938 return SimpleConvolution2dTestImpl<ArmnnType, ArmnnBType>(
939 workloadFactory,
940 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100941 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100942 input,
943 kernel,
944 GetBias2<ArmnnBType>(false, qScale * qScale),
945 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +0100946 inputDesc.GetShape(),
947 kernelDesc.GetShape(),
948 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100949 qScale,
950 qOffset,
951 layout,
952 1, // Padding left.
953 2, // Padding top.
954 3, // Padding right.
955 4); // Padding bottom.
956}
957
958template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
959 typename T = armnn::ResolveType<ArmnnType>>
960LayerTestResult<T, 4> SimpleConvolution2dAsymmetricPaddingTestCommon(
961 armnn::IWorkloadFactory& workloadFactory,
962 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100963 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100964 const armnn::DataLayout layout,
965 float qScale,
966 int32_t qOffset)
967{
968 // Use a single-batch 1-channel 5x5 image as input.
969 armnn::TensorInfo inputDesc({ 1, 1, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +0100970 std::vector<T> input =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100971 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100972 11,21,31,41,51,
973 12,22,32,42,52,
974 13,23,33,43,53,
975 14,24,34,44,54,
976 15,25,35,45,55,
Sadik Armagan483c8112021-06-01 09:24:52 +0100977 }, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100978
979 // Use 1 batch of a 1-channel 4x4 kernel.
980 armnn::TensorInfo kernelDesc({ 1, 1, 4, 4 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +0100981 std::vector<T> kernel =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100982 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100983 -11,-21,-31,-41,
984 -12,-22,-32,-42,
985 -13,-23,-33,-43,
986 -14,-24,-34,-44,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100987 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100988 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100989
990 // Expected output is 1 batch of a 1-channel 5x5 image.
991 armnn::TensorInfo outputDesc({ 1, 1, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +0100992 std::vector<T> expectedOutput =
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100993 QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100994 -7140, -10580, -13940, -9300, -5230,
995 -9590, -14120, -18520, -12290, -6860,
996 -9980, -14560, -18960, -12560, -7000,
997 -7518, -10904, -14144, -9318, -5152,
998 -5032, -7256, -9376, -6142, -3368,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100999 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001000 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001001
1002 return SimpleConvolution2dTestImpl<ArmnnType, ArmnnBType>(
1003 workloadFactory,
1004 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001005 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001006 input,
1007 kernel,
1008 GetBias2<ArmnnBType>(false, qScale * qScale),
1009 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01001010 inputDesc.GetShape(),
1011 kernelDesc.GetShape(),
1012 outputDesc.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001013 qScale,
1014 qOffset,
1015 layout,
1016 1, // Padding left.
1017 1, // Padding top.
1018 2, // Padding right.
1019 2); // Padding bottom.
1020}
1021
1022template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
1023LayerTestResult<T, 4> Convolution2d3x3DilationTestCommon(
1024 armnn::IWorkloadFactory& workloadFactory,
1025 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001026 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001027 const std::vector<float>& inputNoQuantizedValues,
1028 armnn::TensorInfo& inputTensorInfo,
1029 const std::vector<float>& kernelNoQuantizedValues,
1030 armnn::TensorInfo& kernelTensorInfo,
1031 const std::vector<float>& outputExpectedNoQuantizedValues,
1032 armnn::TensorInfo& outputTensorInfo,
1033 uint32_t dilationX,
1034 uint32_t dilationY,
1035 armnn::DataLayout layout = armnn::DataLayout::NCHW,
1036 uint32_t padLeft = 0,
1037 uint32_t padTop = 0,
1038 uint32_t padRight = 0,
1039 uint32_t padBottom = 0,
1040 uint32_t strideX = 1,
1041 uint32_t strideY = 1,
1042 bool biasEnabled = false
1043)
1044{
1045 float qScale;
1046 int32_t qOffset;
1047 switch (ArmnnType)
1048 {
Derek Lambertif90c56d2020-01-10 17:14:08 +00001049 case armnn::DataType::QAsymmU8:
Sadik Armagan303980c2020-04-17 12:45:14 +01001050 case armnn::DataType::QAsymmS8:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001051 {
1052 qScale = 0.1f;
1053 qOffset = 128;
1054 break;
1055 }
Derek Lambertif90c56d2020-01-10 17:14:08 +00001056 case armnn::DataType::QSymmS16:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001057 {
1058 qScale = 0.1f;
1059 qOffset = 0;
1060 break;
1061 }
1062 case armnn::DataType::Float32:
1063 default:
1064 {
1065 qScale = 0.f;
1066 qOffset = 0;
1067 break;
1068 }
1069 }
1070
1071 inputTensorInfo.SetQuantizationScale(qScale);
1072 inputTensorInfo.SetQuantizationOffset(qOffset);
1073 kernelTensorInfo.SetQuantizationScale(qScale);
1074 kernelTensorInfo.SetQuantizationOffset(qOffset);
1075 outputTensorInfo.SetQuantizationScale(qScale);
1076 outputTensorInfo.SetQuantizationOffset(qOffset);
1077
Sadik Armagan483c8112021-06-01 09:24:52 +01001078 auto input = QuantizedVector<T>(inputNoQuantizedValues,
1079 inputTensorInfo.GetQuantizationScale(),
1080 inputTensorInfo.GetQuantizationOffset());
1081 auto kernel = QuantizedVector<T>(kernelNoQuantizedValues,
1082 kernelTensorInfo.GetQuantizationScale(),
1083 kernelTensorInfo.GetQuantizationOffset());
1084 auto expectedOutput = QuantizedVector<T>(outputExpectedNoQuantizedValues,
1085 outputTensorInfo.GetQuantizationScale(),
1086 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001087
1088 return SimpleConvolution2dTestImpl<ArmnnType, ArmnnBType>(
1089 workloadFactory,
1090 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001091 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001092 input,
1093 kernel,
1094 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
1095 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01001096 inputTensorInfo.GetShape(),
1097 kernelTensorInfo.GetShape(),
1098 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001099 qScale,
1100 qOffset,
1101 layout,
1102 padLeft,
1103 padTop,
1104 padRight,
1105 padBottom,
1106 strideX,
1107 strideY,
1108 dilationX,
1109 dilationY);
1110}
1111
1112template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
1113LayerTestResult<T, 4> Convolution2d3x3Dilation3x3Test(
1114 armnn::IWorkloadFactory& workloadFactory,
1115 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001116 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001117 bool biasEnabled,
1118 const armnn::DataLayout layout)
1119{
Sadik Armagan483c8112021-06-01 09:24:52 +01001120 armnn::TensorInfo inputTensorInfo({ 1, 1, 10, 10 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001121 std::vector<float> inputNoQuantizedValues =
1122 {
1123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1126 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1127 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1128 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1133 };
1134
1135 armnn::TensorInfo kernelTensorInfo({ 1, 1, 3, 3}, ArmnnType);
1136 std::vector<float> kernelNoQuantizedValues =
1137 {
1138 1, 2, 3,
1139 4, 5, 6,
1140 7, 8, 9
1141 };
1142
1143 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
1144 // therefore the output will be 4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
1145 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4}, ArmnnType);
1146 std::vector<float> outputExpectedNoQuantizedValues =
1147 {
1148 6., 5., 5., 5.,
1149 6., 5., 5., 5.,
1150 6., 5., 5., 5.,
1151 3., 2., 2., 2.
1152 };
1153
1154 return Convolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
1155 workloadFactory,
1156 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001157 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001158 inputNoQuantizedValues,
1159 inputTensorInfo,
1160 kernelNoQuantizedValues,
1161 kernelTensorInfo,
1162 outputExpectedNoQuantizedValues,
1163 outputTensorInfo,
1164 3,
1165 3,
1166 layout,
1167 biasEnabled);
1168}
1169
1170template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
1171LayerTestResult<T, 4> Convolution2d2x3x3Dilation3x3Test(
1172 armnn::IWorkloadFactory& workloadFactory,
1173 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001174 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001175 bool biasEnabled,
1176 const armnn::DataLayout layout)
1177{
Sadik Armagan483c8112021-06-01 09:24:52 +01001178 armnn::TensorInfo inputTensorInfo({ 1, 2, 10, 10 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001179 std::vector<float> inputNoQuantizedValues =
1180 {
1181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1184 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1185 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1186 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1191
1192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1195 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1196 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1197 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
1198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1202 };
1203
Sadik Armagan483c8112021-06-01 09:24:52 +01001204 armnn::TensorInfo kernelTensorInfo({ 1, 2, 3, 3 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001205 std::vector<float> kernelNoQuantizedValues =
1206 {
1207 1, 2, 3,
1208 4, 5, 6,
1209 7, 8, 9,
1210
1211 1, 2, 3,
1212 4, 5, 6,
1213 7, 8, 9
1214 };
1215
1216 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
1217 // therefore the output will be 4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
Sadik Armagan483c8112021-06-01 09:24:52 +01001218 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001219 std::vector<float> outputExpectedNoQuantizedValues =
1220 {
1221 12., 10., 10., 10.,
1222 12., 10., 10., 10.,
1223 12., 10., 10., 10.,
1224 6., 4., 4., 4.
1225 };
1226
1227 return Convolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
1228 workloadFactory,
1229 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001230 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001231 inputNoQuantizedValues,
1232 inputTensorInfo,
1233 kernelNoQuantizedValues,
1234 kernelTensorInfo,
1235 outputExpectedNoQuantizedValues,
1236 outputTensorInfo,
1237 3,
1238 3,
1239 layout,
1240 biasEnabled);
1241}
1242
1243template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
1244LayerTestResult<T, 4> Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test(
Sadik Armagan483c8112021-06-01 09:24:52 +01001245 armnn::IWorkloadFactory& workloadFactory,
1246 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001247 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001248 bool biasEnabled,
1249 const armnn::DataLayout layout)
1250{
Sadik Armagan483c8112021-06-01 09:24:52 +01001251 armnn::TensorInfo inputTensorInfo({ 1, 1, 10, 10 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001252 std::vector<float> inputNoQuantizedValues =
1253 {
1254 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1255 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1256 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1257 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1258 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1259 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1260 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1261 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1262 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1263 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1264 };
1265
Sadik Armagan483c8112021-06-01 09:24:52 +01001266 armnn::TensorInfo kernelTensorInfo({ 1, 1, 2, 2 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001267 std::vector<float> kernelNoQuantizedValues =
1268 {
1269 1, 2,
1270 3, 4
1271 };
1272
1273 // Since the dilation rate is 2 this will dilate the kernel to be like 3x3: d(K-1)+1 --> 2 x (2-1) + 1 = 3,
1274 // therefore the output will be 4x4: (I − K + 2P)/S +1 => trunc ( (10 - 3 + 2x2 ) / 3 + 1 )
1275 // where, dilation size = d = 2; kernel size = K = 2; input size = I = 10; padding size = P = 2; stride = S = 3
1276 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4}, ArmnnType);
1277 std::vector<float> outputExpectedNoQuantizedValues =
1278 {
1279 4, 7, 7, 3,
1280 6, 10, 10, 4,
1281 6, 10, 10, 4,
1282 2, 3, 3, 1
1283 };
1284 uint32_t padLeft = 1;
1285 uint32_t padTop = 1;
1286 uint32_t padRight = 1;
1287 uint32_t padBottom = 1;
1288
1289 return Convolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
1290 workloadFactory,
1291 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001292 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001293 inputNoQuantizedValues,
1294 inputTensorInfo,
1295 kernelNoQuantizedValues,
1296 kernelTensorInfo,
1297 outputExpectedNoQuantizedValues,
1298 outputTensorInfo,
1299 2,
1300 2,
1301 layout,
1302 padLeft,
1303 padTop,
1304 padRight,
1305 padBottom,
1306 3,
1307 3,
1308 biasEnabled
1309 );
1310}
1311
1312template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
1313LayerTestResult<T,4> CompareConvolution2dTestImpl(
1314 armnn::IWorkloadFactory& workloadFactory,
1315 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001316 armnn::IWorkloadFactory& refWorkloadFactory,
1317 const armnn::ITensorHandleFactory& tensorHandleFactory,
1318 const armnn::ITensorHandleFactory& refTensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001319{
1320 unsigned int inputHeight = 8;
1321 unsigned int inputWidth = 16;
1322 unsigned int inputChannels = 3;
1323 unsigned int inputNum = 5;
1324
1325 unsigned int kernelHeight = 3;
1326 unsigned int kernelWidth = 3;
1327
1328 unsigned int strideX = 2;
1329 unsigned int strideY = 3;
1330 unsigned int padX = 1;
1331 unsigned int padY = 1;
1332
1333 unsigned int outputNum = inputNum;
1334 unsigned int outputChannels = 2;
1335 unsigned int outputHeight = (inputHeight + 2 * padY - kernelHeight + strideY) / strideY;
1336 unsigned int outputWidth = (inputWidth + 2 * padX - kernelWidth + strideX) / strideX;
1337
1338 armnn::TensorInfo inputTensorInfo;
1339 armnn::TensorInfo outputTensorInfo;
1340 armnn::TensorInfo kernelDesc;
1341 armnn::TensorInfo biasDesc;
1342
1343 unsigned int inputShape[] = {inputNum, inputChannels, inputHeight, inputWidth};
1344 unsigned int outputShape[] = {outputNum, outputChannels, outputHeight, outputWidth};
1345 unsigned int kernelShape[] = {outputChannels, inputChannels, kernelHeight, kernelWidth};
1346 unsigned int biasShape[] = {outputChannels};
1347
1348 inputTensorInfo = armnn::TensorInfo(4, inputShape, ArmnnType);
1349 outputTensorInfo = armnn::TensorInfo(4, outputShape, ArmnnType);
1350 kernelDesc = armnn::TensorInfo(4, kernelShape, ArmnnType);
1351 biasDesc = armnn::TensorInfo(1, biasShape, ArmnnType);
1352
Sadik Armagan483c8112021-06-01 09:24:52 +01001353 auto input = MakeRandomTensor<T>(inputTensorInfo, 124908);
1354 auto kernel = MakeRandomTensor<T>(kernelDesc, 891234);
1355 auto bias = MakeRandomTensor<T>(biasDesc, 1028);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001356
Sadik Armagan483c8112021-06-01 09:24:52 +01001357 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
1358 std::vector<T> expectedOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001359
1360 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1361 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1362
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001363 armnn::Convolution2dQueueDescriptor data;
1364 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01001365 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
1366 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001367
Sadik Armagan483c8112021-06-01 09:24:52 +01001368 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
1369 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001370
1371 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1372 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1373 data.m_Weight = &weightsTensor;
1374 data.m_Bias = &biasTensor;
1375 data.m_Parameters.m_StrideX = strideX;
1376 data.m_Parameters.m_StrideY = strideY;
1377 data.m_Parameters.m_PadLeft = padX;
1378 data.m_Parameters.m_PadRight = padX;
1379 data.m_Parameters.m_PadTop = padY;
1380 data.m_Parameters.m_PadBottom = padY;
1381 data.m_Parameters.m_BiasEnabled = true;
Keith Davisf500d6c2020-08-31 08:32:55 +01001382
1383 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1384 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1385
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001386 armnn::Convolution2dQueueDescriptor refData = data;
Sadik Armagan483c8112021-06-01 09:24:52 +01001387 armnn::WorkloadInfo refInfo = info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001388 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
1389 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1390
Sadik Armagan483c8112021-06-01 09:24:52 +01001391 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateConvolution2d(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001392 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateConvolution2d(refData, refInfo);
1393
1394 outputHandleRef->Allocate();
1395 inputHandleRef->Allocate();
1396
1397 inputHandle->Allocate();
1398 outputHandle->Allocate();
1399
Sadik Armagan483c8112021-06-01 09:24:52 +01001400 CopyDataToITensorHandle(inputHandle.get(), input.data());
1401 CopyDataToITensorHandle(inputHandleRef.get(), input.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001402
1403 ExecuteWorkload(*workload, memoryManager);
1404
1405 workloadRef->PostAllocationConfigure();
1406 workloadRef->Execute();
1407
Sadik Armagan483c8112021-06-01 09:24:52 +01001408 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1409 CopyDataFromITensorHandle(expectedOutput.data(), outputHandleRef.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001410
Sadik Armagan483c8112021-06-01 09:24:52 +01001411 return LayerTestResult<T, 4>(actualOutput,
1412 expectedOutput,
1413 outputHandle->GetShape(),
1414 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001415}
1416
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001417LayerTestResult<float, 4> Convolution2d3x3Stride2x2BFloat16Test(
1418 armnn::IWorkloadFactory& workloadFactory,
1419 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001420 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001421 bool biasEnabled,
1422 const armnn::DataLayout& dataLayout)
1423{
1424 // BFloat16 input and weight, Float32 output
1425 armnn::IgnoreUnused(biasEnabled);
1426
1427 // Input is a single-batch, 1 channel, 5x5 image.
Sadik Armagan483c8112021-06-01 09:24:52 +01001428 armnn::TensorInfo inputDesc({ 1, 5, 5, 1 }, armnn::DataType::BFloat16);
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001429
1430 std::vector<armnn::BFloat16> inputValues = armnnUtils::QuantizedVector<armnn::BFloat16>(
1431 {
1432 10.0367984f, // 10.0625
1433 2.0380895f, // 2.03125
1434 15.0420157f, // 15.0625
1435 22.0675631f, // 22.125
1436 8.0938920f, // 8.125
1437 5.0476106f, // 5.0625
1438 80.1035490f, // 80
1439 100.1260370f, // 100
1440 55.0461647f, // 55
1441 120.0883828f, // 120
1442 9.1159540f, // 9.125
1443 90.0498519f, // 90
1444 200.0104630f, // 200
1445 30.0154114f, // 30
1446 75.00137681f, // 75
1447 30.0344238f, // 30
1448 25.0356445f, // 25
1449 130.0495605f, // 130
1450 60.0683594f, // 60
1451 35.0991211f, // 35
1452 8.0461426f, // 8.0625
1453 12.0996094f, // 12.125
1454 98.1269530f, // 98
1455 125.0393066f, // 125
1456 5.103516f // 5.0937
1457 },
1458 1.0f, 0);
1459
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001460 // Use a 3x3 kernel.
1461 armnn::TensorInfo kernelDesc({1, 3, 3, 1}, armnn::DataType::BFloat16);
1462
1463 std::vector<armnn::BFloat16> kernelValues = armnnUtils::QuantizedVector<armnn::BFloat16>(
1464 {
1465 -0.126184f, // -0.125977
1466 -0.150468f, // -0.150391
1467 -0.101412f, // -0.101562
1468 -0.0586369f,// -0.0585938
1469 -0.0865864f,// -0.0864258
1470 -0.0435089f,// -0.043457
1471 0.0347555f, // 0.034668
1472 0.0323111f, // 0.0322266
1473 0.0385381f // 0.0385742
1474 },
1475 1.0f, 0);
1476
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001477 // Expected output is a single-batch, 1 channel, 3x3 image.
Sadik Armagan483c8112021-06-01 09:24:52 +01001478 armnn::TensorInfo outputDesc({ 1, 3, 3, 1 }, armnn::DataType::Float32);
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001479
1480 // Expected output (with results if calculated as FP32 in the comments)
1481 const std::vector<float> outputData =
1482 {
1483 2.296875f, // 2.29240716
1484 5.75f, // 5.75851926
1485 3.78125f, // 3.79855026
1486 -11.625f, // -11.65498118
1487 -47.25f, // -47.27316893
1488 -30.0f, // -30.04771684
1489 -8.25f, // -8.28126168
1490 -43.5f, // -43.46531337
1491 -20.625f // -20.63477281
1492 };
1493
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001494 uint32_t padLeft = 1;
1495 uint32_t padTop = 1;
1496 uint32_t padRight = 1;
1497 uint32_t padBottom = 1;
1498 uint32_t strideX = 2;
1499 uint32_t strideY = 2;
1500
1501 return SimpleConvolution2dNhwcTestImpl
1502 <armnn::DataType::BFloat16, armnn::DataType::Float32, armnn::BFloat16, float, armnn::DataType::Float32, float>(
1503 workloadFactory,
1504 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001505 tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +01001506 inputValues,
1507 kernelValues,
1508 std::vector<float>(),
1509 outputData,
1510 inputDesc.GetShape(),
1511 kernelDesc.GetShape(),
1512 outputDesc.GetShape(),
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001513 dataLayout,
1514 1.0f,
1515 0,
1516 padLeft,
1517 padTop,
1518 padRight,
1519 padBottom,
1520 strideX,
1521 strideY);
1522}
1523
1524LayerTestResult<float, 4> Convolution2d3x3Stride2x2BFloat16SmallValueTest(
1525 armnn::IWorkloadFactory& workloadFactory,
1526 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001527 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001528 bool biasEnabled,
1529 const armnn::DataLayout& dataLayout)
1530{
1531 // BFloat16 input and weight, Float32 output
1532 armnn::IgnoreUnused(biasEnabled);
1533
1534 // Input is a single-batch, 1 channel, 5x5 image.
1535 armnn::TensorInfo inputDesc({1, 5, 5, 1}, armnn::DataType::BFloat16);
1536
1537 std::vector<armnn::BFloat16> inputValues = armnnUtils::QuantizedVector<armnn::BFloat16>(
1538 {
1539 0.0367984f, // 0.0368652
1540 0.0380895f, // 0.0380859
1541 0.0420157f, // 0.0419922
1542 0.0675631f, // 0.0673828
1543 0.0938920f, // 0.09375
1544 0.0476106f, // 0.0476074
1545 0.1035490f, // 0.103516
1546 0.1260370f, // 0.125977
1547 0.0461647f, // 0.0461426
1548 0.0883828f, // 0.0883789
1549 0.1159540f, // 0.115723
1550 0.0498519f, // 0.0498047
1551 0.0104630f, // 0.010437
1552 0.0154114f, // 0.0154419
1553 0.00137681f, // 0.00137329
1554 0.0344238f, // 0.0344616
1555 0.0356445f, // 0.0355693
1556 0.0495605f, // 0.0495018
1557 0.0683594f, // 0.0683308
1558 0.0991211f, // 0.0988837
1559 0.0461426f, // 0.0461838
1560 0.0996094f, // 0.0997546
1561 0.1269530f, // 0.127099
1562 0.0393066f, // 0.0392791
1563 0.103516f // 0.103641
1564 },
1565 1.0f, 0);
1566
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001567 // Use a 3x3 kernel.
1568 armnn::TensorInfo kernelDesc({1, 3, 3, 1}, armnn::DataType::BFloat16);
1569
1570 std::vector<armnn::BFloat16> kernelValues = armnnUtils::QuantizedVector<armnn::BFloat16>(
1571 {
1572 -0.126184f, // -0.125977
1573 -0.150468f, // -0.150391
1574 -0.101412f, // -0.101562
1575 -0.0586369f,// -0.0585938
1576 -0.0865864f,// -0.0864258
1577 -0.0435089f,// -0.043457
1578 0.0347555f, // 0.034668
1579 0.0323111f, // 0.0322266
1580 0.0385381f // 0.0385742
1581 },
1582 1.0f, 0);
1583
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001584 // Expected output is a single-batch, 1 channel, 3x3 image.
1585 armnn::TensorInfo outputDesc({1, 3, 3, 1}, armnn::DataType::Float32);
1586
1587 // Expected output (with results if calculated as FP32 in the comments)
1588 const std::vector<float> outputData =
1589 {
1590 0.000686645508f, // 0.000685
1591 0.000640869141f, // 0.000639
1592 -0.00759887695f, // -0.007631
1593 -0.02734375f, // -0.027388
1594 -0.0356445312f, // -0.035737
1595 -0.0145874023f, // -0.014568
1596 -0.0170898438f, // -0.017124
1597 -0.0373535156f, // -0.037431
1598 -0.0346679688f // -0.034808
1599 };
1600
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001601 uint32_t padLeft = 1;
1602 uint32_t padTop = 1;
1603 uint32_t padRight = 1;
1604 uint32_t padBottom = 1;
1605 uint32_t strideX = 2;
1606 uint32_t strideY = 2;
1607
1608 return SimpleConvolution2dNhwcTestImpl
1609 <armnn::DataType::BFloat16, armnn::DataType::Float32, armnn::BFloat16, float, armnn::DataType::Float32, float>(
1610 workloadFactory,
1611 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001612 tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +01001613 inputValues,
1614 kernelValues,
1615 std::vector<float>(),
1616 outputData,
1617 inputDesc.GetShape(),
1618 kernelDesc.GetShape(),
1619 outputDesc.GetShape(),
Narumol Prangnawarate8cddeb2020-04-01 16:51:23 +01001620 dataLayout,
1621 1.0f,
1622 0,
1623 padLeft,
1624 padTop,
1625 padRight,
1626 padBottom,
1627 strideX,
1628 strideY);
1629}
1630
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001631//
1632// DepthwiseConvolution2d implementations
1633//
1634
1635template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
1636 typename T = armnn::ResolveType<ArmnnType>, typename B = armnn::ResolveType<ArmnnBType>>
1637LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestImpl(
1638 armnn::IWorkloadFactory& workloadFactory,
1639 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001640 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +01001641 const std::vector<T>& input,
1642 const std::vector<T>& kernel,
1643 const std::vector<B>& bias,
1644 const std::vector<T>& outputExpected,
1645 const armnn::TensorShape& inputShape,
1646 const armnn::TensorShape& kernelShape,
1647 const armnn::TensorShape& outputExpectedShape,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001648 float qScale,
1649 int32_t qOffset,
1650 const armnn::DataLayout layout,
1651 uint32_t padLeft = 0,
1652 uint32_t padTop = 0,
1653 uint32_t padRight = 0,
1654 uint32_t padBottom = 0,
1655 uint32_t strideX = 1,
1656 uint32_t strideY = 1)
1657{
Sadik Armagan483c8112021-06-01 09:24:52 +01001658 unsigned int inputNum = armnn::numeric_cast<unsigned int>(inputShape[0]);
1659 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(inputShape[1]);
1660 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(inputShape[2]);
1661 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(inputShape[3]);
Jan Eilers53ef7952021-06-02 12:01:25 +01001662 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(kernelShape[1]);
1663 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(kernelShape[2]);
1664 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(kernelShape[3]);
Sadik Armagan483c8112021-06-01 09:24:52 +01001665 unsigned int outputNum = armnn::numeric_cast<unsigned int>(outputExpectedShape[0]);
1666 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(outputExpectedShape[1]);
1667 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
1668 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(outputExpectedShape[3]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001669
1670 // If a bias is used, its size must equal the number of output channels.
1671 bool biasEnabled = bias.size() > 0;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01001672 ARMNN_ASSERT(!biasEnabled || bias.size() == outputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001673
1674 // Creates the tensors.
1675 armnn::TensorInfo inputTensorInfo =
1676 armnnUtils::GetTensorInfo(inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1677 armnn::TensorInfo outputTensorInfo =
1678 armnnUtils::GetTensorInfo(outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
Jan Eilers53ef7952021-06-02 12:01:25 +01001679 armnn::TensorInfo kernelDesc({1, kernelHeight, kernelWidth, kernelChannels}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001680 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
1681
1682 // Set quantization parameters if the requested type is a quantized type.
1683 if (armnn::IsQuantizedType<T>())
1684 {
1685 inputTensorInfo.SetQuantizationScale(qScale);
1686 inputTensorInfo.SetQuantizationOffset(qOffset);
1687 outputTensorInfo.SetQuantizationScale(qScale);
1688 outputTensorInfo.SetQuantizationOffset(qOffset);
1689 kernelDesc.SetQuantizationScale(qScale);
1690 kernelDesc.SetQuantizationOffset(qOffset);
1691 biasDesc.SetQuantizationScale(qScale*qScale);
1692 biasDesc.SetQuantizationOffset(0);
1693 }
1694
1695 // Construct the input data.
1696 std::vector<T> inputData;
1697 inputData.assign(input.data(), input.data() + inputChannels*inputHeight*inputWidth);
1698
1699 // At this point if we require it permute the input data
1700 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
1701 if (layout == armnn::DataLayout::NHWC)
1702 {
1703 std::vector<T> tmp(inputData.size());
1704 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
1705 inputData = tmp;
1706 }
1707
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001708 // Construct the output data, with bias applied, as appropriate.
1709 std::vector<T> outputData;
1710 outputData.assign(outputExpected.data(), outputExpected.data() + outputChannels*outputHeight*outputWidth);
1711 if (biasEnabled)
1712 {
1713 std::vector<T> biasV;
1714 biasV.assign(bias.data(), bias.data() + outputChannels);
1715 ApplyBias(outputData, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
1716 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
1717 outputWidth, outputHeight);
1718 }
1719
Sadik Armagan483c8112021-06-01 09:24:52 +01001720 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001721
1722 // At this point if we require it permute the expected output
1723 if (layout == armnn::DataLayout::NHWC)
1724 {
1725 std::vector<T> tmp(outputData.size());
1726 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp.data(), sizeof(T));
1727 outputData = tmp;
1728 }
1729
Keith Davisf500d6c2020-08-31 08:32:55 +01001730 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1731 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1732
James Conroy1f58f032021-04-27 17:13:27 +01001733 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001734
Sadik Armagan483c8112021-06-01 09:24:52 +01001735 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001736
James Conroy1f58f032021-04-27 17:13:27 +01001737 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001738 if (biasEnabled)
1739 {
Sadik Armagan483c8112021-06-01 09:24:52 +01001740 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001741 }
1742
1743 armnn::DepthwiseConvolution2dQueueDescriptor data;
1744 data.m_Weight = &weightsTensor;
1745 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - it can be a source of bugs.
1746 data.m_Parameters.m_StrideX = strideX;
1747 data.m_Parameters.m_StrideY = strideY;
1748 data.m_Parameters.m_PadLeft = padLeft;
1749 data.m_Parameters.m_PadRight = padRight;
1750 data.m_Parameters.m_PadTop = padTop;
1751 data.m_Parameters.m_PadBottom = padBottom;
1752 data.m_Parameters.m_BiasEnabled = biasEnabled;
1753 data.m_Parameters.m_DataLayout = layout;
1754
1755 armnn::WorkloadInfo info;
1756 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1757 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1758
1759 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
1760 inputHandle->Allocate();
1761 outputHandle->Allocate();
1762
Sadik Armagan483c8112021-06-01 09:24:52 +01001763 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001764
1765 ExecuteWorkload(*workload, memoryManager);
1766
Sadik Armagan483c8112021-06-01 09:24:52 +01001767 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001768
Sadik Armagan483c8112021-06-01 09:24:52 +01001769 return LayerTestResult<T, 4>(actualOutput,
1770 outputData,
1771 outputHandle->GetShape(),
1772 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001773}
1774
1775template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
1776LayerTestResult<T, 4> DepthwiseConvolution2dDepthMul1TestImpl(
1777 armnn::IWorkloadFactory& workloadFactory,
1778 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001779 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001780 float qScale,
1781 int32_t qOffset,
1782 bool biasEnabled,
1783 const armnn::DataLayout layout)
1784{
1785 using B = armnn::ResolveType<ArmnnBType>;
1786
1787 unsigned int inputHeight = 3;
1788 unsigned int inputWidth = 3;
1789 unsigned int inputChannels = 2;
1790 unsigned int inputNum = 1;
1791
1792 unsigned int kernelHeight = 3;
1793 unsigned int kernelWidth = 3;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001794
1795 unsigned int outputHeight = 1;
1796 unsigned int outputWidth = 1;
Jan Eilers53ef7952021-06-02 12:01:25 +01001797 unsigned int outputChannels = inputChannels;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001798 unsigned int outputNum = inputNum;
1799
1800 armnn::TensorInfo inputTensorInfo =
1801 armnnUtils::GetTensorInfo(inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1802 armnn::TensorInfo outputTensorInfo =
1803 armnnUtils::GetTensorInfo(outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
Jan Eilers53ef7952021-06-02 12:01:25 +01001804 armnn::TensorInfo kernelDesc({1, kernelHeight, kernelWidth, outputChannels},
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001805 ArmnnType);
1806 armnn::TensorInfo biasDesc({ outputChannels }, ArmnnBType);
1807
1808 // Set quantization parameters if the requested type is a quantized type.
1809 if(armnn::IsQuantizedType<T>())
1810 {
1811 inputTensorInfo.SetQuantizationScale(qScale);
1812 inputTensorInfo.SetQuantizationOffset(qOffset);
1813 outputTensorInfo.SetQuantizationScale(qScale);
1814 outputTensorInfo.SetQuantizationOffset(qOffset);
1815 kernelDesc.SetQuantizationScale(qScale);
1816 kernelDesc.SetQuantizationOffset(qOffset);
1817 biasDesc.SetQuantizationScale(qScale*qScale);
1818 biasDesc.SetQuantizationOffset(0);
1819 }
1820 std::vector<T> inputData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001821 QuantizedVector<T>({
1822 1.f, 2.f, 1.f,
1823 2.f, 1.f, 2.f,
1824 1.f, 2.f, 1.f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001825
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001826 1.f, 2.f, 1.f,
1827 2.f, 1.f, 2.f,
1828 1.f, 2.f, 1.f,
1829 },
1830 inputTensorInfo.GetQuantizationScale(),
1831 inputTensorInfo.GetQuantizationOffset()));
1832
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001833 // at this point if we require it permute the input data
1834 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
1835 if (layout == armnn::DataLayout::NHWC)
1836 {
1837 std::vector<T> tmp(inputData.size());
1838 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
1839 inputData = tmp;
1840 }
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001841
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001842 std::vector<B> biasV(QuantizedVector<B>({ 0, 2 },
1843 biasDesc.GetQuantizationScale(),
1844 biasDesc.GetQuantizationOffset()));
1845
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001846 std::vector<T> kernelData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001847 QuantizedVector<T>({
1848 1.f, 0.f, 1.f,
1849 0.f, 0.f, 0.f,
1850 -1.f, 0.f, -1.f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001851
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001852 1.f, 0.f, 1.f,
1853 0.f, 0.f, 0.f,
1854 -1.f, 0.f, -1.f,
1855 },
1856 kernelDesc.GetQuantizationScale(),
1857 kernelDesc.GetQuantizationOffset()));
1858
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001859 // Manually calculated.
1860 std::vector<T> outputImage(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001861 QuantizedVector<T>({ 0.f, 0.f },
1862 outputTensorInfo.GetQuantizationScale(),
1863 outputTensorInfo.GetQuantizationOffset())
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001864 );
1865
1866 // Optionally apply bias to output image.
1867 if(biasEnabled)
1868 {
1869 ApplyBias(outputImage, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
1870 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
1871 outputWidth, outputHeight);
1872 }
1873
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001874 if (layout == armnn::DataLayout::NHWC)
1875 {
1876 std::vector<T> tmp(outputImage.size());
1877 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputImage.data(), tmp.data(), sizeof(T));
1878 outputImage = tmp;
1879 }
1880
Sadik Armagan483c8112021-06-01 09:24:52 +01001881 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001882
1883 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1884 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1885
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001886 armnn::DepthwiseConvolution2dQueueDescriptor data;
1887 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01001888 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
1889 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001890
Sadik Armagan483c8112021-06-01 09:24:52 +01001891 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
1892 AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001893
1894 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1895 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1896
1897 data.m_Weight = &weightsTensor;
1898 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
1899 data.m_Parameters.m_StrideX = 1;
1900 data.m_Parameters.m_StrideY = 1;
1901 data.m_Parameters.m_PadLeft = 0;
1902 data.m_Parameters.m_PadRight = 0;
1903 data.m_Parameters.m_PadTop = 0;
1904 data.m_Parameters.m_PadBottom = 0;
1905 data.m_Parameters.m_BiasEnabled = biasEnabled;
1906 data.m_Parameters.m_DataLayout = layout;
1907
1908 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
1909 inputHandle->Allocate();
1910 outputHandle->Allocate();
1911
Sadik Armagan483c8112021-06-01 09:24:52 +01001912 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001913
1914 ExecuteWorkload(*workload, memoryManager);
1915
Sadik Armagan483c8112021-06-01 09:24:52 +01001916 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001917
Sadik Armagan483c8112021-06-01 09:24:52 +01001918 return LayerTestResult<T, 4>(actualOutput,
1919 outputImage,
1920 outputHandle->GetShape(),
1921 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001922}
1923
1924template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
1925LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
1926 armnn::IWorkloadFactory& workloadFactory,
1927 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001928 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001929 float qScale,
1930 int32_t qOffset,
1931 bool biasEnabled,
1932 const armnn::DataLayout layout)
1933{
1934 using B = armnn::ResolveType<ArmnnBType>;
1935
1936 unsigned int depthMultiplier = 2;
1937
1938 unsigned int inputHeight = 8;
1939 unsigned int inputWidth = 16;
1940 unsigned int inputChannels = 2;
1941 unsigned int inputBatchSize = 1;
1942
1943 unsigned int kernelHeight = 5;
1944 unsigned int kernelWidth = 3;
1945
1946 unsigned int outputHeight = inputHeight - kernelHeight + 1 + 2;
1947 unsigned int outputWidth = (inputWidth - kernelWidth + 1)/2;
1948 unsigned int outputChannels = inputChannels * depthMultiplier;
1949 unsigned int outputBatchSize = inputBatchSize;
1950
1951 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(
1952 inputBatchSize, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1953 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(
1954 outputBatchSize, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
Jan Eilers53ef7952021-06-02 12:01:25 +01001955 armnn::TensorInfo kernelDesc({1, kernelHeight, kernelWidth, outputChannels},
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001956 ArmnnType);
1957 armnn::TensorInfo biasDesc({outputChannels}, ArmnnBType);
1958
1959 // Set quantization parameters if the requested type is a quantized type.
1960 if(armnn::IsQuantizedType<T>())
1961 {
1962 inputTensorInfo.SetQuantizationScale(qScale);
1963 inputTensorInfo.SetQuantizationOffset(qOffset);
1964 outputTensorInfo.SetQuantizationScale(qScale);
1965 outputTensorInfo.SetQuantizationOffset(qOffset);
1966 kernelDesc.SetQuantizationScale(qScale);
1967 kernelDesc.SetQuantizationOffset(qOffset);
1968 biasDesc.SetQuantizationScale(qScale*qScale);
1969 biasDesc.SetQuantizationOffset(0);
1970 }
1971
1972 // NOTE: originalInputData is in NCHW format
1973 std::vector<T> originalInputData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001974 QuantizedVector<T>({
1975 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1976 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1977 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1978 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1979 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1980 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1981 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1982 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1983 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1984 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1985 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1986 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1987 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1988 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1989 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1990 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
1991 },
1992 inputTensorInfo.GetQuantizationScale(),
1993 inputTensorInfo.GetQuantizationOffset()));
1994
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001995 std::vector<T> inputData = originalInputData;
1996 // at this point if we require it permute the input data
1997 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
1998 if (layout == armnn::DataLayout::NHWC)
1999 {
2000 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC,
2001 originalInputData.data(), inputData.data(), sizeof(T));
2002 }
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002003
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002004 std::vector<B> biasV = QuantizedVector<B>({ 0, 2, 1, -1 },
2005 biasDesc.GetQuantizationScale(),
2006 biasDesc.GetQuantizationOffset());
2007
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002008 std::vector<T> kernelData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002009 QuantizedVector<T>({
2010 1, 1, 1,
2011 1, -1, 1,
2012 1, 1, 1,
2013 1, 1, 1,
2014 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002015
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002016 2, 2, 2,
2017 2, 2, 2,
2018 2, 2, 2,
2019 2, 2, 2,
2020 2, 2, 2,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002021
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002022 0, 0, 0,
2023 0, -1, 0,
2024 0, 0, 0,
2025 0, 0, 0,
2026 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002027
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002028 0, 0, 0,
2029 0, 0, 0,
2030 0, 1, 0,
2031 0, 0, 0,
2032 0, 0, 0
2033 },
2034 kernelDesc.GetQuantizationScale(),
2035 kernelDesc.GetQuantizationOffset()));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002036
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002037 // Manually calculated.
2038 std::vector<T> originalOutputImage = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002039 QuantizedVector<T>({
Jan Eilers53ef7952021-06-02 12:01:25 +01002040 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2041 5, 5, 5, 5, 5, 5, 5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5,
2042 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5, 5, 5, 5, 5, 5, 5,
2043 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
2044 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 6, 6, 6, 6, 6, 6, 6,
2045 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2046 1, 3, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0,
2047 2, 4, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0,
2048 2, 4, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0,
2049 2, 4, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0,
2050 3, 5, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0,
2051 3, 5, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002052 },
2053 outputTensorInfo.GetQuantizationScale(),
2054 outputTensorInfo.GetQuantizationOffset()));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002055
2056 // Optionally apply bias to output image.
2057 if(biasEnabled)
2058 {
2059 ApplyBias(originalOutputImage,
2060 outputTensorInfo.GetQuantizationScale(),
2061 outputTensorInfo.GetQuantizationOffset(),
2062 biasV,
2063 biasDesc.GetQuantizationScale(),
2064 biasDesc.GetQuantizationOffset(),
2065 outputWidth,
2066 outputHeight);
2067 }
2068
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002069 std::vector<T> outputImage = originalOutputImage;
2070 if (layout == armnn::DataLayout::NHWC)
2071 {
2072 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC,
2073 originalOutputImage.data(), outputImage.data(), sizeof(T));
2074 }
2075
Sadik Armagan483c8112021-06-01 09:24:52 +01002076 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01002077
2078 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2079 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2080
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002081 armnn::DepthwiseConvolution2dQueueDescriptor data;
2082 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01002083 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
2084 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002085
Sadik Armagan483c8112021-06-01 09:24:52 +01002086 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
2087 AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002088
2089 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2090 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2091
2092 data.m_Weight = &weightsTensor;
2093 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
2094 data.m_Parameters.m_StrideX = 2;
2095 data.m_Parameters.m_StrideY = 1;
2096 data.m_Parameters.m_PadLeft = 0;
2097 data.m_Parameters.m_PadRight = 0;
2098 data.m_Parameters.m_PadTop = 1;
2099 data.m_Parameters.m_PadBottom = 1;
2100 data.m_Parameters.m_BiasEnabled = biasEnabled;
2101 data.m_Parameters.m_DataLayout = layout;
2102
2103 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
2104 inputHandle->Allocate();
2105 outputHandle->Allocate();
2106
Sadik Armagan483c8112021-06-01 09:24:52 +01002107 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002108
2109 ExecuteWorkload(*workload, memoryManager);
2110
Sadik Armagan483c8112021-06-01 09:24:52 +01002111 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002112
Sadik Armagan483c8112021-06-01 09:24:52 +01002113 return LayerTestResult<T, 4>(actualOutput,
2114 outputImage,
2115 outputHandle->GetShape(),
2116 outputTensorInfo.GetShape());
2117
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002118}
2119
2120template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2121 typename T = armnn::ResolveType<ArmnnType>, typename B = armnn::ResolveType<ArmnnBType>>
2122LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
2123 armnn::IWorkloadFactory& workloadFactory,
2124 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002125 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +01002126 const std::vector<T>& originalInput,
2127 const std::vector<T>& originalKernel,
2128 const std::vector<B>& bias,
2129 const std::vector<T>& originalOutputExpected,
2130 const armnn::TensorShape& originalInputShape,
2131 const armnn::TensorShape& originalKernelShape,
2132 const armnn::TensorShape& originalOutputExpectedShape,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002133 float qScale,
2134 int32_t qOffset,
2135 const armnn::DataLayout layout = armnn::DataLayout::NCHW,
2136 uint32_t padLeft = 0,
2137 uint32_t padTop = 0,
2138 uint32_t padRight = 0,
2139 uint32_t padBottom = 0,
2140 uint32_t strideX = 1,
2141 uint32_t strideY = 1,
2142 uint32_t dilationX = 1,
2143 uint32_t dilationY = 1)
2144{
Sadik Armagan483c8112021-06-01 09:24:52 +01002145 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(originalInputShape[2]);
2146 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(originalInputShape[3]);
2147 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(originalInputShape[1]);
2148 unsigned int inputNum = armnn::numeric_cast<unsigned int>(originalInputShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002149
Sadik Armagan483c8112021-06-01 09:24:52 +01002150 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[2]);
2151 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[3]);
2152 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[1]);
2153 unsigned int outputNum = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002154
Jan Eilers53ef7952021-06-02 12:01:25 +01002155 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(originalKernelShape[1]);
2156 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(originalKernelShape[2]);
2157 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(originalKernelShape[3]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002158
2159 bool biasEnabled = bias.size() > 0;
2160
2161 // This function currently assumes 1 batch of input/output (and duplicates this into 2 batches).
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01002162 ARMNN_ASSERT(inputNum == 1);
2163 ARMNN_ASSERT(outputNum == 1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002164
2165 // If a bias is used, its size must equal the number of output channels.
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01002166 ARMNN_ASSERT(!biasEnabled || bias.size() == outputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002167
2168
2169 // Note these tensors will use two (identical) batches.
2170 armnn::TensorInfo inputTensorInfo =
2171 armnnUtils::GetTensorInfo(2*inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
2172 armnn::TensorInfo outputTensorInfo =
2173 armnnUtils::GetTensorInfo(2*outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
2174
2175 // Kernel must be NCHW layout always, independently of the layout of the input and output for depthwise convolution.
Jan Eilers53ef7952021-06-02 12:01:25 +01002176 armnn::TensorInfo kernelDesc({1, kernelHeight, kernelWidth, kernelChannels}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002177
2178 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
2179
2180 // Set quantization parameters if the requested type is a quantized type.
2181 if(armnn::IsQuantizedType<T>())
2182 {
2183 inputTensorInfo.SetQuantizationScale(qScale);
2184 inputTensorInfo.SetQuantizationOffset(qOffset);
2185 outputTensorInfo.SetQuantizationScale(qScale);
2186 outputTensorInfo.SetQuantizationOffset(qOffset);
2187 kernelDesc.SetQuantizationScale(qScale);
2188 kernelDesc.SetQuantizationOffset(qOffset);
2189 biasDesc.SetQuantizationScale(qScale*qScale);
2190 biasDesc.SetQuantizationOffset(0);
2191 }
2192
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002193 // Construct input data
2194 std::vector<T> input;
2195 input.assign(originalInput.data(), originalInput.data() + 1*inputChannels*inputHeight*inputWidth);
2196 std::vector<T> inputData;
2197 inputData.insert(inputData.end(), input.begin(), input.end());
2198 inputData.insert(inputData.end(), input.begin(), input.end());
2199
2200 // at this point if we require it permute the input data
2201 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
2202 if (layout == armnn::DataLayout::NHWC)
2203 {
2204 std::vector<T> tmp(inputData.size());
2205 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
2206 inputData = tmp;
2207 }
2208
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002209 std::vector<T> output;
2210 output.assign(originalOutputExpected.data(),
2211 originalOutputExpected.data() + outputChannels*outputHeight*outputWidth);
2212
2213 // Apply bias to output data if it is enabled.
2214 if(biasEnabled)
2215 {
2216 std::vector<T> biasV;
2217 biasV.assign(bias.data(), bias.data() + outputChannels);
2218 ApplyBias(output, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
2219 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
2220 outputWidth, outputHeight);
2221 }
2222
Sadik Armagan483c8112021-06-01 09:24:52 +01002223 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
2224
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002225 // Construct expected output data
2226 std::vector<T> outputData;
2227 outputData.insert(outputData.end(), output.begin(), output.end());
2228 outputData.insert(outputData.end(), output.begin(), output.end());
2229
2230 // at this point if we require it permute the expected output
2231 if (layout == armnn::DataLayout::NHWC)
2232 {
2233 std::vector<T> tmp(outputData.size());
2234 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp.data(), sizeof(T));
2235 outputData = tmp;
2236 }
Keith Davisf500d6c2020-08-31 08:32:55 +01002237
2238 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2239 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2240
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002241 armnn::DepthwiseConvolution2dQueueDescriptor data;
2242 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01002243 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
2244 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002245
Sadik Armagan483c8112021-06-01 09:24:52 +01002246 AllocateAndCopyDataToITensorHandle(&weightsTensor, originalKernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002247
2248 if(biasEnabled)
2249 {
Sadik Armagan483c8112021-06-01 09:24:52 +01002250 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002251 }
2252
2253 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2254 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2255
2256 data.m_Weight = &weightsTensor;
2257 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - can be a source of bugs.
2258 data.m_Parameters.m_StrideX = strideX;
2259 data.m_Parameters.m_StrideY = strideY;
2260 data.m_Parameters.m_PadLeft = padLeft;
2261 data.m_Parameters.m_PadRight = padRight;
2262 data.m_Parameters.m_PadTop = padTop;
2263 data.m_Parameters.m_PadBottom = padBottom;
2264 data.m_Parameters.m_BiasEnabled = biasEnabled;
2265 data.m_Parameters.m_DataLayout = layout;
2266 data.m_Parameters.m_DilationX = dilationX;
2267 data.m_Parameters.m_DilationY = dilationY;
2268
2269 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
2270 inputHandle->Allocate();
2271 outputHandle->Allocate();
2272
Sadik Armagan483c8112021-06-01 09:24:52 +01002273 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002274
2275 ExecuteWorkload(*workload, memoryManager);
2276
Sadik Armagan483c8112021-06-01 09:24:52 +01002277 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002278
Sadik Armagan483c8112021-06-01 09:24:52 +01002279 return LayerTestResult<T, 4>(actualOutput,
2280 outputData,
2281 outputHandle->GetShape(),
2282 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002283}
2284
2285template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2286 typename T = armnn::ResolveType<ArmnnType>>
2287LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestCommon(
2288 armnn::IWorkloadFactory& workloadFactory,
2289 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002290 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002291 float qScale,
2292 int32_t qOffset,
2293 bool biasEnabled,
2294 const armnn::DataLayout layout)
2295{
2296 // Use a single-batch 2-channel 5x5 image as input.
2297 armnn::TensorInfo inputTensorInfo({ 1, 2, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002298 auto input = QuantizedVector<T>(
2299 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002300 0, 1, 2, 3, 4,
2301 5, 6, 7, 8, 9,
2302 10, 11, 12, 13, 14,
2303 15, 16, 17, 18, 19,
2304 20, 21, 22, 23, 24,
2305
2306 25, 26, 27, 28, 29,
2307 30, 31, 32, 33, 34,
2308 35, 36, 37, 38, 39,
2309 40, 41, 42, 43, 44,
2310 45, 46, 47, 48, 49
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002311 },
2312 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002313 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002314
2315 // Use a depth multiplier of 1 on a 2-channel 4x4 kernel.
Jan Eilers53ef7952021-06-02 12:01:25 +01002316 // Weights layout for depthwise: [1,H,W,I*M]
2317 armnn::TensorInfo kernelTensorInfo({ 1, 4, 4, 2 }, ArmnnType);
2318 auto kernel = QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002319 32, 31, 30, 29,
2320 28, 27, 26, 25,
2321 24, 23, 22, 21,
2322 20, 19, 18, 17,
2323
2324 16, 15, 14, 13,
2325 12, 11, 10, 9,
2326 8, 7, 6, 5,
2327 4, 3, 2, 1
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002328 },
2329 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002330 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002331
2332 // Expected output is 1 batch of a 2-channel 5x5 image.
2333 // Calculated using the python tensorflow library with strideX=1, strideY=1.
2334 armnn::TensorInfo outputTensorInfo({ 1, 2, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002335 auto expectedOutput = QuantizedVector<T>(
2336 {
Jan Eilers53ef7952021-06-02 12:01:25 +01002337 396, 664, 820, 756, 602, 1016, 1608, 1880, 1652, 1268, 1976, 2968, 3240, 2732,
2338 2028, 2628, 3808, 4060, 3312, 2390, 2596, 3700, 3900, 3130, 2226, 2817, 4186,
2339 4330, 3609, 2651, 5414, 7864, 8120, 6626, 4780, 6314, 9144, 9400, 7646, 5500,
2340 6759, 9610, 9850, 7875, 5579, 5935, 8348, 8540, 6757, 4742
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002341 },
2342 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002343 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002344
2345 return DepthwiseConvolution2dAsymmetricTestImpl<ArmnnType, ArmnnBType>(
2346 workloadFactory,
2347 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002348 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002349 input,
2350 kernel,
2351 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2352 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002353 inputTensorInfo.GetShape(),
2354 kernelTensorInfo.GetShape(),
2355 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002356 qScale,
2357 qOffset,
2358 layout,
2359 1, // Padding left.
2360 1, // Padding top.
2361 2, // Padding right.
2362 2, // Padding bottom.
2363 1, // strideX
2364 1); // strideY
2365}
2366
2367template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2368 typename T = armnn::ResolveType<ArmnnType>>
2369LayerTestResult<T, 4> DepthwiseConvolution2dNhwcTestCommon(
2370 armnn::IWorkloadFactory& workloadFactory,
2371 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002372 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002373 float qScale,
2374 int32_t qOffset,
2375 bool biasEnabled)
2376{
2377 auto layout = armnn::DataLayout::NHWC;
2378
2379 armnn::TensorInfo inputTensorInfo({ 1, 2, 5, 5}, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002380 auto input = QuantizedVector<T>(
2381 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002382 0, 1, 2, 3, 4,
2383 5, 6, 7, 8, 9,
2384 10, 11, 12, 13, 14,
2385 15, 16, 17, 18, 19,
2386 20, 21, 22, 23, 24,
2387
2388 25, 26, 27, 28, 29,
2389 30, 31, 32, 33, 34,
2390 35, 36, 37, 38, 39,
2391 40, 41, 42, 43, 44,
2392 45, 46, 47, 48, 49
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002393 },
2394 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002395 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002396
Jan Eilers53ef7952021-06-02 12:01:25 +01002397 armnn::TensorInfo kernelTensorInfo({ 1, 4, 4, 2 }, ArmnnType);
2398 auto kernel = QuantizedVector<T>({
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002399 32, 31, 30, 29,
2400 28, 27, 26, 25,
2401 24, 23, 22, 21,
2402 20, 19, 18, 17,
2403
2404 16, 15, 14, 13,
2405 12, 11, 10, 9,
2406 8, 7, 6, 5,
2407 4, 3, 2, 1
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002408 },
2409 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002410 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002411
2412 armnn::TensorInfo outputTensorInfo({ 1, 2, 5, 5}, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002413 auto expectedOutput = QuantizedVector<T>(
2414 {
Jan Eilers53ef7952021-06-02 12:01:25 +01002415 396,664,820,756,602,
2416 1016,1608,1880,1652,1268,
2417 1976,2968,3240,2732,2028,
2418 2628,3808,4060,3312,2390,
2419 2596,3700,3900,3130,2226,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002420
Jan Eilers53ef7952021-06-02 12:01:25 +01002421 2817,4186,4330,3609,2651,
2422 5414,7864,8120,6626,4780,
2423 6314,9144,9400,7646,5500,
2424 6759,9610,9850,7875,5579,
2425 5935,8348,8540,6757,4742
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002426 },
2427 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002428 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002429
2430 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2431 workloadFactory,
2432 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002433 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002434 input,
2435 kernel,
2436 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2437 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002438 inputTensorInfo.GetShape(),
2439 kernelTensorInfo.GetShape(),
2440 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002441 qScale,
2442 qOffset,
2443 layout,
2444 1, // Padding left.
2445 1, // Padding top.
2446 2, // Padding right.
2447 2, // Padding bottom.
2448 1, // strideX
2449 1); // strideY
2450}
2451
2452template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2453 typename T = armnn::ResolveType<ArmnnType>>
2454LayerTestResult<T, 4> SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTestCommon(
2455 armnn::IWorkloadFactory& workloadFactory,
2456 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002457 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002458 float qScale,
2459 int32_t qOffset,
2460 bool biasEnabled)
2461{
2462 auto layout = armnn::DataLayout::NHWC;
2463
Sadik Armagan483c8112021-06-01 09:24:52 +01002464 armnn::TensorInfo inputTensorInfo({ 1, 1, 9, 9 }, ArmnnType);
2465 auto input = QuantizedVector<T>(
2466 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002467 0, 0, 0, 0, 0, 0, 0, 0, 0,
2468 0, 0, 0, 0, 0, 0, 0, 0, 0,
2469 0, 0, 0, 0, 0, 0, 0, 0, 0,
2470 0, 0, 0, 1, 1, 1, 0, 0, 0,
2471 0, 0, 0, 1, 1, 1, 0, 0, 0,
2472 0, 0, 0, 1, 1, 1, 0, 0, 0,
2473 0, 0, 0, 0, 0, 0, 0, 0, 0,
2474 0, 0, 0, 0, 0, 0, 0, 0, 0,
2475 0, 0, 0, 0, 0, 0, 0, 0, 0
2476 },
2477 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002478 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002479
Jan Eilers53ef7952021-06-02 12:01:25 +01002480 armnn::TensorInfo kernelTensorInfo({ 1, 3, 3, 1}, ArmnnType);
2481 auto kernel = QuantizedVector<T>({
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002482 1, 2, 3,
2483 4, 5, 6,
2484 7, 8, 9
2485 },
2486 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002487 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002488
2489 uint32_t padLeft = 0;
2490 uint32_t padTop = 0;
2491 uint32_t padRight = 0;
2492 uint32_t padBottom = 0;
2493 uint32_t strideX = 1;
2494 uint32_t strideY = 1;
2495 uint32_t dilationX = 3;
2496 uint32_t dilationY = 3;
2497
2498 // Since the dilation rate is 3 this will reduce the size of the output from 9x9 to 3x3 of all 5s.
Sadik Armagan483c8112021-06-01 09:24:52 +01002499 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
2500 auto expectedOutput = QuantizedVector<T>(
2501 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002502 5, 5, 5,
2503 5, 5, 5,
2504 5, 5, 5
2505 },
2506 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002507 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002508
2509 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2510 workloadFactory,
2511 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002512 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002513 input,
2514 kernel,
2515 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2516 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002517 inputTensorInfo.GetShape(),
2518 kernelTensorInfo.GetShape(),
2519 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002520 qScale,
2521 qOffset,
2522 layout,
2523 padLeft,
2524 padTop,
2525 padRight,
2526 padBottom,
2527 strideX,
2528 strideY,
2529 dilationX,
2530 dilationY);
2531}
2532
2533template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
2534LayerTestResult<T, 4> DepthwiseConvolution2d3x3DilationTestCommon(
2535 armnn::IWorkloadFactory& workloadFactory,
2536 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002537 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002538 const std::vector<float>& inputNoQuantizedValues,
2539 armnn::TensorInfo& inputTensorInfo,
2540 const std::vector<float>& kernelNoQuantizedValues,
2541 armnn::TensorInfo& kernelTensorInfo,
2542 const std::vector<float>& outputExpectedNoQuantizedValues,
2543 armnn::TensorInfo& outputTensorInfo,
2544 uint32_t dilationX,
2545 uint32_t dilationY,
2546 armnn::DataLayout layout = armnn::DataLayout::NCHW,
2547 bool biasEnabled = false)
2548{
2549 float qScale;
2550 int32_t qOffset;
2551 switch (ArmnnType)
2552 {
Sadik Armagan303980c2020-04-17 12:45:14 +01002553 case armnn::DataType::QAsymmS8:
Derek Lambertif90c56d2020-01-10 17:14:08 +00002554 case armnn::DataType::QAsymmU8:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002555 {
2556 qScale = 0.1f;
2557 qOffset = 128;
2558 break;
2559 }
Derek Lambertif90c56d2020-01-10 17:14:08 +00002560 case armnn::DataType::QSymmS16:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002561 {
2562 qScale = 0.1f;
2563 qOffset = 0;
2564 break;
2565 }
2566 case armnn::DataType::Float32:
2567 default:
2568 {
2569 qScale = 0.f;
2570 qOffset = 0;
2571 break;
2572 }
2573 }
2574
2575 inputTensorInfo.SetQuantizationScale(qScale);
2576 inputTensorInfo.SetQuantizationOffset(qOffset);
2577 kernelTensorInfo.SetQuantizationScale(qScale);
2578 kernelTensorInfo.SetQuantizationOffset(qOffset);
2579 outputTensorInfo.SetQuantizationScale(qScale);
2580 outputTensorInfo.SetQuantizationOffset(qOffset);
2581
Sadik Armagan483c8112021-06-01 09:24:52 +01002582 auto input = QuantizedVector<T>(inputNoQuantizedValues,
2583 inputTensorInfo.GetQuantizationScale(),
2584 inputTensorInfo.GetQuantizationOffset());
2585 auto kernel = QuantizedVector<T>(kernelNoQuantizedValues,
2586 kernelTensorInfo.GetQuantizationScale(),
2587 kernelTensorInfo.GetQuantizationOffset());
2588 auto expectedOutput = QuantizedVector<T>(outputExpectedNoQuantizedValues,
2589 outputTensorInfo.GetQuantizationScale(),
2590 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002591
2592 uint32_t padLeft = 0;
2593 uint32_t padTop = 0;
2594 uint32_t padRight = 0;
2595 uint32_t padBottom = 0;
2596 uint32_t strideX = 1;
2597 uint32_t strideY = 1;
2598
2599 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2600 workloadFactory,
2601 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002602 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002603 input,
2604 kernel,
2605 GetBias<ArmnnBType>(biasEnabled, qScale * qScale, outputTensorInfo, layout),
2606 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002607 inputTensorInfo.GetShape(),
2608 kernelTensorInfo.GetShape(),
2609 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002610 qScale,
2611 qOffset,
2612 layout,
2613 padLeft,
2614 padTop,
2615 padRight,
2616 padBottom,
2617 strideX,
2618 strideY,
2619 dilationX,
2620 dilationY);
2621}
2622
2623template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2624LayerTestResult<T, 4> DepthwiseConvolution2d3x3Dilation3x3Test(
2625 armnn::IWorkloadFactory& workloadFactory,
2626 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002627 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002628 bool biasEnabled,
2629 const armnn::DataLayout layout)
2630{
2631 armnn::TensorInfo inputTensorInfo({1, 1, 10, 10}, ArmnnType);
2632 std::vector<float> inputNoQuantizedValues =
2633 {
2634 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2637 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2638 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2639 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2644 };
2645
Jan Eilers53ef7952021-06-02 12:01:25 +01002646 armnn::TensorInfo kernelTensorInfo({ 1, 3, 3, 1}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002647 std::vector<float> kernelNoQuantizedValues =
2648 {
2649 1, 2, 3,
2650 4, 5, 6,
2651 7, 8, 9
2652 };
2653
2654 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
2655 // therefore the output will be 4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
2656 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4}, ArmnnType);
2657 std::vector<float> outputExpectedNoQuantizedValues =
2658 {
2659 6., 5., 5., 5.,
2660 6., 5., 5., 5.,
2661 6., 5., 5., 5.,
2662 3., 2., 2., 2.
2663 };
2664
2665 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2666 workloadFactory,
2667 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002668 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002669 inputNoQuantizedValues,
2670 inputTensorInfo,
2671 kernelNoQuantizedValues,
2672 kernelTensorInfo,
2673 outputExpectedNoQuantizedValues,
2674 outputTensorInfo,
2675 3,
2676 3,
2677 layout,
2678 biasEnabled);
2679}
2680
2681template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2682LayerTestResult<T, 4> DepthwiseConvolution2d2x3x3Dilation3x3Test(
2683 armnn::IWorkloadFactory& workloadFactory,
2684 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002685 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002686 bool biasEnabled,
2687 const armnn::DataLayout layout)
2688{
2689 armnn::TensorInfo inputTensorInfo({1, 2, 10, 10}, ArmnnType);
2690 std::vector<float> inputNoQuantizedValues =
2691 {
2692 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2695 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2696 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2697 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2698 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2700 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2701 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2702
2703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2704 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2705 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2706 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2707 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2708 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2709 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2711 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2712 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2713 };
2714
Jan Eilers53ef7952021-06-02 12:01:25 +01002715 armnn::TensorInfo kernelTensorInfo({ 1, 3, 3, 2}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002716 std::vector<float> kernelNoQuantizedValues =
2717 {
2718 1, 2, 3,
2719 4, 5, 6,
2720 7, 8, 9,
2721
2722 1, 2, 3,
2723 4, 5, 6,
2724 7, 8, 9
2725 };
2726
2727 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
2728 // therefore the output will be 2x4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
2729 armnn::TensorInfo outputTensorInfo({ 1, 2, 4, 4}, ArmnnType);
2730 std::vector<float> outputExpectedNoQuantizedValues =
2731 {
Jan Eilers53ef7952021-06-02 12:01:25 +01002732 2, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 5, 3, 3, 3, 3,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002733
Jan Eilers53ef7952021-06-02 12:01:25 +01002734 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 1, 6, 4, 4, 4
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002735 };
2736
2737 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2738 workloadFactory,
2739 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002740 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002741 inputNoQuantizedValues,
2742 inputTensorInfo,
2743 kernelNoQuantizedValues,
2744 kernelTensorInfo,
2745 outputExpectedNoQuantizedValues,
2746 outputTensorInfo,
2747 3,
2748 3,
2749 layout,
2750 biasEnabled);
2751}
2752
2753template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2754LayerTestResult<T, 4> DepthwiseConvolution2dMult4Test(
2755 armnn::IWorkloadFactory& workloadFactory,
2756 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002757 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002758 bool biasEnabled,
2759 const armnn::DataLayout layout)
2760{
2761 armnn::TensorInfo inputTensorInfo({1, 2, 3, 3}, ArmnnType);
2762 std::vector<float> inputNoQuantizedValues =
2763 {
2764 10.0, 10.0, 10.0,
2765 10.0, 10.0, 10.0,
2766 10.0, 10.0, 10.0,
2767
2768 21.0, 22.0, 23.0,
2769 24.0, 25.0, 26.0,
2770 27.0, 28.0, 29.0
2771 };
2772
Jan Eilers53ef7952021-06-02 12:01:25 +01002773 armnn::TensorInfo kernelTensorInfo({ 1, 2, 2, 8}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002774
2775 std::vector<float> kernelNoQuantizedValues =
2776 {
2777 0.25f, 0.25f,
2778 0.25f, 0.25f,
2779
2780 0.25f, 0.25f,
2781 0.25f, 0.25f,
2782
2783 0.0f , 0.0f,
2784 0.0f , 0.1f,
2785
2786 0.0f , 0.0f,
2787 0.0f , 0.1f,
2788
2789 0.2f , 0.0f,
2790 0.0f , 0.0f,
2791
2792 0.2f , 0.0f,
2793 0.0f , 0.0f,
2794
2795 0.0f , 0.3f,
2796 0.0f , 0.0f,
2797
2798 0.0f , 0.3f,
2799 0.0f , 0.0f
2800 };
2801
2802 armnn::TensorInfo outputTensorInfo({ 1, 8, 2, 2}, ArmnnType);
2803 std::vector<float> outputExpectedNoQuantizedValues =
2804 {
Jan Eilers53ef7952021-06-02 12:01:25 +01002805 4.5f, 4.5f, 4.5f, 4.5f, 5.5f, 5.5f, 5.5f, 5.5f,
2806 2.5f, 2.5f, 2.5f, 2.5f, 3.5f, 3.5f, 3.5f, 3.5f,
2807 10.05f, 10.5f, 11.4f, 11.85f, 12.75f, 13.3f, 14.4f, 14.95f,
2808 5.25f, 5.5f, 6.0f, 6.25f, 7.45f, 7.8f, 8.5f, 8.85f
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002809 };
2810
2811
2812 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2813 workloadFactory,
2814 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002815 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002816 inputNoQuantizedValues,
2817 inputTensorInfo,
2818 kernelNoQuantizedValues,
2819 kernelTensorInfo,
2820 outputExpectedNoQuantizedValues,
2821 outputTensorInfo,
2822 1,
2823 1,
2824 layout,
2825 biasEnabled);
2826}
2827
2828template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2829LayerTestResult<T, 4> DepthwiseConvolution2dMult2Test(
2830 armnn::IWorkloadFactory& workloadFactory,
2831 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002832 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002833 bool biasEnabled,
2834 const armnn::DataLayout layout)
2835{
2836 armnn::TensorInfo inputTensorInfo({1, 2, 3, 3}, ArmnnType);
2837 std::vector<float> inputNoQuantizedValues =
2838 {
2839 10.0, 10.0, 10.0,
2840 10.0, 10.0, 10.0,
2841 10.0, 10.0, 10.0,
2842
2843 21.0, 22.0, 23.0,
2844 24.0, 25.0, 26.0,
2845 27.0, 28.0, 29.0
2846 };
2847
Jan Eilers53ef7952021-06-02 12:01:25 +01002848 armnn::TensorInfo kernelTensorInfo({ 1, 2, 2, 4}, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002849
2850 std::vector<float> kernelNoQuantizedValues =
2851 {
2852 0.25f, 0.25f,
2853 0.25f, 0.25f,
2854
2855 0.2f , 0.0f,
2856 0.0f , 0.0f,
2857
2858 0.0f , 0.0f,
2859 0.0f , 0.1f,
2860
2861 0.0f , 0.3f,
2862 0.0f , 0.0f
2863
2864 };
2865
2866 armnn::TensorInfo outputTensorInfo({ 1, 4, 2, 2}, ArmnnType);
2867 std::vector<float> outputExpectedNoQuantizedValues =
2868 {
Jan Eilers53ef7952021-06-02 12:01:25 +01002869 4.5f, 4.5f, 4.5f, 4.5f,
2870 5.5f, 5.5f, 5.5f, 5.5f,
2871 5.25f, 5.5f, 6.0f, 6.25f,
2872 7.65f, 8.0f, 8.7f, 9.05f
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002873 };
2874
2875
2876 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2877 workloadFactory,
2878 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002879 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002880 inputNoQuantizedValues,
2881 inputTensorInfo,
2882 kernelNoQuantizedValues,
2883 kernelTensorInfo,
2884 outputExpectedNoQuantizedValues,
2885 outputTensorInfo,
2886 1,
2887 1,
2888 layout,
2889 biasEnabled);
2890}
2891
2892template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
2893LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
2894 armnn::IWorkloadFactory& workloadFactory,
2895 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2896 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002897 const armnn::ITensorHandleFactory& tensorHandleFactory,
2898 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002899 const armnnUtils::DataLayoutIndexed& layout)
2900{
2901 unsigned int inputHeight = 8;
2902 unsigned int inputWidth = 16;
2903 unsigned int inputChannels = 3;
2904 unsigned int inputNum = 5;
2905
2906 unsigned int kernelHeight = 3;
2907 unsigned int kernelWidth = 3;
2908 unsigned int channelMultiplier = 1;
2909
2910 unsigned int strideX = 2;
2911 unsigned int strideY = 3;
2912 unsigned int padX = 1;
2913 unsigned int padY = 1;
2914
2915 unsigned int outputNum = inputNum;
2916 unsigned int outputChannels = inputChannels * channelMultiplier;
2917 unsigned int outputHeight = (inputHeight + 2 * padY - kernelHeight + strideY) / strideY;
2918 unsigned int outputWidth = (inputWidth + 2 * padX - kernelWidth + strideX) / strideX;
2919
2920 armnn::TensorInfo inputTensorInfo;
2921 armnn::TensorInfo outputTensorInfo;
2922 armnn::TensorInfo kernelDesc;
2923 armnn::TensorInfo biasDesc;
2924
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002925 std::vector<unsigned int> inputShape;
2926 std::vector<unsigned int> outputShape;
Jan Eilers53ef7952021-06-02 12:01:25 +01002927 std::vector<unsigned int> kernelShape{ 1, kernelHeight, kernelWidth, outputChannels };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002928 std::vector<unsigned int> biasShape{ outputChannels };
2929 switch (layout.GetDataLayout())
2930 {
2931 case armnn::DataLayout::NCHW:
2932 inputShape = { inputNum, inputChannels, inputHeight, inputWidth };
2933 outputShape = { outputNum, outputChannels, outputHeight, outputWidth };
2934 break;
2935 case armnn::DataLayout ::NHWC:
2936 inputShape = { inputNum, inputHeight, inputWidth, inputChannels };
2937 outputShape = { outputNum, outputHeight, outputWidth, outputChannels };
2938 break;
2939 default:
2940 throw armnn::InvalidArgumentException("unknown data layout ["
2941 + std::to_string(static_cast<int>(layout.GetDataLayout())) + "]");
2942 }
2943
2944 float inputsQScale = armnn::IsQuantizedType<T>() ? 1.0f : 0;
2945 float outputQScale = armnn::IsQuantizedType<T>() ? 2.0f : 0;
2946 int32_t qOffset = 0;
2947
2948 inputTensorInfo = armnn::TensorInfo(4, inputShape.data(), ArmnnType, inputsQScale, qOffset);
2949 outputTensorInfo = armnn::TensorInfo(4, outputShape.data(), ArmnnType, outputQScale, qOffset);
2950 kernelDesc = armnn::TensorInfo(4, kernelShape.data(), ArmnnType, inputsQScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01002951 biasDesc = armnn::TensorInfo(1, biasShape.data(), armnn::GetBiasDataType(ArmnnType), inputsQScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002952
Sadik Armagan483c8112021-06-01 09:24:52 +01002953 auto input = MakeRandomTensor<T>(inputTensorInfo, 124908, 0.0f, 255.0f);
2954 auto kernel = MakeRandomTensor<T>(kernelDesc, 891234, 0.0f, 255.0f);
2955 auto bias = MakeRandomTensor<typename FullyConnectedBiasTypeForInputType<T>::Type>(biasDesc, 1028, 0.0f, 255.0f);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002956
Sadik Armagan483c8112021-06-01 09:24:52 +01002957 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
2958 std::vector<T> expectedOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01002959
2960 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2961 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2962
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002963 armnn::DepthwiseConvolution2dQueueDescriptor data;
2964 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01002965 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
2966 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002967
Sadik Armagan483c8112021-06-01 09:24:52 +01002968 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
2969 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002970
2971 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2972 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2973 data.m_Weight = &weightsTensor;
2974 data.m_Bias = &biasTensor;
2975 data.m_Parameters.m_StrideX = strideX;
2976 data.m_Parameters.m_StrideY = strideY;
2977 data.m_Parameters.m_PadLeft = padX;
2978 data.m_Parameters.m_PadRight = padX;
2979 data.m_Parameters.m_PadTop = padY;
2980 data.m_Parameters.m_PadBottom = padY;
2981 data.m_Parameters.m_BiasEnabled = true;
2982 data.m_Parameters.m_DataLayout = layout.GetDataLayout();
Keith Davisf500d6c2020-08-31 08:32:55 +01002983
2984 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2985 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2986
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002987 armnn::DepthwiseConvolution2dQueueDescriptor refData = data;
2988 armnn::WorkloadInfo refInfo = info;
2989 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
2990 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
2991
2992 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
2993 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateDepthwiseConvolution2d(refData, refInfo);
2994
2995 outputHandleRef->Allocate();
2996 inputHandleRef->Allocate();
2997
2998 inputHandle->Allocate();
2999 outputHandle->Allocate();
3000
Sadik Armagan483c8112021-06-01 09:24:52 +01003001 CopyDataToITensorHandle(inputHandle.get(), input.data());
3002 CopyDataToITensorHandle(inputHandleRef.get(), input.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003003
3004 ExecuteWorkload(*workload, memoryManager);
3005
3006 workloadRef->PostAllocationConfigure();
3007 workloadRef->Execute();
3008
Sadik Armagan483c8112021-06-01 09:24:52 +01003009 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
3010 CopyDataFromITensorHandle(expectedOutput.data(), outputHandleRef.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003011
Sadik Armagan483c8112021-06-01 09:24:52 +01003012 return LayerTestResult<T, 4>(actualOutput,
3013 expectedOutput,
3014 outputHandle->GetShape(),
3015 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003016}
3017
3018//
3019// Explicit template specializations
3020//
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003021template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3022Convolution2d3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3023 armnn::IWorkloadFactory&,
3024 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003025 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003026 bool,
3027 armnn::DataLayout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003028
3029template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3030Convolution2d3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3031 armnn::IWorkloadFactory&,
3032 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003033 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003034 bool,
3035 armnn::DataLayout);
3036
Sadik Armagan303980c2020-04-17 12:45:14 +01003037template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3038Convolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3039 armnn::IWorkloadFactory&,
3040 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003041 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003042 bool,
3043 armnn::DataLayout);
3044
Derek Lambertif90c56d2020-01-10 17:14:08 +00003045template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3046Convolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003047 armnn::IWorkloadFactory&,
3048 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003049 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003050 bool,
3051 armnn::DataLayout);
3052
Derek Lambertif90c56d2020-01-10 17:14:08 +00003053template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3054Convolution2d3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003055 armnn::IWorkloadFactory&,
3056 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003057 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003058 bool,
3059 armnn::DataLayout);
3060
3061template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3062Convolution2d2x3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3063 armnn::IWorkloadFactory&,
3064 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003065 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003066 bool,
3067 armnn::DataLayout);
3068
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003069template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3070Convolution2d2x3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3071 armnn::IWorkloadFactory&,
3072 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003073 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003074 bool,
3075 armnn::DataLayout);
3076
Sadik Armagan303980c2020-04-17 12:45:14 +01003077template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3078Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3079 armnn::IWorkloadFactory&,
3080 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003081 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003082 bool,
3083 armnn::DataLayout);
3084
Derek Lambertif90c56d2020-01-10 17:14:08 +00003085template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3086Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003087 armnn::IWorkloadFactory&,
3088 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003089 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003090 bool,
3091 armnn::DataLayout);
3092
Derek Lambertif90c56d2020-01-10 17:14:08 +00003093template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3094Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003095 armnn::IWorkloadFactory&,
3096 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003097 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003098 bool,
3099 armnn::DataLayout);
3100
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003101template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3102Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3103 armnn::IWorkloadFactory &workloadFactory,
3104 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003105 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003106 bool biasEnabled,
3107 const armnn::DataLayout layout);
3108
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003109template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3110Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3111 armnn::IWorkloadFactory &workloadFactory,
3112 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003113 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003114 bool biasEnabled,
3115 const armnn::DataLayout layout);
3116
Sadik Armagan303980c2020-04-17 12:45:14 +01003117template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3118Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3119 armnn::IWorkloadFactory &workloadFactory,
3120 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003121 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan303980c2020-04-17 12:45:14 +01003122 bool biasEnabled,
3123 const armnn::DataLayout layout);
3124
Derek Lambertif90c56d2020-01-10 17:14:08 +00003125template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3126Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003127 armnn::IWorkloadFactory &workloadFactory,
3128 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003129 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003130 bool biasEnabled,
3131 const armnn::DataLayout layout);
3132
Derek Lambertif90c56d2020-01-10 17:14:08 +00003133template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3134Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003135 armnn::IWorkloadFactory &workloadFactory,
3136 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003137 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003138 bool biasEnabled,
3139 const armnn::DataLayout layout);
3140
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003141template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3142DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3143 armnn::IWorkloadFactory&,
3144 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003145 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003146 bool,
3147 armnn::DataLayout);
3148
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003149template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3150DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3151 armnn::IWorkloadFactory&,
3152 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003153 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003154 bool,
3155 armnn::DataLayout);
3156
Sadik Armagan303980c2020-04-17 12:45:14 +01003157template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3158DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3159 armnn::IWorkloadFactory&,
3160 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003161 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003162 bool,
3163 armnn::DataLayout);
3164
Derek Lambertif90c56d2020-01-10 17:14:08 +00003165template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3166DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003167 armnn::IWorkloadFactory&,
3168 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003169 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003170 bool,
3171 armnn::DataLayout);
3172
Derek Lambertif90c56d2020-01-10 17:14:08 +00003173template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3174DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003175 armnn::IWorkloadFactory&,
3176 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003177 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003178 bool,
3179 armnn::DataLayout);
3180
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003181template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3182DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3183 armnn::IWorkloadFactory&,
3184 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003185 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003186 bool,
3187 armnn::DataLayout);
3188
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003189template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3190DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3191 armnn::IWorkloadFactory&,
3192 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003193 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003194 bool,
3195 armnn::DataLayout);
3196
Sadik Armagan303980c2020-04-17 12:45:14 +01003197template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3198DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3199 armnn::IWorkloadFactory&,
3200 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003201 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003202 bool,
3203 armnn::DataLayout);
3204
Derek Lambertif90c56d2020-01-10 17:14:08 +00003205template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3206DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003207 armnn::IWorkloadFactory&,
3208 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003209 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003210 bool,
3211 armnn::DataLayout);
3212
Derek Lambertif90c56d2020-01-10 17:14:08 +00003213template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3214DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003215 armnn::IWorkloadFactory&,
3216 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003217 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003218 bool,
3219 armnn::DataLayout);
3220
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003221template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3222DepthwiseConvolution2dMult4Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3223 armnn::IWorkloadFactory &workloadFactory,
3224 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003225 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003226 bool biasEnabled,
3227 const armnn::DataLayout layout);
3228
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003229template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3230DepthwiseConvolution2dMult4Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3231 armnn::IWorkloadFactory &workloadFactory,
3232 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003233 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003234 bool biasEnabled,
3235 const armnn::DataLayout layout);
3236
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003237template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3238DepthwiseConvolution2dMult2Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3239 armnn::IWorkloadFactory &workloadFactory,
3240 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003241 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003242 bool biasEnabled,
3243 const armnn::DataLayout layout);
3244
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003245template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3246DepthwiseConvolution2dMult2Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3247 armnn::IWorkloadFactory &workloadFactory,
3248 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003249 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003250 bool biasEnabled,
3251 const armnn::DataLayout layout);
3252
3253//
3254// Implementation functions
3255//
3256
3257LayerTestResult<float, 4> SimpleConvolution2d3x5Test(
3258 armnn::IWorkloadFactory& workloadFactory,
3259 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003260 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003261 bool biasEnabled,
3262 const armnn::DataLayout layout)
3263{
3264 return SimpleConvolution2d3x5TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003265 workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003266}
3267
3268LayerTestResult<uint8_t, 4> SimpleConvolution2d3x5Uint8Test(
3269 armnn::IWorkloadFactory& workloadFactory,
3270 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003271 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003272 bool biasEnabled,
3273 const armnn::DataLayout layout)
3274{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003275 return SimpleConvolution2d3x5TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003276 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003277}
3278
3279LayerTestResult<float, 4> SimpleConvolution2d3x3Test(
3280 armnn::IWorkloadFactory& workloadFactory,
3281 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003282 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003283 bool biasEnabled,
3284 const armnn::DataLayout layout)
3285{
3286 return SimpleConvolution2d3x3TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003287 workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003288}
3289
3290LayerTestResult<float, 4> SimpleConvolution2d3x3NhwcTest(
3291 armnn::IWorkloadFactory& workloadFactory,
3292 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003293 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003294 bool biasEnabled)
3295{
3296 return SimpleConvolution2d3x3NhwcTestCommon<armnn::DataType::Float32>(
3297 workloadFactory,
3298 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003299 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003300 0.f,
3301 0,
3302 biasEnabled,
3303 armnn::DataLayout::NHWC);
3304}
3305
3306LayerTestResult<float, 4> SimpleConvolution2d3x3Stride2x2Test(
3307 armnn::IWorkloadFactory& workloadFactory,
3308 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003309 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003310 bool biasEnabled,
3311 const armnn::DataLayout layout)
3312{
3313 return SimpleConvolution2d3x3Stride2x2TestCommon<armnn::DataType::Float32>(
3314 workloadFactory,
3315 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003316 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003317 0.f,
3318 0,
3319 biasEnabled,
3320 layout);
3321}
3322
3323LayerTestResult<uint8_t, 4> SimpleConvolution2d3x3Uint8Test(
3324 armnn::IWorkloadFactory& workloadFactory,
3325 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003326 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003327 bool biasEnabled,
3328 const armnn::DataLayout layout)
3329{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003330 return SimpleConvolution2d3x3TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003331 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003332}
3333
3334LayerTestResult<int16_t, 4> SimpleConvolution2d3x5QSymm16Test(
3335 armnn::IWorkloadFactory& workloadFactory,
3336 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003337 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003338 bool biasEnabled,
3339 const armnn::DataLayout layout)
3340{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003341 return SimpleConvolution2d3x5TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003342 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003343}
3344
3345LayerTestResult<int16_t, 4> SimpleConvolution2d3x3QSymm16Test(
3346 armnn::IWorkloadFactory& workloadFactory,
3347 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003348 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003349 bool biasEnabled,
3350 const armnn::DataLayout layout)
3351{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003352 return SimpleConvolution2d3x3TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003353 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003354}
3355
3356LayerTestResult<float, 4> Convolution2dAsymmetricPaddingTest(
3357 armnn::IWorkloadFactory& workloadFactory,
3358 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003359 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003360 armnn::DataLayout layout)
3361{
3362 return SimpleConvolution2dAsymmetricPaddingTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003363 workloadFactory, memoryManager, tensorHandleFactory, layout, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003364}
3365
3366LayerTestResult<float, 4> Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTest(
3367 armnn::IWorkloadFactory& workloadFactory,
3368 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003369 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003370 armnn::DataLayout layout)
3371{
3372 return Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTestCommon
3373 <armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003374 workloadFactory, memoryManager, tensorHandleFactory, layout, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003375}
3376
3377LayerTestResult<float, 4> Convolution1dTest(
3378 armnn::IWorkloadFactory& workloadFactory,
3379 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003380 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003381 bool biasEnabled)
3382{
3383 return Convolution1dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003384 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003385}
3386
3387LayerTestResult<uint8_t, 4> Convolution1dUint8Test(
3388 armnn::IWorkloadFactory& workloadFactory,
3389 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003390 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003391 bool biasEnabled)
3392{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003393 return Convolution1dTestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003394 workloadFactory, memoryManager, tensorHandleFactory, 0.1f, 128, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003395}
3396
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003397LayerTestResult<uint8_t, 4> Convolution2dPerAxisQuantTest(
3398 armnn::IWorkloadFactory& workloadFactory,
3399 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003400 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003401 const armnn::DataLayout layout)
3402{
3403 using namespace armnn;
3404
Derek Lambertif90c56d2020-01-10 17:14:08 +00003405 const DataType inputType = DataType::QAsymmU8;
Derek Lambertid466a542020-01-22 15:37:29 +00003406 const DataType kernelType = DataType::QSymmS8;
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003407 const DataType biasType = DataType::Signed32;
3408
3409 TensorInfo inputInfo ({ 1, 3, 1, 2 }, inputType, 0.5f, 128);
3410 TensorInfo outputInfo({ 1, 3, 1, 3 }, inputType, 1.0f, 128);
3411
3412 const std::vector<float> quantScales{ 0.5f, 0.75f, 1.0f };
3413 constexpr unsigned int quantDimension = 0;
3414
3415 TensorInfo kernelInfo({ 3, 1, 1, 2 }, kernelType, quantScales, quantDimension);
3416
3417 const std::vector<float> biasQuantScales{ 0.25f, 0.375f, 0.5f };
3418 TensorInfo biasInfo({ 3 }, biasType, biasQuantScales, quantDimension);
3419
3420 std::vector<uint8_t> inputData =
3421 {
3422 138, 108, 138, 108, 138, 108
3423 };
3424
3425 std::vector<int8_t> kernelData =
3426 {
3427 1, 2, 1, 2, 1, 2
3428 };
3429
3430 std::vector<int32_t> biasData =
3431 {
3432 4, 4, 4
3433 };
3434
3435 std::vector<uint8_t> expectedOutputData =
3436 {
3437 121, 118, 115, 121, 118, 115, 121, 118, 115
3438 };
3439
3440 if (layout == DataLayout::NCHW)
3441 {
3442 PermuteTensorNhwcToNchw(inputInfo, inputData);
3443 PermuteTensorNhwcToNchw(kernelInfo, kernelData);
3444 PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
3445 }
3446
Sadik Armagan483c8112021-06-01 09:24:52 +01003447 std::vector<uint8_t> actualOutput(outputInfo.GetNumElements());
3448
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003449 Convolution2dDescriptor descriptor;
3450 descriptor.m_StrideX = 1;
3451 descriptor.m_StrideY = 1;
3452 descriptor.m_PadLeft = 0;
3453 descriptor.m_PadRight = 0;
3454 descriptor.m_PadTop = 0;
3455 descriptor.m_PadBottom = 0;
3456 descriptor.m_BiasEnabled = true;
3457 descriptor.m_DataLayout = layout;
3458
Keith Davisf500d6c2020-08-31 08:32:55 +01003459 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
3460 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
3461
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003462 WorkloadInfo workloadInfo;
James Conroy1f58f032021-04-27 17:13:27 +01003463 ScopedTensorHandle weightTensor(kernelInfo);
3464 ScopedTensorHandle biasTensor(biasInfo);
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003465
3466 AllocateAndCopyDataToITensorHandle(&weightTensor, kernelData.data());
3467 AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
3468
3469 Convolution2dQueueDescriptor queueDescriptor;
3470 queueDescriptor.m_Parameters = descriptor;
3471 queueDescriptor.m_Weight = &weightTensor;
3472 queueDescriptor.m_Bias = &biasTensor;
3473
3474 AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
3475 AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
3476
3477 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConvolution2d(queueDescriptor, workloadInfo);
3478 inputHandle->Allocate();
3479 outputHandle->Allocate();
3480
3481 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
3482
3483 ExecuteWorkload(*workload, memoryManager);
3484
Sadik Armagan483c8112021-06-01 09:24:52 +01003485 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003486
Sadik Armagan483c8112021-06-01 09:24:52 +01003487 return LayerTestResult<uint8_t, 4>(actualOutput,
3488 expectedOutputData,
3489 outputHandle->GetShape(),
3490 outputInfo.GetShape());
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003491}
3492
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003493LayerTestResult<float,4> CompareConvolution2dTest(
3494 armnn::IWorkloadFactory& workloadFactory,
3495 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003496 armnn::IWorkloadFactory& refWorkloadFactory,
3497 const armnn::ITensorHandleFactory& tensorHandleFactory,
3498 const armnn::ITensorHandleFactory& refTensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003499{
3500 return CompareConvolution2dTestImpl<armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003501 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003502}
3503
3504LayerTestResult<float, 4> DepthwiseConvolution2dTest(
3505 armnn::IWorkloadFactory& workloadFactory,
3506 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003507 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003508 bool biasEnabled,
3509 const armnn::DataLayout layout)
3510{
3511 return DepthwiseConvolution2dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003512 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003513}
3514
3515LayerTestResult<float, 4> DepthwiseConvolution2dDepthNhwcTest(
3516 armnn::IWorkloadFactory& workloadFactory,
3517 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003518 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003519 bool biasEnabled)
3520{
3521 return DepthwiseConvolution2dNhwcTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003522 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003523}
3524
3525LayerTestResult<float, 4> DepthwiseConvolution2dDepthMul1Test(
3526 armnn::IWorkloadFactory& workloadFactory,
3527 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003528 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003529 bool biasEnabled,
3530 const armnn::DataLayout layout)
3531{
3532 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003533 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003534}
3535
3536LayerTestResult<float, 4> DepthwiseConvolution2dDepthMul64Test(
3537 armnn::IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003538 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3539 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003540{
3541 armnn::TensorInfo inputTensorInfo({ 1, 1, 2, 2 }, armnn::DataType::Float32);
Sadik Armagan483c8112021-06-01 09:24:52 +01003542 std::vector<float> input = { 1.f, 2.f, 3.f, 4.f };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003543
3544 std::vector<float> kernelData;
3545 std::vector<float> singleDepthKernel{ 1.f, -1.f, -1.f, 1.f };
3546 for (unsigned int i = 0; i < 64; ++i)
3547 {
3548 kernelData.insert(kernelData.end(), singleDepthKernel.begin(), singleDepthKernel.end());
3549 }
3550 armnn::TensorInfo kernelTensorInfo({ 64, 1, 2, 2 }, armnn::DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003551
Jan Eilers53ef7952021-06-02 12:01:25 +01003552 // permute from [O,1,H,W] --> [1,H,W,O]
3553 armnn::PermutationVector permutationVector {3,0,1,2};
3554 kernelTensorInfo = armnnUtils::Permuted(kernelTensorInfo, permutationVector);
3555 std::vector<float> kernelPermuted(kernelTensorInfo.GetNumElements());
3556 armnnUtils::Permute(kernelTensorInfo.GetShape(), permutationVector,
3557 kernelData.data(), kernelPermuted.data(),
3558 GetDataTypeSize(kernelTensorInfo.GetDataType()));
3559
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003560 std::vector<float> expectedOutputData(64, 0.f);
3561 armnn::TensorInfo outputTensorInfo({ 1, 64, 1, 1 }, armnn::DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003562
3563 return DepthwiseConvolution2dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
3564 workloadFactory,
3565 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003566 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003567 input,
Jan Eilers53ef7952021-06-02 12:01:25 +01003568 kernelPermuted,
Sadik Armagan483c8112021-06-01 09:24:52 +01003569 std::vector<float>(),
3570 expectedOutputData,
3571 inputTensorInfo.GetShape(),
3572 kernelTensorInfo.GetShape(),
3573 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003574 0.f,
3575 0,
3576 armnn::DataLayout::NCHW);
3577}
3578
3579LayerTestResult<float, 4> DepthwiseConvolution2dAsymmetricTest(
3580 armnn::IWorkloadFactory& workloadFactory,
3581 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003582 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003583 bool biasEnabled,
3584 const armnn::DataLayout layout)
3585{
3586 return DepthwiseConvolution2dAsymmetricTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003587 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003588}
3589
3590LayerTestResult<uint8_t, 4> DepthwiseConvolution2dUint8Test(
3591 armnn::IWorkloadFactory& workloadFactory,
3592 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003593 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003594 bool biasEnabled,
3595 const armnn::DataLayout layout)
3596{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003597 return DepthwiseConvolution2dTestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003598 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003599}
3600
3601LayerTestResult<uint8_t, 4> DepthwiseConvolution2dDepthMul1Uint8Test(
3602 armnn::IWorkloadFactory& workloadFactory,
3603 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003604 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003605 bool biasEnabled,
3606 const armnn::DataLayout layout)
3607{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003608 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003609 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003610}
3611
3612LayerTestResult<float, 4> SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTest(
3613 armnn::IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003614 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3615 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003616{
3617 return SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
3618 workloadFactory,
3619 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003620 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003621 0.f,
3622 0,
3623 false);
3624}
3625
3626LayerTestResult<int16_t, 4> DepthwiseConvolution2dInt16Test(
3627 armnn::IWorkloadFactory& workloadFactory,
3628 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003629 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003630 bool biasEnabled,
3631 const armnn::DataLayout layout)
3632{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003633 return DepthwiseConvolution2dTestImpl<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003634 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003635}
3636
3637LayerTestResult<int16_t, 4> DepthwiseConvolution2dDepthMul1Int16Test(
3638 armnn::IWorkloadFactory& workloadFactory,
3639 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003640 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003641 bool biasEnabled,
3642 const armnn::DataLayout layout)
3643{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003644 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003645 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003646}
3647
Teresa Charlind8df0262019-11-11 12:28:15 +00003648LayerTestResult<uint8_t, 4> DepthwiseConvolution2dPerAxisQuantTest(
3649 armnn::IWorkloadFactory& workloadFactory,
3650 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003651 const armnn::ITensorHandleFactory& tensorHandleFactory,
Teresa Charlind8df0262019-11-11 12:28:15 +00003652 const armnn::DataLayout layout)
3653{
3654 using namespace armnn;
3655
Derek Lambertif90c56d2020-01-10 17:14:08 +00003656 const DataType inputType = DataType::QAsymmU8;
Derek Lambertid466a542020-01-22 15:37:29 +00003657 const DataType kernelType = DataType::QSymmS8;
Teresa Charlind8df0262019-11-11 12:28:15 +00003658 const DataType biasType = DataType::Signed32;
3659
3660 TensorInfo inputInfo ({ 1, 3, 3, 2 }, inputType, 0.5f, 128); // N H W C
3661 TensorInfo outputInfo({ 1, 2, 2, 4 }, inputType, 1.0f, 128); // N H W C
3662
3663 const std::vector<float> quantScales{ 1.0f, 0.5f, 1.0f, 0.5f };
Jan Eilers53ef7952021-06-02 12:01:25 +01003664 const unsigned int quantDimension = 3;
3665 TensorInfo kernelInfo({ 1, 2, 2, 4 }, kernelType, quantScales, quantDimension); // [1, H, W, I*M]
Teresa Charlind8df0262019-11-11 12:28:15 +00003666
3667 const std::vector<float> biasQuantScales{ 0.5f, 0.25f, 0.5f, 0.25f };
3668 constexpr unsigned int biasQuantDimension = 0;
3669 TensorInfo biasInfo({ 4 }, biasType, biasQuantScales, biasQuantDimension);
3670
3671 std::vector<uint8_t> inputData =
3672 {
3673 129, 130,
3674 129, 130,
3675 129, 130,
3676 129, 130,
3677 129, 130,
3678 129, 130,
3679 129, 130,
3680 129, 130,
3681 129, 130
3682 };
3683
3684 std::vector<int8_t> kernelData =
3685 {
3686 1, 1, 1, 1,
3687 1, 1, 1, 1,
3688 1, 1, 1, 1,
3689 1, 1, 1, 1
3690 };
3691
3692 std::vector<int32_t> biasData =
3693 {
3694 4, 4, 4, 4
3695 };
3696
3697 std::vector<uint8_t> expectedOutputData =
3698 {
3699 132, 130, 134, 131,
3700 132, 130, 134, 131,
3701 132, 130, 134, 131,
3702 132, 130, 134, 131
3703 };
3704
3705 if (layout == DataLayout::NCHW)
3706 {
3707 PermuteTensorNhwcToNchw(inputInfo, inputData);
3708 PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
3709 }
3710
Sadik Armagan483c8112021-06-01 09:24:52 +01003711 std::vector<uint8_t> actualOutput(outputInfo.GetNumElements());
3712
Teresa Charlind8df0262019-11-11 12:28:15 +00003713 DepthwiseConvolution2dDescriptor descriptor;
3714 descriptor.m_StrideX = 1;
3715 descriptor.m_StrideY = 1;
3716 descriptor.m_PadLeft = 0;
3717 descriptor.m_PadRight = 0;
3718 descriptor.m_PadTop = 0;
3719 descriptor.m_PadBottom = 0;
3720 descriptor.m_DilationX = 1;
3721 descriptor.m_DilationY = 1;
3722 descriptor.m_BiasEnabled = true;
3723 descriptor.m_DataLayout = layout;
3724
Keith Davisf500d6c2020-08-31 08:32:55 +01003725 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
3726 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
Teresa Charlind8df0262019-11-11 12:28:15 +00003727
3728 WorkloadInfo workloadInfo;
James Conroy1f58f032021-04-27 17:13:27 +01003729 ScopedTensorHandle weightTensor(kernelInfo);
3730 ScopedTensorHandle biasTensor(biasInfo);
Teresa Charlind8df0262019-11-11 12:28:15 +00003731
3732 AllocateAndCopyDataToITensorHandle(&weightTensor, kernelData.data());
3733 AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
3734
3735 DepthwiseConvolution2dQueueDescriptor queueDescriptor;
3736 queueDescriptor.m_Parameters = descriptor;
3737 queueDescriptor.m_Weight = &weightTensor;
3738 queueDescriptor.m_Bias = &biasTensor;
3739
3740 AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
3741 AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
3742
3743 std::unique_ptr<IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(queueDescriptor, workloadInfo);
3744 inputHandle->Allocate();
3745 outputHandle->Allocate();
3746
3747 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
3748
3749 ExecuteWorkload(*workload, memoryManager);
3750
3751 LayerTestResult<uint8_t, 4> ret(outputInfo);
3752
Sadik Armagan483c8112021-06-01 09:24:52 +01003753 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Teresa Charlind8df0262019-11-11 12:28:15 +00003754
Sadik Armagan483c8112021-06-01 09:24:52 +01003755 return LayerTestResult<uint8_t, 4>(actualOutput,
3756 expectedOutputData,
3757 outputHandle->GetShape(),
3758 outputInfo.GetShape());
Teresa Charlind8df0262019-11-11 12:28:15 +00003759}
3760
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003761LayerTestResult<float, 4> CompareDepthwiseConvolution2dFloatTest(
3762 armnn::IWorkloadFactory& workloadFactory,
3763 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3764 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003765 const armnn::ITensorHandleFactory& tensorHandleFactory,
3766 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003767 const armnn::DataLayout layout)
3768{
3769 return CompareDepthwiseConvolution2dTestImpl<armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003770 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003771}
3772
3773LayerTestResult<uint8_t, 4> CompareDepthwiseConvolution2dUint8Test(
3774 armnn::IWorkloadFactory& workloadFactory,
3775 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3776 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003777 const armnn::ITensorHandleFactory& tensorHandleFactory,
3778 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003779 const armnn::DataLayout layout)
3780{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003781 return CompareDepthwiseConvolution2dTestImpl<armnn::DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003782 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003783}