blob: 98264ee928f783d9200c7225acd50f1cfcf5ef82 [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
James Conroy1f58f032021-04-27 17:13:27 +010016#include <backendsCommon/TensorHandle.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010017
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +000018#include <backendsCommon/test/DataLayoutUtils.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010019#include <backendsCommon/test/TensorCopyUtils.hpp>
20#include <backendsCommon/test/WorkloadTestUtils.hpp>
21
22#include <test/TensorHelpers.hpp>
23
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]);
1662 unsigned int kernelChanMul = armnn::numeric_cast<unsigned int>(kernelShape[0]);
1663 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(kernelShape[1]);
1664 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(kernelShape[2]);
1665 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(kernelShape[3]);
1666 unsigned int outputNum = armnn::numeric_cast<unsigned int>(outputExpectedShape[0]);
1667 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(outputExpectedShape[1]);
1668 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
1669 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(outputExpectedShape[3]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001670
1671 // If a bias is used, its size must equal the number of output channels.
1672 bool biasEnabled = bias.size() > 0;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01001673 ARMNN_ASSERT(!biasEnabled || bias.size() == outputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001674
1675 // Creates the tensors.
1676 armnn::TensorInfo inputTensorInfo =
1677 armnnUtils::GetTensorInfo(inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1678 armnn::TensorInfo outputTensorInfo =
1679 armnnUtils::GetTensorInfo(outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
1680 armnn::TensorInfo kernelDesc({kernelChanMul, kernelChannels, kernelHeight, kernelWidth}, ArmnnType);
1681 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
1682
1683 // Set quantization parameters if the requested type is a quantized type.
1684 if (armnn::IsQuantizedType<T>())
1685 {
1686 inputTensorInfo.SetQuantizationScale(qScale);
1687 inputTensorInfo.SetQuantizationOffset(qOffset);
1688 outputTensorInfo.SetQuantizationScale(qScale);
1689 outputTensorInfo.SetQuantizationOffset(qOffset);
1690 kernelDesc.SetQuantizationScale(qScale);
1691 kernelDesc.SetQuantizationOffset(qOffset);
1692 biasDesc.SetQuantizationScale(qScale*qScale);
1693 biasDesc.SetQuantizationOffset(0);
1694 }
1695
1696 // Construct the input data.
1697 std::vector<T> inputData;
1698 inputData.assign(input.data(), input.data() + inputChannels*inputHeight*inputWidth);
1699
1700 // At this point if we require it permute the input data
1701 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
1702 if (layout == armnn::DataLayout::NHWC)
1703 {
1704 std::vector<T> tmp(inputData.size());
1705 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
1706 inputData = tmp;
1707 }
1708
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001709 // Construct the output data, with bias applied, as appropriate.
1710 std::vector<T> outputData;
1711 outputData.assign(outputExpected.data(), outputExpected.data() + outputChannels*outputHeight*outputWidth);
1712 if (biasEnabled)
1713 {
1714 std::vector<T> biasV;
1715 biasV.assign(bias.data(), bias.data() + outputChannels);
1716 ApplyBias(outputData, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
1717 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
1718 outputWidth, outputHeight);
1719 }
1720
Sadik Armagan483c8112021-06-01 09:24:52 +01001721 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001722
1723 // At this point if we require it permute the expected output
1724 if (layout == armnn::DataLayout::NHWC)
1725 {
1726 std::vector<T> tmp(outputData.size());
1727 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp.data(), sizeof(T));
1728 outputData = tmp;
1729 }
1730
Keith Davisf500d6c2020-08-31 08:32:55 +01001731 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1732 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1733
James Conroy1f58f032021-04-27 17:13:27 +01001734 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001735
Sadik Armagan483c8112021-06-01 09:24:52 +01001736 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001737
James Conroy1f58f032021-04-27 17:13:27 +01001738 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001739 if (biasEnabled)
1740 {
Sadik Armagan483c8112021-06-01 09:24:52 +01001741 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001742 }
1743
1744 armnn::DepthwiseConvolution2dQueueDescriptor data;
1745 data.m_Weight = &weightsTensor;
1746 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - it can be a source of bugs.
1747 data.m_Parameters.m_StrideX = strideX;
1748 data.m_Parameters.m_StrideY = strideY;
1749 data.m_Parameters.m_PadLeft = padLeft;
1750 data.m_Parameters.m_PadRight = padRight;
1751 data.m_Parameters.m_PadTop = padTop;
1752 data.m_Parameters.m_PadBottom = padBottom;
1753 data.m_Parameters.m_BiasEnabled = biasEnabled;
1754 data.m_Parameters.m_DataLayout = layout;
1755
1756 armnn::WorkloadInfo info;
1757 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1758 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1759
1760 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
1761 inputHandle->Allocate();
1762 outputHandle->Allocate();
1763
Sadik Armagan483c8112021-06-01 09:24:52 +01001764 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001765
1766 ExecuteWorkload(*workload, memoryManager);
1767
Sadik Armagan483c8112021-06-01 09:24:52 +01001768 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001769
Sadik Armagan483c8112021-06-01 09:24:52 +01001770 return LayerTestResult<T, 4>(actualOutput,
1771 outputData,
1772 outputHandle->GetShape(),
1773 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001774}
1775
1776template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
1777LayerTestResult<T, 4> DepthwiseConvolution2dDepthMul1TestImpl(
1778 armnn::IWorkloadFactory& workloadFactory,
1779 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001780 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001781 float qScale,
1782 int32_t qOffset,
1783 bool biasEnabled,
1784 const armnn::DataLayout layout)
1785{
1786 using B = armnn::ResolveType<ArmnnBType>;
1787
1788 unsigned int inputHeight = 3;
1789 unsigned int inputWidth = 3;
1790 unsigned int inputChannels = 2;
1791 unsigned int inputNum = 1;
1792
1793 unsigned int kernelHeight = 3;
1794 unsigned int kernelWidth = 3;
1795 unsigned int kernelChannels = inputChannels;
1796 unsigned int kernelDepthMultiplier = 1;
1797
1798 unsigned int outputHeight = 1;
1799 unsigned int outputWidth = 1;
1800 unsigned int outputChannels = kernelChannels;
1801 unsigned int outputNum = inputNum;
1802
1803 armnn::TensorInfo inputTensorInfo =
1804 armnnUtils::GetTensorInfo(inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1805 armnn::TensorInfo outputTensorInfo =
1806 armnnUtils::GetTensorInfo(outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
1807 armnn::TensorInfo kernelDesc({kernelDepthMultiplier, kernelChannels, kernelHeight, kernelWidth},
1808 ArmnnType);
1809 armnn::TensorInfo biasDesc({ outputChannels }, ArmnnBType);
1810
1811 // Set quantization parameters if the requested type is a quantized type.
1812 if(armnn::IsQuantizedType<T>())
1813 {
1814 inputTensorInfo.SetQuantizationScale(qScale);
1815 inputTensorInfo.SetQuantizationOffset(qOffset);
1816 outputTensorInfo.SetQuantizationScale(qScale);
1817 outputTensorInfo.SetQuantizationOffset(qOffset);
1818 kernelDesc.SetQuantizationScale(qScale);
1819 kernelDesc.SetQuantizationOffset(qOffset);
1820 biasDesc.SetQuantizationScale(qScale*qScale);
1821 biasDesc.SetQuantizationOffset(0);
1822 }
1823 std::vector<T> inputData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001824 QuantizedVector<T>({
1825 1.f, 2.f, 1.f,
1826 2.f, 1.f, 2.f,
1827 1.f, 2.f, 1.f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001828
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001829 1.f, 2.f, 1.f,
1830 2.f, 1.f, 2.f,
1831 1.f, 2.f, 1.f,
1832 },
1833 inputTensorInfo.GetQuantizationScale(),
1834 inputTensorInfo.GetQuantizationOffset()));
1835
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001836 // at this point if we require it permute the input data
1837 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
1838 if (layout == armnn::DataLayout::NHWC)
1839 {
1840 std::vector<T> tmp(inputData.size());
1841 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
1842 inputData = tmp;
1843 }
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001844
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001845 std::vector<B> biasV(QuantizedVector<B>({ 0, 2 },
1846 biasDesc.GetQuantizationScale(),
1847 biasDesc.GetQuantizationOffset()));
1848
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001849 std::vector<T> kernelData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001850 QuantizedVector<T>({
1851 1.f, 0.f, 1.f,
1852 0.f, 0.f, 0.f,
1853 -1.f, 0.f, -1.f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001854
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001855 1.f, 0.f, 1.f,
1856 0.f, 0.f, 0.f,
1857 -1.f, 0.f, -1.f,
1858 },
1859 kernelDesc.GetQuantizationScale(),
1860 kernelDesc.GetQuantizationOffset()));
1861
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001862 // Manually calculated.
1863 std::vector<T> outputImage(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001864 QuantizedVector<T>({ 0.f, 0.f },
1865 outputTensorInfo.GetQuantizationScale(),
1866 outputTensorInfo.GetQuantizationOffset())
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001867 );
1868
1869 // Optionally apply bias to output image.
1870 if(biasEnabled)
1871 {
1872 ApplyBias(outputImage, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
1873 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
1874 outputWidth, outputHeight);
1875 }
1876
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001877 if (layout == armnn::DataLayout::NHWC)
1878 {
1879 std::vector<T> tmp(outputImage.size());
1880 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputImage.data(), tmp.data(), sizeof(T));
1881 outputImage = tmp;
1882 }
1883
Sadik Armagan483c8112021-06-01 09:24:52 +01001884 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001885
1886 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1887 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1888
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001889 armnn::DepthwiseConvolution2dQueueDescriptor data;
1890 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01001891 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
1892 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001893
Sadik Armagan483c8112021-06-01 09:24:52 +01001894 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
1895 AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001896
1897 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1898 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1899
1900 data.m_Weight = &weightsTensor;
1901 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
1902 data.m_Parameters.m_StrideX = 1;
1903 data.m_Parameters.m_StrideY = 1;
1904 data.m_Parameters.m_PadLeft = 0;
1905 data.m_Parameters.m_PadRight = 0;
1906 data.m_Parameters.m_PadTop = 0;
1907 data.m_Parameters.m_PadBottom = 0;
1908 data.m_Parameters.m_BiasEnabled = biasEnabled;
1909 data.m_Parameters.m_DataLayout = layout;
1910
1911 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
1912 inputHandle->Allocate();
1913 outputHandle->Allocate();
1914
Sadik Armagan483c8112021-06-01 09:24:52 +01001915 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001916
1917 ExecuteWorkload(*workload, memoryManager);
1918
Sadik Armagan483c8112021-06-01 09:24:52 +01001919 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001920
Sadik Armagan483c8112021-06-01 09:24:52 +01001921 return LayerTestResult<T, 4>(actualOutput,
1922 outputImage,
1923 outputHandle->GetShape(),
1924 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001925}
1926
1927template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
1928LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
1929 armnn::IWorkloadFactory& workloadFactory,
1930 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001931 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001932 float qScale,
1933 int32_t qOffset,
1934 bool biasEnabled,
1935 const armnn::DataLayout layout)
1936{
1937 using B = armnn::ResolveType<ArmnnBType>;
1938
1939 unsigned int depthMultiplier = 2;
1940
1941 unsigned int inputHeight = 8;
1942 unsigned int inputWidth = 16;
1943 unsigned int inputChannels = 2;
1944 unsigned int inputBatchSize = 1;
1945
1946 unsigned int kernelHeight = 5;
1947 unsigned int kernelWidth = 3;
1948
1949 unsigned int outputHeight = inputHeight - kernelHeight + 1 + 2;
1950 unsigned int outputWidth = (inputWidth - kernelWidth + 1)/2;
1951 unsigned int outputChannels = inputChannels * depthMultiplier;
1952 unsigned int outputBatchSize = inputBatchSize;
1953
1954 armnn::TensorInfo inputTensorInfo = armnnUtils::GetTensorInfo(
1955 inputBatchSize, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
1956 armnn::TensorInfo outputTensorInfo = armnnUtils::GetTensorInfo(
1957 outputBatchSize, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
1958 armnn::TensorInfo kernelDesc({depthMultiplier, inputChannels, kernelHeight, kernelWidth},
1959 ArmnnType);
1960 armnn::TensorInfo biasDesc({outputChannels}, ArmnnBType);
1961
1962 // Set quantization parameters if the requested type is a quantized type.
1963 if(armnn::IsQuantizedType<T>())
1964 {
1965 inputTensorInfo.SetQuantizationScale(qScale);
1966 inputTensorInfo.SetQuantizationOffset(qOffset);
1967 outputTensorInfo.SetQuantizationScale(qScale);
1968 outputTensorInfo.SetQuantizationOffset(qOffset);
1969 kernelDesc.SetQuantizationScale(qScale);
1970 kernelDesc.SetQuantizationOffset(qOffset);
1971 biasDesc.SetQuantizationScale(qScale*qScale);
1972 biasDesc.SetQuantizationOffset(0);
1973 }
1974
1975 // NOTE: originalInputData is in NCHW format
1976 std::vector<T> originalInputData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001977 QuantizedVector<T>({
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.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,
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.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,
1984 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,
1985 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,
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 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,
1992 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,
1993 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
1994 },
1995 inputTensorInfo.GetQuantizationScale(),
1996 inputTensorInfo.GetQuantizationOffset()));
1997
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001998 std::vector<T> inputData = originalInputData;
1999 // at this point if we require it permute the input data
2000 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
2001 if (layout == armnn::DataLayout::NHWC)
2002 {
2003 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC,
2004 originalInputData.data(), inputData.data(), sizeof(T));
2005 }
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002006
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002007 std::vector<B> biasV = QuantizedVector<B>({ 0, 2, 1, -1 },
2008 biasDesc.GetQuantizationScale(),
2009 biasDesc.GetQuantizationOffset());
2010
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002011 std::vector<T> kernelData = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002012 QuantizedVector<T>({
2013 1, 1, 1,
2014 1, -1, 1,
2015 1, 1, 1,
2016 1, 1, 1,
2017 1, 1, 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002018
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002019 2, 2, 2,
2020 2, 2, 2,
2021 2, 2, 2,
2022 2, 2, 2,
2023 2, 2, 2,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002024
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002025 0, 0, 0,
2026 0, -1, 0,
2027 0, 0, 0,
2028 0, 0, 0,
2029 0, 0, 0,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002030
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002031 0, 0, 0,
2032 0, 0, 0,
2033 0, 1, 0,
2034 0, 0, 0,
2035 0, 0, 0
2036 },
2037 kernelDesc.GetQuantizationScale(),
2038 kernelDesc.GetQuantizationOffset()));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002039
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002040 // Manually calculated.
2041 std::vector<T> originalOutputImage = std::vector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002042 QuantizedVector<T>({
2043 3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f,
2044 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
2045 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
2046 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f,
2047 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f,
2048 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002049
2050 -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002051 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002052 -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
2053 -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
2054 -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
2055 -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
2056
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002057 8.0f, 8.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002058 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2059 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2060 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2061 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002062 8.0f, 8.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002063
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002064 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2065 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2066 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2067 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2068 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
2069 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
2070 },
2071 outputTensorInfo.GetQuantizationScale(),
2072 outputTensorInfo.GetQuantizationOffset()));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002073
2074 // Optionally apply bias to output image.
2075 if(biasEnabled)
2076 {
2077 ApplyBias(originalOutputImage,
2078 outputTensorInfo.GetQuantizationScale(),
2079 outputTensorInfo.GetQuantizationOffset(),
2080 biasV,
2081 biasDesc.GetQuantizationScale(),
2082 biasDesc.GetQuantizationOffset(),
2083 outputWidth,
2084 outputHeight);
2085 }
2086
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002087 std::vector<T> outputImage = originalOutputImage;
2088 if (layout == armnn::DataLayout::NHWC)
2089 {
2090 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC,
2091 originalOutputImage.data(), outputImage.data(), sizeof(T));
2092 }
2093
Sadik Armagan483c8112021-06-01 09:24:52 +01002094 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01002095
2096 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2097 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2098
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002099 armnn::DepthwiseConvolution2dQueueDescriptor data;
2100 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01002101 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
2102 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002103
Sadik Armagan483c8112021-06-01 09:24:52 +01002104 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
2105 AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002106
2107 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2108 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2109
2110 data.m_Weight = &weightsTensor;
2111 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
2112 data.m_Parameters.m_StrideX = 2;
2113 data.m_Parameters.m_StrideY = 1;
2114 data.m_Parameters.m_PadLeft = 0;
2115 data.m_Parameters.m_PadRight = 0;
2116 data.m_Parameters.m_PadTop = 1;
2117 data.m_Parameters.m_PadBottom = 1;
2118 data.m_Parameters.m_BiasEnabled = biasEnabled;
2119 data.m_Parameters.m_DataLayout = layout;
2120
2121 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
2122 inputHandle->Allocate();
2123 outputHandle->Allocate();
2124
Sadik Armagan483c8112021-06-01 09:24:52 +01002125 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002126
2127 ExecuteWorkload(*workload, memoryManager);
2128
Sadik Armagan483c8112021-06-01 09:24:52 +01002129 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002130
Sadik Armagan483c8112021-06-01 09:24:52 +01002131 return LayerTestResult<T, 4>(actualOutput,
2132 outputImage,
2133 outputHandle->GetShape(),
2134 outputTensorInfo.GetShape());
2135
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002136}
2137
2138template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2139 typename T = armnn::ResolveType<ArmnnType>, typename B = armnn::ResolveType<ArmnnBType>>
2140LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
2141 armnn::IWorkloadFactory& workloadFactory,
2142 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002143 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan483c8112021-06-01 09:24:52 +01002144 const std::vector<T>& originalInput,
2145 const std::vector<T>& originalKernel,
2146 const std::vector<B>& bias,
2147 const std::vector<T>& originalOutputExpected,
2148 const armnn::TensorShape& originalInputShape,
2149 const armnn::TensorShape& originalKernelShape,
2150 const armnn::TensorShape& originalOutputExpectedShape,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002151 float qScale,
2152 int32_t qOffset,
2153 const armnn::DataLayout layout = armnn::DataLayout::NCHW,
2154 uint32_t padLeft = 0,
2155 uint32_t padTop = 0,
2156 uint32_t padRight = 0,
2157 uint32_t padBottom = 0,
2158 uint32_t strideX = 1,
2159 uint32_t strideY = 1,
2160 uint32_t dilationX = 1,
2161 uint32_t dilationY = 1)
2162{
Sadik Armagan483c8112021-06-01 09:24:52 +01002163 unsigned int inputHeight = armnn::numeric_cast<unsigned int>(originalInputShape[2]);
2164 unsigned int inputWidth = armnn::numeric_cast<unsigned int>(originalInputShape[3]);
2165 unsigned int inputChannels = armnn::numeric_cast<unsigned int>(originalInputShape[1]);
2166 unsigned int inputNum = armnn::numeric_cast<unsigned int>(originalInputShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002167
Sadik Armagan483c8112021-06-01 09:24:52 +01002168 unsigned int outputHeight = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[2]);
2169 unsigned int outputWidth = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[3]);
2170 unsigned int outputChannels = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[1]);
2171 unsigned int outputNum = armnn::numeric_cast<unsigned int>(originalOutputExpectedShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002172
Sadik Armagan483c8112021-06-01 09:24:52 +01002173 unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(originalKernelShape[2]);
2174 unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(originalKernelShape[3]);
2175 unsigned int kernelChannels = armnn::numeric_cast<unsigned int>(originalKernelShape[1]);
2176 unsigned int kernelDepthMul = armnn::numeric_cast<unsigned int>(originalKernelShape[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002177
2178 bool biasEnabled = bias.size() > 0;
2179
2180 // This function currently assumes 1 batch of input/output (and duplicates this into 2 batches).
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01002181 ARMNN_ASSERT(inputNum == 1);
2182 ARMNN_ASSERT(outputNum == 1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002183
2184 // If a bias is used, its size must equal the number of output channels.
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01002185 ARMNN_ASSERT(!biasEnabled || bias.size() == outputChannels);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002186
2187
2188 // Note these tensors will use two (identical) batches.
2189 armnn::TensorInfo inputTensorInfo =
2190 armnnUtils::GetTensorInfo(2*inputNum, inputChannels, inputHeight, inputWidth, layout, ArmnnType);
2191 armnn::TensorInfo outputTensorInfo =
2192 armnnUtils::GetTensorInfo(2*outputNum, outputChannels, outputHeight, outputWidth, layout, ArmnnType);
2193
2194 // Kernel must be NCHW layout always, independently of the layout of the input and output for depthwise convolution.
2195 armnn::TensorInfo kernelDesc({kernelDepthMul, kernelChannels, kernelHeight, kernelWidth}, ArmnnType);
2196
2197 armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
2198
2199 // Set quantization parameters if the requested type is a quantized type.
2200 if(armnn::IsQuantizedType<T>())
2201 {
2202 inputTensorInfo.SetQuantizationScale(qScale);
2203 inputTensorInfo.SetQuantizationOffset(qOffset);
2204 outputTensorInfo.SetQuantizationScale(qScale);
2205 outputTensorInfo.SetQuantizationOffset(qOffset);
2206 kernelDesc.SetQuantizationScale(qScale);
2207 kernelDesc.SetQuantizationOffset(qOffset);
2208 biasDesc.SetQuantizationScale(qScale*qScale);
2209 biasDesc.SetQuantizationOffset(0);
2210 }
2211
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002212 // Construct input data
2213 std::vector<T> input;
2214 input.assign(originalInput.data(), originalInput.data() + 1*inputChannels*inputHeight*inputWidth);
2215 std::vector<T> inputData;
2216 inputData.insert(inputData.end(), input.begin(), input.end());
2217 inputData.insert(inputData.end(), input.begin(), input.end());
2218
2219 // at this point if we require it permute the input data
2220 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
2221 if (layout == armnn::DataLayout::NHWC)
2222 {
2223 std::vector<T> tmp(inputData.size());
2224 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(T));
2225 inputData = tmp;
2226 }
2227
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002228 std::vector<T> output;
2229 output.assign(originalOutputExpected.data(),
2230 originalOutputExpected.data() + outputChannels*outputHeight*outputWidth);
2231
2232 // Apply bias to output data if it is enabled.
2233 if(biasEnabled)
2234 {
2235 std::vector<T> biasV;
2236 biasV.assign(bias.data(), bias.data() + outputChannels);
2237 ApplyBias(output, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
2238 biasV, biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset(),
2239 outputWidth, outputHeight);
2240 }
2241
Sadik Armagan483c8112021-06-01 09:24:52 +01002242 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
2243
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002244 // Construct expected output data
2245 std::vector<T> outputData;
2246 outputData.insert(outputData.end(), output.begin(), output.end());
2247 outputData.insert(outputData.end(), output.begin(), output.end());
2248
2249 // at this point if we require it permute the expected output
2250 if (layout == armnn::DataLayout::NHWC)
2251 {
2252 std::vector<T> tmp(outputData.size());
2253 armnnUtils::Permute(outputTensorInfo.GetShape(), NCHWToNHWC, outputData.data(), tmp.data(), sizeof(T));
2254 outputData = tmp;
2255 }
Keith Davisf500d6c2020-08-31 08:32:55 +01002256
2257 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2258 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2259
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002260 armnn::DepthwiseConvolution2dQueueDescriptor data;
2261 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01002262 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
2263 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002264
Sadik Armagan483c8112021-06-01 09:24:52 +01002265 AllocateAndCopyDataToITensorHandle(&weightsTensor, originalKernel.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002266
2267 if(biasEnabled)
2268 {
Sadik Armagan483c8112021-06-01 09:24:52 +01002269 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002270 }
2271
2272 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2273 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2274
2275 data.m_Weight = &weightsTensor;
2276 data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - can be a source of bugs.
2277 data.m_Parameters.m_StrideX = strideX;
2278 data.m_Parameters.m_StrideY = strideY;
2279 data.m_Parameters.m_PadLeft = padLeft;
2280 data.m_Parameters.m_PadRight = padRight;
2281 data.m_Parameters.m_PadTop = padTop;
2282 data.m_Parameters.m_PadBottom = padBottom;
2283 data.m_Parameters.m_BiasEnabled = biasEnabled;
2284 data.m_Parameters.m_DataLayout = layout;
2285 data.m_Parameters.m_DilationX = dilationX;
2286 data.m_Parameters.m_DilationY = dilationY;
2287
2288 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
2289 inputHandle->Allocate();
2290 outputHandle->Allocate();
2291
Sadik Armagan483c8112021-06-01 09:24:52 +01002292 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002293
2294 ExecuteWorkload(*workload, memoryManager);
2295
Sadik Armagan483c8112021-06-01 09:24:52 +01002296 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002297
Sadik Armagan483c8112021-06-01 09:24:52 +01002298 return LayerTestResult<T, 4>(actualOutput,
2299 outputData,
2300 outputHandle->GetShape(),
2301 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002302}
2303
2304template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2305 typename T = armnn::ResolveType<ArmnnType>>
2306LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestCommon(
2307 armnn::IWorkloadFactory& workloadFactory,
2308 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002309 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002310 float qScale,
2311 int32_t qOffset,
2312 bool biasEnabled,
2313 const armnn::DataLayout layout)
2314{
2315 // Use a single-batch 2-channel 5x5 image as input.
2316 armnn::TensorInfo inputTensorInfo({ 1, 2, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002317 auto input = QuantizedVector<T>(
2318 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002319 0, 1, 2, 3, 4,
2320 5, 6, 7, 8, 9,
2321 10, 11, 12, 13, 14,
2322 15, 16, 17, 18, 19,
2323 20, 21, 22, 23, 24,
2324
2325 25, 26, 27, 28, 29,
2326 30, 31, 32, 33, 34,
2327 35, 36, 37, 38, 39,
2328 40, 41, 42, 43, 44,
2329 45, 46, 47, 48, 49
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002330 },
2331 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002332 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002333
2334 // Use a depth multiplier of 1 on a 2-channel 4x4 kernel.
2335 armnn::TensorInfo kernelTensorInfo({ 1, 2, 4, 4 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002336 auto kernel = QuantizedVector<T>(
2337 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002338 32, 31, 30, 29,
2339 28, 27, 26, 25,
2340 24, 23, 22, 21,
2341 20, 19, 18, 17,
2342
2343 16, 15, 14, 13,
2344 12, 11, 10, 9,
2345 8, 7, 6, 5,
2346 4, 3, 2, 1
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002347 },
2348 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002349 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002350
2351 // Expected output is 1 batch of a 2-channel 5x5 image.
2352 // Calculated using the python tensorflow library with strideX=1, strideY=1.
2353 armnn::TensorInfo outputTensorInfo({ 1, 2, 5, 5 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002354 auto expectedOutput = QuantizedVector<T>(
2355 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002356 1062, 1580, 1850, 1530, 1117,
2357 2140, 3108, 3500, 2842, 2042,
2358 3580, 5068, 5460, 4342, 3062,
2359 3618, 5072, 5390, 4248, 2971,
2360 3074, 4282, 4510, 3533, 2457,
2361
2362 1550, 2284, 2362, 1955, 1428,
2363 2910, 4206, 4342, 3528, 2536,
2364 3390, 4886, 5022, 4068, 2916,
2365 3566, 5056, 5182, 4133, 2922,
2366 3100, 4352, 4452, 3517, 2465
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002367 },
2368 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002369 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002370
2371 return DepthwiseConvolution2dAsymmetricTestImpl<ArmnnType, ArmnnBType>(
2372 workloadFactory,
2373 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002374 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002375 input,
2376 kernel,
2377 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2378 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002379 inputTensorInfo.GetShape(),
2380 kernelTensorInfo.GetShape(),
2381 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002382 qScale,
2383 qOffset,
2384 layout,
2385 1, // Padding left.
2386 1, // Padding top.
2387 2, // Padding right.
2388 2, // Padding bottom.
2389 1, // strideX
2390 1); // strideY
2391}
2392
2393template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2394 typename T = armnn::ResolveType<ArmnnType>>
2395LayerTestResult<T, 4> DepthwiseConvolution2dNhwcTestCommon(
2396 armnn::IWorkloadFactory& workloadFactory,
2397 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002398 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002399 float qScale,
2400 int32_t qOffset,
2401 bool biasEnabled)
2402{
2403 auto layout = armnn::DataLayout::NHWC;
2404
2405 armnn::TensorInfo inputTensorInfo({ 1, 2, 5, 5}, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002406 auto input = QuantizedVector<T>(
2407 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002408 0, 1, 2, 3, 4,
2409 5, 6, 7, 8, 9,
2410 10, 11, 12, 13, 14,
2411 15, 16, 17, 18, 19,
2412 20, 21, 22, 23, 24,
2413
2414 25, 26, 27, 28, 29,
2415 30, 31, 32, 33, 34,
2416 35, 36, 37, 38, 39,
2417 40, 41, 42, 43, 44,
2418 45, 46, 47, 48, 49
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002419 },
2420 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002421 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002422
2423 armnn::TensorInfo kernelTensorInfo({ 1, 2, 4, 4 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002424 auto kernel = QuantizedVector<T>(
2425 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002426 32, 31, 30, 29,
2427 28, 27, 26, 25,
2428 24, 23, 22, 21,
2429 20, 19, 18, 17,
2430
2431 16, 15, 14, 13,
2432 12, 11, 10, 9,
2433 8, 7, 6, 5,
2434 4, 3, 2, 1
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002435 },
2436 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002437 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002438
2439 armnn::TensorInfo outputTensorInfo({ 1, 2, 5, 5}, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01002440 auto expectedOutput = QuantizedVector<T>(
2441 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002442 1062, 1580, 1850, 1530, 1117,
2443 2140, 3108, 3500, 2842, 2042,
2444 3580, 5068, 5460, 4342, 3062,
2445 3618, 5072, 5390, 4248, 2971,
2446 3074, 4282, 4510, 3533, 2457,
2447
2448 1550, 2284, 2362, 1955, 1428,
2449 2910, 4206, 4342, 3528, 2536,
2450 3390, 4886, 5022, 4068, 2916,
2451 3566, 5056, 5182, 4133, 2922,
2452 3100, 4352, 4452, 3517, 2465
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002453 },
2454 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002455 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002456
2457 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2458 workloadFactory,
2459 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002460 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002461 input,
2462 kernel,
2463 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2464 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002465 inputTensorInfo.GetShape(),
2466 kernelTensorInfo.GetShape(),
2467 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002468 qScale,
2469 qOffset,
2470 layout,
2471 1, // Padding left.
2472 1, // Padding top.
2473 2, // Padding right.
2474 2, // Padding bottom.
2475 1, // strideX
2476 1); // strideY
2477}
2478
2479template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType,
2480 typename T = armnn::ResolveType<ArmnnType>>
2481LayerTestResult<T, 4> SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTestCommon(
2482 armnn::IWorkloadFactory& workloadFactory,
2483 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002484 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002485 float qScale,
2486 int32_t qOffset,
2487 bool biasEnabled)
2488{
2489 auto layout = armnn::DataLayout::NHWC;
2490
Sadik Armagan483c8112021-06-01 09:24:52 +01002491 armnn::TensorInfo inputTensorInfo({ 1, 1, 9, 9 }, ArmnnType);
2492 auto input = QuantizedVector<T>(
2493 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002494 0, 0, 0, 0, 0, 0, 0, 0, 0,
2495 0, 0, 0, 0, 0, 0, 0, 0, 0,
2496 0, 0, 0, 0, 0, 0, 0, 0, 0,
2497 0, 0, 0, 1, 1, 1, 0, 0, 0,
2498 0, 0, 0, 1, 1, 1, 0, 0, 0,
2499 0, 0, 0, 1, 1, 1, 0, 0, 0,
2500 0, 0, 0, 0, 0, 0, 0, 0, 0,
2501 0, 0, 0, 0, 0, 0, 0, 0, 0,
2502 0, 0, 0, 0, 0, 0, 0, 0, 0
2503 },
2504 inputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002505 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002506
Sadik Armagan483c8112021-06-01 09:24:52 +01002507 armnn::TensorInfo kernelTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
2508 auto kernel = QuantizedVector<T>(
2509 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002510 1, 2, 3,
2511 4, 5, 6,
2512 7, 8, 9
2513 },
2514 kernelTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002515 kernelTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002516
2517 uint32_t padLeft = 0;
2518 uint32_t padTop = 0;
2519 uint32_t padRight = 0;
2520 uint32_t padBottom = 0;
2521 uint32_t strideX = 1;
2522 uint32_t strideY = 1;
2523 uint32_t dilationX = 3;
2524 uint32_t dilationY = 3;
2525
2526 // 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 +01002527 armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, ArmnnType);
2528 auto expectedOutput = QuantizedVector<T>(
2529 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002530 5, 5, 5,
2531 5, 5, 5,
2532 5, 5, 5
2533 },
2534 outputTensorInfo.GetQuantizationScale(),
Sadik Armagan483c8112021-06-01 09:24:52 +01002535 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002536
2537 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2538 workloadFactory,
2539 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002540 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002541 input,
2542 kernel,
2543 GetBias2<ArmnnBType>(biasEnabled, qScale * qScale),
2544 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002545 inputTensorInfo.GetShape(),
2546 kernelTensorInfo.GetShape(),
2547 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002548 qScale,
2549 qOffset,
2550 layout,
2551 padLeft,
2552 padTop,
2553 padRight,
2554 padBottom,
2555 strideX,
2556 strideY,
2557 dilationX,
2558 dilationY);
2559}
2560
2561template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T = armnn::ResolveType<ArmnnType>>
2562LayerTestResult<T, 4> DepthwiseConvolution2d3x3DilationTestCommon(
2563 armnn::IWorkloadFactory& workloadFactory,
2564 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002565 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002566 const std::vector<float>& inputNoQuantizedValues,
2567 armnn::TensorInfo& inputTensorInfo,
2568 const std::vector<float>& kernelNoQuantizedValues,
2569 armnn::TensorInfo& kernelTensorInfo,
2570 const std::vector<float>& outputExpectedNoQuantizedValues,
2571 armnn::TensorInfo& outputTensorInfo,
2572 uint32_t dilationX,
2573 uint32_t dilationY,
2574 armnn::DataLayout layout = armnn::DataLayout::NCHW,
2575 bool biasEnabled = false)
2576{
2577 float qScale;
2578 int32_t qOffset;
2579 switch (ArmnnType)
2580 {
Sadik Armagan303980c2020-04-17 12:45:14 +01002581 case armnn::DataType::QAsymmS8:
Derek Lambertif90c56d2020-01-10 17:14:08 +00002582 case armnn::DataType::QAsymmU8:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002583 {
2584 qScale = 0.1f;
2585 qOffset = 128;
2586 break;
2587 }
Derek Lambertif90c56d2020-01-10 17:14:08 +00002588 case armnn::DataType::QSymmS16:
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002589 {
2590 qScale = 0.1f;
2591 qOffset = 0;
2592 break;
2593 }
2594 case armnn::DataType::Float32:
2595 default:
2596 {
2597 qScale = 0.f;
2598 qOffset = 0;
2599 break;
2600 }
2601 }
2602
2603 inputTensorInfo.SetQuantizationScale(qScale);
2604 inputTensorInfo.SetQuantizationOffset(qOffset);
2605 kernelTensorInfo.SetQuantizationScale(qScale);
2606 kernelTensorInfo.SetQuantizationOffset(qOffset);
2607 outputTensorInfo.SetQuantizationScale(qScale);
2608 outputTensorInfo.SetQuantizationOffset(qOffset);
2609
Sadik Armagan483c8112021-06-01 09:24:52 +01002610 auto input = QuantizedVector<T>(inputNoQuantizedValues,
2611 inputTensorInfo.GetQuantizationScale(),
2612 inputTensorInfo.GetQuantizationOffset());
2613 auto kernel = QuantizedVector<T>(kernelNoQuantizedValues,
2614 kernelTensorInfo.GetQuantizationScale(),
2615 kernelTensorInfo.GetQuantizationOffset());
2616 auto expectedOutput = QuantizedVector<T>(outputExpectedNoQuantizedValues,
2617 outputTensorInfo.GetQuantizationScale(),
2618 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002619
2620 uint32_t padLeft = 0;
2621 uint32_t padTop = 0;
2622 uint32_t padRight = 0;
2623 uint32_t padBottom = 0;
2624 uint32_t strideX = 1;
2625 uint32_t strideY = 1;
2626
2627 return DepthwiseConvolution2dTestImpl<ArmnnType, ArmnnBType>(
2628 workloadFactory,
2629 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002630 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002631 input,
2632 kernel,
2633 GetBias<ArmnnBType>(biasEnabled, qScale * qScale, outputTensorInfo, layout),
2634 expectedOutput,
Sadik Armagan483c8112021-06-01 09:24:52 +01002635 inputTensorInfo.GetShape(),
2636 kernelTensorInfo.GetShape(),
2637 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002638 qScale,
2639 qOffset,
2640 layout,
2641 padLeft,
2642 padTop,
2643 padRight,
2644 padBottom,
2645 strideX,
2646 strideY,
2647 dilationX,
2648 dilationY);
2649}
2650
2651template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2652LayerTestResult<T, 4> DepthwiseConvolution2d3x3Dilation3x3Test(
2653 armnn::IWorkloadFactory& workloadFactory,
2654 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002655 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002656 bool biasEnabled,
2657 const armnn::DataLayout layout)
2658{
2659 armnn::TensorInfo inputTensorInfo({1, 1, 10, 10}, ArmnnType);
2660 std::vector<float> inputNoQuantizedValues =
2661 {
2662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2663 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2664 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2665 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2666 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2667 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2668 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2669 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2670 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2671 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2672 };
2673
2674 armnn::TensorInfo kernelTensorInfo({ 1, 1, 3, 3}, ArmnnType);
2675 std::vector<float> kernelNoQuantizedValues =
2676 {
2677 1, 2, 3,
2678 4, 5, 6,
2679 7, 8, 9
2680 };
2681
2682 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
2683 // therefore the output will be 4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
2684 armnn::TensorInfo outputTensorInfo({ 1, 1, 4, 4}, ArmnnType);
2685 std::vector<float> outputExpectedNoQuantizedValues =
2686 {
2687 6., 5., 5., 5.,
2688 6., 5., 5., 5.,
2689 6., 5., 5., 5.,
2690 3., 2., 2., 2.
2691 };
2692
2693 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2694 workloadFactory,
2695 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002696 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002697 inputNoQuantizedValues,
2698 inputTensorInfo,
2699 kernelNoQuantizedValues,
2700 kernelTensorInfo,
2701 outputExpectedNoQuantizedValues,
2702 outputTensorInfo,
2703 3,
2704 3,
2705 layout,
2706 biasEnabled);
2707}
2708
2709template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2710LayerTestResult<T, 4> DepthwiseConvolution2d2x3x3Dilation3x3Test(
2711 armnn::IWorkloadFactory& workloadFactory,
2712 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002713 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002714 bool biasEnabled,
2715 const armnn::DataLayout layout)
2716{
2717 armnn::TensorInfo inputTensorInfo({1, 2, 10, 10}, ArmnnType);
2718 std::vector<float> inputNoQuantizedValues =
2719 {
2720 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2721 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2722 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2723 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2724 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2725 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2730
2731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2732 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2733 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2734 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2735 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2736 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
2737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2738 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2739 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2741 };
2742
2743 armnn::TensorInfo kernelTensorInfo({ 1, 2, 3, 3}, ArmnnType);
2744 std::vector<float> kernelNoQuantizedValues =
2745 {
2746 1, 2, 3,
2747 4, 5, 6,
2748 7, 8, 9,
2749
2750 1, 2, 3,
2751 4, 5, 6,
2752 7, 8, 9
2753 };
2754
2755 // Since the dilation rate is 3 this will dilate the kernel to be like 7x7,
2756 // therefore the output will be 2x4x4: (I−K+2P)/S +1 => (10-7 +0)/1 +1
2757 armnn::TensorInfo outputTensorInfo({ 1, 2, 4, 4}, ArmnnType);
2758 std::vector<float> outputExpectedNoQuantizedValues =
2759 {
2760 6., 5., 5., 5.,
2761 6., 5., 5., 5.,
2762 6., 5., 5., 5.,
2763 3., 2., 2., 2.,
2764
2765 6., 5., 5., 5.,
2766 6., 5., 5., 5.,
2767 6., 5., 5., 5.,
2768 3., 2., 2., 2.
2769 };
2770
2771 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2772 workloadFactory,
2773 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002774 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002775 inputNoQuantizedValues,
2776 inputTensorInfo,
2777 kernelNoQuantizedValues,
2778 kernelTensorInfo,
2779 outputExpectedNoQuantizedValues,
2780 outputTensorInfo,
2781 3,
2782 3,
2783 layout,
2784 biasEnabled);
2785}
2786
2787template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2788LayerTestResult<T, 4> DepthwiseConvolution2dMult4Test(
2789 armnn::IWorkloadFactory& workloadFactory,
2790 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002791 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002792 bool biasEnabled,
2793 const armnn::DataLayout layout)
2794{
2795 armnn::TensorInfo inputTensorInfo({1, 2, 3, 3}, ArmnnType);
2796 std::vector<float> inputNoQuantizedValues =
2797 {
2798 10.0, 10.0, 10.0,
2799 10.0, 10.0, 10.0,
2800 10.0, 10.0, 10.0,
2801
2802 21.0, 22.0, 23.0,
2803 24.0, 25.0, 26.0,
2804 27.0, 28.0, 29.0
2805 };
2806
2807 armnn::TensorInfo kernelTensorInfo({ 4, 2, 2, 2}, ArmnnType);
2808
2809 std::vector<float> kernelNoQuantizedValues =
2810 {
2811 0.25f, 0.25f,
2812 0.25f, 0.25f,
2813
2814 0.25f, 0.25f,
2815 0.25f, 0.25f,
2816
2817 0.0f , 0.0f,
2818 0.0f , 0.1f,
2819
2820 0.0f , 0.0f,
2821 0.0f , 0.1f,
2822
2823 0.2f , 0.0f,
2824 0.0f , 0.0f,
2825
2826 0.2f , 0.0f,
2827 0.0f , 0.0f,
2828
2829 0.0f , 0.3f,
2830 0.0f , 0.0f,
2831
2832 0.0f , 0.3f,
2833 0.0f , 0.0f
2834 };
2835
2836 armnn::TensorInfo outputTensorInfo({ 1, 8, 2, 2}, ArmnnType);
2837 std::vector<float> outputExpectedNoQuantizedValues =
2838 {
2839 10.f, 10.f,
2840 10.f, 10.f,
2841
2842 1.f, 1.f,
2843 1.f, 1.f,
2844
2845 2.f, 2.f,
2846 2.f, 2.f,
2847
2848 3.f, 3.f,
2849 3.f, 3.f,
2850
2851 23.f, 24.f,
2852 26.f, 27.f,
2853
2854 2.5f, 2.6000001f,
2855 2.8f, 2.9f,
2856
2857 4.2000003f, 4.4f,
2858 4.8f, 5.f,
2859
2860 6.6000004f, 6.9f,
2861 7.5000005f, 7.8f
2862 };
2863
2864
2865 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2866 workloadFactory,
2867 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002868 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002869 inputNoQuantizedValues,
2870 inputTensorInfo,
2871 kernelNoQuantizedValues,
2872 kernelTensorInfo,
2873 outputExpectedNoQuantizedValues,
2874 outputTensorInfo,
2875 1,
2876 1,
2877 layout,
2878 biasEnabled);
2879}
2880
2881template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType, typename T>
2882LayerTestResult<T, 4> DepthwiseConvolution2dMult2Test(
2883 armnn::IWorkloadFactory& workloadFactory,
2884 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002885 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002886 bool biasEnabled,
2887 const armnn::DataLayout layout)
2888{
2889 armnn::TensorInfo inputTensorInfo({1, 2, 3, 3}, ArmnnType);
2890 std::vector<float> inputNoQuantizedValues =
2891 {
2892 10.0, 10.0, 10.0,
2893 10.0, 10.0, 10.0,
2894 10.0, 10.0, 10.0,
2895
2896 21.0, 22.0, 23.0,
2897 24.0, 25.0, 26.0,
2898 27.0, 28.0, 29.0
2899 };
2900
2901 armnn::TensorInfo kernelTensorInfo({ 2, 2, 2, 2}, ArmnnType);
2902
2903 std::vector<float> kernelNoQuantizedValues =
2904 {
2905 0.25f, 0.25f,
2906 0.25f, 0.25f,
2907
2908 0.2f , 0.0f,
2909 0.0f , 0.0f,
2910
2911 0.0f , 0.0f,
2912 0.0f , 0.1f,
2913
2914 0.0f , 0.3f,
2915 0.0f , 0.0f
2916
2917 };
2918
2919 armnn::TensorInfo outputTensorInfo({ 1, 4, 2, 2}, ArmnnType);
2920 std::vector<float> outputExpectedNoQuantizedValues =
2921 {
2922 10.f, 10.f,
2923 10.f, 10.f,
2924
2925 1.f, 1.f,
2926 1.f, 1.f,
2927
2928 4.2000003f, 4.4f,
2929 4.8f, 5.f,
2930
2931 6.6000004f, 6.9f,
2932 7.5000005f, 7.8f
2933 };
2934
2935
2936 return DepthwiseConvolution2d3x3DilationTestCommon<ArmnnType, ArmnnBType>(
2937 workloadFactory,
2938 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002939 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002940 inputNoQuantizedValues,
2941 inputTensorInfo,
2942 kernelNoQuantizedValues,
2943 kernelTensorInfo,
2944 outputExpectedNoQuantizedValues,
2945 outputTensorInfo,
2946 1,
2947 1,
2948 layout,
2949 biasEnabled);
2950}
2951
2952template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
2953LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
2954 armnn::IWorkloadFactory& workloadFactory,
2955 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2956 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002957 const armnn::ITensorHandleFactory& tensorHandleFactory,
2958 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002959 const armnnUtils::DataLayoutIndexed& layout)
2960{
2961 unsigned int inputHeight = 8;
2962 unsigned int inputWidth = 16;
2963 unsigned int inputChannels = 3;
2964 unsigned int inputNum = 5;
2965
2966 unsigned int kernelHeight = 3;
2967 unsigned int kernelWidth = 3;
2968 unsigned int channelMultiplier = 1;
2969
2970 unsigned int strideX = 2;
2971 unsigned int strideY = 3;
2972 unsigned int padX = 1;
2973 unsigned int padY = 1;
2974
2975 unsigned int outputNum = inputNum;
2976 unsigned int outputChannels = inputChannels * channelMultiplier;
2977 unsigned int outputHeight = (inputHeight + 2 * padY - kernelHeight + strideY) / strideY;
2978 unsigned int outputWidth = (inputWidth + 2 * padX - kernelWidth + strideX) / strideX;
2979
2980 armnn::TensorInfo inputTensorInfo;
2981 armnn::TensorInfo outputTensorInfo;
2982 armnn::TensorInfo kernelDesc;
2983 armnn::TensorInfo biasDesc;
2984
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002985 std::vector<unsigned int> inputShape;
2986 std::vector<unsigned int> outputShape;
2987 std::vector<unsigned int> kernelShape{ channelMultiplier, inputChannels, kernelHeight, kernelWidth };
2988 std::vector<unsigned int> biasShape{ outputChannels };
2989 switch (layout.GetDataLayout())
2990 {
2991 case armnn::DataLayout::NCHW:
2992 inputShape = { inputNum, inputChannels, inputHeight, inputWidth };
2993 outputShape = { outputNum, outputChannels, outputHeight, outputWidth };
2994 break;
2995 case armnn::DataLayout ::NHWC:
2996 inputShape = { inputNum, inputHeight, inputWidth, inputChannels };
2997 outputShape = { outputNum, outputHeight, outputWidth, outputChannels };
2998 break;
2999 default:
3000 throw armnn::InvalidArgumentException("unknown data layout ["
3001 + std::to_string(static_cast<int>(layout.GetDataLayout())) + "]");
3002 }
3003
3004 float inputsQScale = armnn::IsQuantizedType<T>() ? 1.0f : 0;
3005 float outputQScale = armnn::IsQuantizedType<T>() ? 2.0f : 0;
3006 int32_t qOffset = 0;
3007
3008 inputTensorInfo = armnn::TensorInfo(4, inputShape.data(), ArmnnType, inputsQScale, qOffset);
3009 outputTensorInfo = armnn::TensorInfo(4, outputShape.data(), ArmnnType, outputQScale, qOffset);
3010 kernelDesc = armnn::TensorInfo(4, kernelShape.data(), ArmnnType, inputsQScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01003011 biasDesc = armnn::TensorInfo(1, biasShape.data(), armnn::GetBiasDataType(ArmnnType), inputsQScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003012
Sadik Armagan483c8112021-06-01 09:24:52 +01003013 auto input = MakeRandomTensor<T>(inputTensorInfo, 124908, 0.0f, 255.0f);
3014 auto kernel = MakeRandomTensor<T>(kernelDesc, 891234, 0.0f, 255.0f);
3015 auto bias = MakeRandomTensor<typename FullyConnectedBiasTypeForInputType<T>::Type>(biasDesc, 1028, 0.0f, 255.0f);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003016
Sadik Armagan483c8112021-06-01 09:24:52 +01003017 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
3018 std::vector<T> expectedOutput(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01003019
3020 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
3021 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
3022
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003023 armnn::DepthwiseConvolution2dQueueDescriptor data;
3024 armnn::WorkloadInfo info;
James Conroy1f58f032021-04-27 17:13:27 +01003025 armnn::ScopedTensorHandle weightsTensor(kernelDesc);
3026 armnn::ScopedTensorHandle biasTensor(biasDesc);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003027
Sadik Armagan483c8112021-06-01 09:24:52 +01003028 AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
3029 AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003030
3031 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
3032 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
3033 data.m_Weight = &weightsTensor;
3034 data.m_Bias = &biasTensor;
3035 data.m_Parameters.m_StrideX = strideX;
3036 data.m_Parameters.m_StrideY = strideY;
3037 data.m_Parameters.m_PadLeft = padX;
3038 data.m_Parameters.m_PadRight = padX;
3039 data.m_Parameters.m_PadTop = padY;
3040 data.m_Parameters.m_PadBottom = padY;
3041 data.m_Parameters.m_BiasEnabled = true;
3042 data.m_Parameters.m_DataLayout = layout.GetDataLayout();
Keith Davisf500d6c2020-08-31 08:32:55 +01003043
3044 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
3045 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo);
3046
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003047 armnn::DepthwiseConvolution2dQueueDescriptor refData = data;
3048 armnn::WorkloadInfo refInfo = info;
3049 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
3050 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
3051
3052 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(data, info);
3053 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateDepthwiseConvolution2d(refData, refInfo);
3054
3055 outputHandleRef->Allocate();
3056 inputHandleRef->Allocate();
3057
3058 inputHandle->Allocate();
3059 outputHandle->Allocate();
3060
Sadik Armagan483c8112021-06-01 09:24:52 +01003061 CopyDataToITensorHandle(inputHandle.get(), input.data());
3062 CopyDataToITensorHandle(inputHandleRef.get(), input.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003063
3064 ExecuteWorkload(*workload, memoryManager);
3065
3066 workloadRef->PostAllocationConfigure();
3067 workloadRef->Execute();
3068
Sadik Armagan483c8112021-06-01 09:24:52 +01003069 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
3070 CopyDataFromITensorHandle(expectedOutput.data(), outputHandleRef.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003071
Sadik Armagan483c8112021-06-01 09:24:52 +01003072 return LayerTestResult<T, 4>(actualOutput,
3073 expectedOutput,
3074 outputHandle->GetShape(),
3075 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003076}
3077
3078//
3079// Explicit template specializations
3080//
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003081template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3082Convolution2d3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3083 armnn::IWorkloadFactory&,
3084 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003085 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003086 bool,
3087 armnn::DataLayout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003088
3089template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3090Convolution2d3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3091 armnn::IWorkloadFactory&,
3092 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003093 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003094 bool,
3095 armnn::DataLayout);
3096
Sadik Armagan303980c2020-04-17 12:45:14 +01003097template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3098Convolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3099 armnn::IWorkloadFactory&,
3100 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003101 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003102 bool,
3103 armnn::DataLayout);
3104
Derek Lambertif90c56d2020-01-10 17:14:08 +00003105template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3106Convolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003107 armnn::IWorkloadFactory&,
3108 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003109 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003110 bool,
3111 armnn::DataLayout);
3112
Derek Lambertif90c56d2020-01-10 17:14:08 +00003113template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3114Convolution2d3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003115 armnn::IWorkloadFactory&,
3116 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003117 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003118 bool,
3119 armnn::DataLayout);
3120
3121template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3122Convolution2d2x3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3123 armnn::IWorkloadFactory&,
3124 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003125 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003126 bool,
3127 armnn::DataLayout);
3128
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003129template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3130Convolution2d2x3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3131 armnn::IWorkloadFactory&,
3132 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003133 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003134 bool,
3135 armnn::DataLayout);
3136
Sadik Armagan303980c2020-04-17 12:45:14 +01003137template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3138Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3139 armnn::IWorkloadFactory&,
3140 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003141 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003142 bool,
3143 armnn::DataLayout);
3144
Derek Lambertif90c56d2020-01-10 17:14:08 +00003145template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3146Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003147 armnn::IWorkloadFactory&,
3148 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003149 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003150 bool,
3151 armnn::DataLayout);
3152
Derek Lambertif90c56d2020-01-10 17:14:08 +00003153template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3154Convolution2d2x3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003155 armnn::IWorkloadFactory&,
3156 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003157 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003158 bool,
3159 armnn::DataLayout);
3160
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003161template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3162Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3163 armnn::IWorkloadFactory &workloadFactory,
3164 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003165 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003166 bool biasEnabled,
3167 const armnn::DataLayout layout);
3168
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003169template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3170Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3171 armnn::IWorkloadFactory &workloadFactory,
3172 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003173 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003174 bool biasEnabled,
3175 const armnn::DataLayout layout);
3176
Sadik Armagan303980c2020-04-17 12:45:14 +01003177template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3178Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3179 armnn::IWorkloadFactory &workloadFactory,
3180 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003181 const armnn::ITensorHandleFactory& tensorHandleFactory,
Sadik Armagan303980c2020-04-17 12:45:14 +01003182 bool biasEnabled,
3183 const armnn::DataLayout layout);
3184
Derek Lambertif90c56d2020-01-10 17:14:08 +00003185template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3186Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003187 armnn::IWorkloadFactory &workloadFactory,
3188 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003189 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003190 bool biasEnabled,
3191 const armnn::DataLayout layout);
3192
Derek Lambertif90c56d2020-01-10 17:14:08 +00003193template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3194Convolution2d2x2Dilation2x2Padding2x2Stride3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003195 armnn::IWorkloadFactory &workloadFactory,
3196 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003197 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003198 bool biasEnabled,
3199 const armnn::DataLayout layout);
3200
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003201template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3202DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3203 armnn::IWorkloadFactory&,
3204 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003205 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003206 bool,
3207 armnn::DataLayout);
3208
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003209template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3210DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3211 armnn::IWorkloadFactory&,
3212 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003213 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003214 bool,
3215 armnn::DataLayout);
3216
Sadik Armagan303980c2020-04-17 12:45:14 +01003217template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3218DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3219 armnn::IWorkloadFactory&,
3220 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003221 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003222 bool,
3223 armnn::DataLayout);
3224
Derek Lambertif90c56d2020-01-10 17:14:08 +00003225template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3226DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003227 armnn::IWorkloadFactory&,
3228 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003229 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003230 bool,
3231 armnn::DataLayout);
3232
Derek Lambertif90c56d2020-01-10 17:14:08 +00003233template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3234DepthwiseConvolution2d3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003235 armnn::IWorkloadFactory&,
3236 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003237 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003238 bool,
3239 armnn::DataLayout);
3240
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003241template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3242DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3243 armnn::IWorkloadFactory&,
3244 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003245 const armnn::ITensorHandleFactory&,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003246 bool,
3247 armnn::DataLayout);
3248
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003249template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3250DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::Float32, armnn::DataType::Float32>(
3251 armnn::IWorkloadFactory&,
3252 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003253 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003254 bool,
3255 armnn::DataLayout);
3256
Sadik Armagan303980c2020-04-17 12:45:14 +01003257template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmS8>, 4>
3258DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
3259 armnn::IWorkloadFactory&,
3260 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003261 const armnn::ITensorHandleFactory&,
Sadik Armagan303980c2020-04-17 12:45:14 +01003262 bool,
3263 armnn::DataLayout);
3264
Derek Lambertif90c56d2020-01-10 17:14:08 +00003265template LayerTestResult<armnn::ResolveType<armnn::DataType::QAsymmU8>, 4>
3266DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003267 armnn::IWorkloadFactory&,
3268 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003269 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003270 bool,
3271 armnn::DataLayout);
3272
Derek Lambertif90c56d2020-01-10 17:14:08 +00003273template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 4>
3274DepthwiseConvolution2d2x3x3Dilation3x3Test<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003275 armnn::IWorkloadFactory&,
3276 const armnn::IBackendInternal::IMemoryManagerSharedPtr&,
Keith Davisf500d6c2020-08-31 08:32:55 +01003277 const armnn::ITensorHandleFactory&,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003278 bool,
3279 armnn::DataLayout);
3280
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003281template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3282DepthwiseConvolution2dMult4Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3283 armnn::IWorkloadFactory &workloadFactory,
3284 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003285 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003286 bool biasEnabled,
3287 const armnn::DataLayout layout);
3288
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003289template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3290DepthwiseConvolution2dMult4Test<armnn::DataType::Float32, armnn::DataType::Float32>(
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 const armnn::DataLayout layout);
3296
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003297template LayerTestResult<armnn::ResolveType<armnn::DataType::BFloat16>, 4>
3298DepthwiseConvolution2dMult2Test<armnn::DataType::BFloat16, armnn::DataType::BFloat16>(
3299 armnn::IWorkloadFactory &workloadFactory,
3300 const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003301 const armnn::ITensorHandleFactory& tensorHandleFactory,
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00003302 bool biasEnabled,
3303 const armnn::DataLayout layout);
3304
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003305template LayerTestResult<armnn::ResolveType<armnn::DataType::Float32>, 4>
3306DepthwiseConvolution2dMult2Test<armnn::DataType::Float32, armnn::DataType::Float32>(
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//
3314// Implementation functions
3315//
3316
3317LayerTestResult<float, 4> SimpleConvolution2d3x5Test(
3318 armnn::IWorkloadFactory& workloadFactory,
3319 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003320 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003321 bool biasEnabled,
3322 const armnn::DataLayout layout)
3323{
3324 return SimpleConvolution2d3x5TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003325 workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003326}
3327
3328LayerTestResult<uint8_t, 4> SimpleConvolution2d3x5Uint8Test(
3329 armnn::IWorkloadFactory& workloadFactory,
3330 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003331 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003332 bool biasEnabled,
3333 const armnn::DataLayout layout)
3334{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003335 return SimpleConvolution2d3x5TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003336 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003337}
3338
3339LayerTestResult<float, 4> SimpleConvolution2d3x3Test(
3340 armnn::IWorkloadFactory& workloadFactory,
3341 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003342 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003343 bool biasEnabled,
3344 const armnn::DataLayout layout)
3345{
3346 return SimpleConvolution2d3x3TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003347 workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003348}
3349
3350LayerTestResult<float, 4> SimpleConvolution2d3x3NhwcTest(
3351 armnn::IWorkloadFactory& workloadFactory,
3352 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003353 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003354 bool biasEnabled)
3355{
3356 return SimpleConvolution2d3x3NhwcTestCommon<armnn::DataType::Float32>(
3357 workloadFactory,
3358 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003359 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003360 0.f,
3361 0,
3362 biasEnabled,
3363 armnn::DataLayout::NHWC);
3364}
3365
3366LayerTestResult<float, 4> SimpleConvolution2d3x3Stride2x2Test(
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 bool biasEnabled,
3371 const armnn::DataLayout layout)
3372{
3373 return SimpleConvolution2d3x3Stride2x2TestCommon<armnn::DataType::Float32>(
3374 workloadFactory,
3375 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003376 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003377 0.f,
3378 0,
3379 biasEnabled,
3380 layout);
3381}
3382
3383LayerTestResult<uint8_t, 4> SimpleConvolution2d3x3Uint8Test(
3384 armnn::IWorkloadFactory& workloadFactory,
3385 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003386 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003387 bool biasEnabled,
3388 const armnn::DataLayout layout)
3389{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003390 return SimpleConvolution2d3x3TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003391 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003392}
3393
3394LayerTestResult<int16_t, 4> SimpleConvolution2d3x5QSymm16Test(
3395 armnn::IWorkloadFactory& workloadFactory,
3396 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003397 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003398 bool biasEnabled,
3399 const armnn::DataLayout layout)
3400{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003401 return SimpleConvolution2d3x5TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003402 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003403}
3404
3405LayerTestResult<int16_t, 4> SimpleConvolution2d3x3QSymm16Test(
3406 armnn::IWorkloadFactory& workloadFactory,
3407 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003408 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003409 bool biasEnabled,
3410 const armnn::DataLayout layout)
3411{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003412 return SimpleConvolution2d3x3TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003413 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003414}
3415
3416LayerTestResult<float, 4> Convolution2dAsymmetricPaddingTest(
3417 armnn::IWorkloadFactory& workloadFactory,
3418 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003419 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003420 armnn::DataLayout layout)
3421{
3422 return SimpleConvolution2dAsymmetricPaddingTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003423 workloadFactory, memoryManager, tensorHandleFactory, layout, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003424}
3425
3426LayerTestResult<float, 4> Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTest(
3427 armnn::IWorkloadFactory& workloadFactory,
3428 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003429 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003430 armnn::DataLayout layout)
3431{
3432 return Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTestCommon
3433 <armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003434 workloadFactory, memoryManager, tensorHandleFactory, layout, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003435}
3436
3437LayerTestResult<float, 4> Convolution1dTest(
3438 armnn::IWorkloadFactory& workloadFactory,
3439 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003440 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003441 bool biasEnabled)
3442{
3443 return Convolution1dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003444 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003445}
3446
3447LayerTestResult<uint8_t, 4> Convolution1dUint8Test(
3448 armnn::IWorkloadFactory& workloadFactory,
3449 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003450 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003451 bool biasEnabled)
3452{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003453 return Convolution1dTestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003454 workloadFactory, memoryManager, tensorHandleFactory, 0.1f, 128, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003455}
3456
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003457LayerTestResult<uint8_t, 4> Convolution2dPerAxisQuantTest(
3458 armnn::IWorkloadFactory& workloadFactory,
3459 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003460 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003461 const armnn::DataLayout layout)
3462{
3463 using namespace armnn;
3464
Derek Lambertif90c56d2020-01-10 17:14:08 +00003465 const DataType inputType = DataType::QAsymmU8;
Derek Lambertid466a542020-01-22 15:37:29 +00003466 const DataType kernelType = DataType::QSymmS8;
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003467 const DataType biasType = DataType::Signed32;
3468
3469 TensorInfo inputInfo ({ 1, 3, 1, 2 }, inputType, 0.5f, 128);
3470 TensorInfo outputInfo({ 1, 3, 1, 3 }, inputType, 1.0f, 128);
3471
3472 const std::vector<float> quantScales{ 0.5f, 0.75f, 1.0f };
3473 constexpr unsigned int quantDimension = 0;
3474
3475 TensorInfo kernelInfo({ 3, 1, 1, 2 }, kernelType, quantScales, quantDimension);
3476
3477 const std::vector<float> biasQuantScales{ 0.25f, 0.375f, 0.5f };
3478 TensorInfo biasInfo({ 3 }, biasType, biasQuantScales, quantDimension);
3479
3480 std::vector<uint8_t> inputData =
3481 {
3482 138, 108, 138, 108, 138, 108
3483 };
3484
3485 std::vector<int8_t> kernelData =
3486 {
3487 1, 2, 1, 2, 1, 2
3488 };
3489
3490 std::vector<int32_t> biasData =
3491 {
3492 4, 4, 4
3493 };
3494
3495 std::vector<uint8_t> expectedOutputData =
3496 {
3497 121, 118, 115, 121, 118, 115, 121, 118, 115
3498 };
3499
3500 if (layout == DataLayout::NCHW)
3501 {
3502 PermuteTensorNhwcToNchw(inputInfo, inputData);
3503 PermuteTensorNhwcToNchw(kernelInfo, kernelData);
3504 PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
3505 }
3506
Sadik Armagan483c8112021-06-01 09:24:52 +01003507 std::vector<uint8_t> actualOutput(outputInfo.GetNumElements());
3508
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003509 Convolution2dDescriptor descriptor;
3510 descriptor.m_StrideX = 1;
3511 descriptor.m_StrideY = 1;
3512 descriptor.m_PadLeft = 0;
3513 descriptor.m_PadRight = 0;
3514 descriptor.m_PadTop = 0;
3515 descriptor.m_PadBottom = 0;
3516 descriptor.m_BiasEnabled = true;
3517 descriptor.m_DataLayout = layout;
3518
Keith Davisf500d6c2020-08-31 08:32:55 +01003519 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
3520 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
3521
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003522 WorkloadInfo workloadInfo;
James Conroy1f58f032021-04-27 17:13:27 +01003523 ScopedTensorHandle weightTensor(kernelInfo);
3524 ScopedTensorHandle biasTensor(biasInfo);
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003525
3526 AllocateAndCopyDataToITensorHandle(&weightTensor, kernelData.data());
3527 AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
3528
3529 Convolution2dQueueDescriptor queueDescriptor;
3530 queueDescriptor.m_Parameters = descriptor;
3531 queueDescriptor.m_Weight = &weightTensor;
3532 queueDescriptor.m_Bias = &biasTensor;
3533
3534 AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
3535 AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
3536
3537 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConvolution2d(queueDescriptor, workloadInfo);
3538 inputHandle->Allocate();
3539 outputHandle->Allocate();
3540
3541 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
3542
3543 ExecuteWorkload(*workload, memoryManager);
3544
Sadik Armagan483c8112021-06-01 09:24:52 +01003545 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003546
Sadik Armagan483c8112021-06-01 09:24:52 +01003547 return LayerTestResult<uint8_t, 4>(actualOutput,
3548 expectedOutputData,
3549 outputHandle->GetShape(),
3550 outputInfo.GetShape());
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +00003551}
3552
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003553LayerTestResult<float,4> CompareConvolution2dTest(
3554 armnn::IWorkloadFactory& workloadFactory,
3555 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003556 armnn::IWorkloadFactory& refWorkloadFactory,
3557 const armnn::ITensorHandleFactory& tensorHandleFactory,
3558 const armnn::ITensorHandleFactory& refTensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003559{
3560 return CompareConvolution2dTestImpl<armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003561 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003562}
3563
3564LayerTestResult<float, 4> DepthwiseConvolution2dTest(
3565 armnn::IWorkloadFactory& workloadFactory,
3566 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003567 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003568 bool biasEnabled,
3569 const armnn::DataLayout layout)
3570{
3571 return DepthwiseConvolution2dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003572 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003573}
3574
3575LayerTestResult<float, 4> DepthwiseConvolution2dDepthNhwcTest(
3576 armnn::IWorkloadFactory& workloadFactory,
3577 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003578 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003579 bool biasEnabled)
3580{
3581 return DepthwiseConvolution2dNhwcTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003582 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003583}
3584
3585LayerTestResult<float, 4> DepthwiseConvolution2dDepthMul1Test(
3586 armnn::IWorkloadFactory& workloadFactory,
3587 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003588 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003589 bool biasEnabled,
3590 const armnn::DataLayout layout)
3591{
3592 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003593 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003594}
3595
3596LayerTestResult<float, 4> DepthwiseConvolution2dDepthMul64Test(
3597 armnn::IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003598 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3599 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003600{
3601 armnn::TensorInfo inputTensorInfo({ 1, 1, 2, 2 }, armnn::DataType::Float32);
Sadik Armagan483c8112021-06-01 09:24:52 +01003602 std::vector<float> input = { 1.f, 2.f, 3.f, 4.f };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003603
3604 std::vector<float> kernelData;
3605 std::vector<float> singleDepthKernel{ 1.f, -1.f, -1.f, 1.f };
3606 for (unsigned int i = 0; i < 64; ++i)
3607 {
3608 kernelData.insert(kernelData.end(), singleDepthKernel.begin(), singleDepthKernel.end());
3609 }
3610 armnn::TensorInfo kernelTensorInfo({ 64, 1, 2, 2 }, armnn::DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003611
3612 std::vector<float> expectedOutputData(64, 0.f);
3613 armnn::TensorInfo outputTensorInfo({ 1, 64, 1, 1 }, armnn::DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003614
3615 return DepthwiseConvolution2dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
3616 workloadFactory,
3617 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003618 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003619 input,
Sadik Armagan483c8112021-06-01 09:24:52 +01003620 kernelData,
3621 std::vector<float>(),
3622 expectedOutputData,
3623 inputTensorInfo.GetShape(),
3624 kernelTensorInfo.GetShape(),
3625 outputTensorInfo.GetShape(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003626 0.f,
3627 0,
3628 armnn::DataLayout::NCHW);
3629}
3630
3631LayerTestResult<float, 4> DepthwiseConvolution2dAsymmetricTest(
3632 armnn::IWorkloadFactory& workloadFactory,
3633 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003634 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003635 bool biasEnabled,
3636 const armnn::DataLayout layout)
3637{
3638 return DepthwiseConvolution2dAsymmetricTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003639 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003640}
3641
3642LayerTestResult<uint8_t, 4> DepthwiseConvolution2dUint8Test(
3643 armnn::IWorkloadFactory& workloadFactory,
3644 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003645 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003646 bool biasEnabled,
3647 const armnn::DataLayout layout)
3648{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003649 return DepthwiseConvolution2dTestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003650 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003651}
3652
3653LayerTestResult<uint8_t, 4> DepthwiseConvolution2dDepthMul1Uint8Test(
3654 armnn::IWorkloadFactory& workloadFactory,
3655 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003656 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003657 bool biasEnabled,
3658 const armnn::DataLayout layout)
3659{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003660 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003661 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003662}
3663
3664LayerTestResult<float, 4> SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTest(
3665 armnn::IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003666 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3667 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003668{
3669 return SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
3670 workloadFactory,
3671 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003672 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003673 0.f,
3674 0,
3675 false);
3676}
3677
3678LayerTestResult<int16_t, 4> DepthwiseConvolution2dInt16Test(
3679 armnn::IWorkloadFactory& workloadFactory,
3680 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003681 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003682 bool biasEnabled,
3683 const armnn::DataLayout layout)
3684{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003685 return DepthwiseConvolution2dTestImpl<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003686 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003687}
3688
3689LayerTestResult<int16_t, 4> DepthwiseConvolution2dDepthMul1Int16Test(
3690 armnn::IWorkloadFactory& workloadFactory,
3691 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003692 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003693 bool biasEnabled,
3694 const armnn::DataLayout layout)
3695{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003696 return DepthwiseConvolution2dDepthMul1TestImpl<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003697 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, 50, biasEnabled, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003698}
3699
Teresa Charlind8df0262019-11-11 12:28:15 +00003700LayerTestResult<uint8_t, 4> DepthwiseConvolution2dPerAxisQuantTest(
3701 armnn::IWorkloadFactory& workloadFactory,
3702 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003703 const armnn::ITensorHandleFactory& tensorHandleFactory,
Teresa Charlind8df0262019-11-11 12:28:15 +00003704 const armnn::DataLayout layout)
3705{
3706 using namespace armnn;
3707
Derek Lambertif90c56d2020-01-10 17:14:08 +00003708 const DataType inputType = DataType::QAsymmU8;
Derek Lambertid466a542020-01-22 15:37:29 +00003709 const DataType kernelType = DataType::QSymmS8;
Teresa Charlind8df0262019-11-11 12:28:15 +00003710 const DataType biasType = DataType::Signed32;
3711
3712 TensorInfo inputInfo ({ 1, 3, 3, 2 }, inputType, 0.5f, 128); // N H W C
3713 TensorInfo outputInfo({ 1, 2, 2, 4 }, inputType, 1.0f, 128); // N H W C
3714
3715 const std::vector<float> quantScales{ 1.0f, 0.5f, 1.0f, 0.5f };
3716 const unsigned int quantDimension = 0;
3717 TensorInfo kernelInfo({ 2, 2, 2, 2 }, kernelType, quantScales, quantDimension); // M I H W
3718
3719 const std::vector<float> biasQuantScales{ 0.5f, 0.25f, 0.5f, 0.25f };
3720 constexpr unsigned int biasQuantDimension = 0;
3721 TensorInfo biasInfo({ 4 }, biasType, biasQuantScales, biasQuantDimension);
3722
3723 std::vector<uint8_t> inputData =
3724 {
3725 129, 130,
3726 129, 130,
3727 129, 130,
3728 129, 130,
3729 129, 130,
3730 129, 130,
3731 129, 130,
3732 129, 130,
3733 129, 130
3734 };
3735
3736 std::vector<int8_t> kernelData =
3737 {
3738 1, 1, 1, 1,
3739 1, 1, 1, 1,
3740 1, 1, 1, 1,
3741 1, 1, 1, 1
3742 };
3743
3744 std::vector<int32_t> biasData =
3745 {
3746 4, 4, 4, 4
3747 };
3748
3749 std::vector<uint8_t> expectedOutputData =
3750 {
3751 132, 130, 134, 131,
3752 132, 130, 134, 131,
3753 132, 130, 134, 131,
3754 132, 130, 134, 131
3755 };
3756
3757 if (layout == DataLayout::NCHW)
3758 {
3759 PermuteTensorNhwcToNchw(inputInfo, inputData);
3760 PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
3761 }
3762
Sadik Armagan483c8112021-06-01 09:24:52 +01003763 std::vector<uint8_t> actualOutput(outputInfo.GetNumElements());
3764
Teresa Charlind8df0262019-11-11 12:28:15 +00003765 DepthwiseConvolution2dDescriptor descriptor;
3766 descriptor.m_StrideX = 1;
3767 descriptor.m_StrideY = 1;
3768 descriptor.m_PadLeft = 0;
3769 descriptor.m_PadRight = 0;
3770 descriptor.m_PadTop = 0;
3771 descriptor.m_PadBottom = 0;
3772 descriptor.m_DilationX = 1;
3773 descriptor.m_DilationY = 1;
3774 descriptor.m_BiasEnabled = true;
3775 descriptor.m_DataLayout = layout;
3776
Keith Davisf500d6c2020-08-31 08:32:55 +01003777 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
3778 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
Teresa Charlind8df0262019-11-11 12:28:15 +00003779
3780 WorkloadInfo workloadInfo;
James Conroy1f58f032021-04-27 17:13:27 +01003781 ScopedTensorHandle weightTensor(kernelInfo);
3782 ScopedTensorHandle biasTensor(biasInfo);
Teresa Charlind8df0262019-11-11 12:28:15 +00003783
3784 AllocateAndCopyDataToITensorHandle(&weightTensor, kernelData.data());
3785 AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
3786
3787 DepthwiseConvolution2dQueueDescriptor queueDescriptor;
3788 queueDescriptor.m_Parameters = descriptor;
3789 queueDescriptor.m_Weight = &weightTensor;
3790 queueDescriptor.m_Bias = &biasTensor;
3791
3792 AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
3793 AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
3794
3795 std::unique_ptr<IWorkload> workload = workloadFactory.CreateDepthwiseConvolution2d(queueDescriptor, workloadInfo);
3796 inputHandle->Allocate();
3797 outputHandle->Allocate();
3798
3799 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
3800
3801 ExecuteWorkload(*workload, memoryManager);
3802
3803 LayerTestResult<uint8_t, 4> ret(outputInfo);
3804
Sadik Armagan483c8112021-06-01 09:24:52 +01003805 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Teresa Charlind8df0262019-11-11 12:28:15 +00003806
Sadik Armagan483c8112021-06-01 09:24:52 +01003807 return LayerTestResult<uint8_t, 4>(actualOutput,
3808 expectedOutputData,
3809 outputHandle->GetShape(),
3810 outputInfo.GetShape());
Teresa Charlind8df0262019-11-11 12:28:15 +00003811}
3812
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003813LayerTestResult<float, 4> CompareDepthwiseConvolution2dFloatTest(
3814 armnn::IWorkloadFactory& workloadFactory,
3815 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3816 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003817 const armnn::ITensorHandleFactory& tensorHandleFactory,
3818 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003819 const armnn::DataLayout layout)
3820{
3821 return CompareDepthwiseConvolution2dTestImpl<armnn::DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003822 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003823}
3824
3825LayerTestResult<uint8_t, 4> CompareDepthwiseConvolution2dUint8Test(
3826 armnn::IWorkloadFactory& workloadFactory,
3827 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3828 armnn::IWorkloadFactory& refWorkloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003829 const armnn::ITensorHandleFactory& tensorHandleFactory,
3830 const armnn::ITensorHandleFactory& refTensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003831 const armnn::DataLayout layout)
3832{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003833 return CompareDepthwiseConvolution2dTestImpl<armnn::DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003834 workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, layout);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003835}