2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // See LICENSE file in the project root for full license information.
5 #include "LayerTests.hpp"
7 #include "test/TensorHelpers.hpp"
8 #include "TensorCopyUtils.hpp"
11 #include <boost/test/unit_test.hpp>
12 #include <boost/assert.hpp>
14 #include "armnn/LayerSupport.hpp"
16 #include "backends/CpuTensorHandle.hpp"
17 #include "backends/WorkloadFactory.hpp"
19 #ifdef ARMCOMPUTECL_ENABLED
20 #include "backends/ClTensorHandle.hpp"
21 #include "backends/ArmComputeTensorUtils.hpp"
25 #include <boost/cast.hpp>
27 #include "WorkloadTestUtils.hpp"
28 #include "Conv2dTestImpl.hpp"
29 #include "BatchNormTestImpl.hpp"
30 #include "ActivationTestImpl.hpp"
31 #include "Pooling2dTestImpl.hpp"
32 #include "ReshapeTestImpl.hpp"
33 #include "FullyConnectedTestImpl.hpp"
34 #include "SplitterTestImpl.hpp"
35 #include "SoftmaxTestImpl.hpp"
36 #include "NormTestImpl.hpp"
37 #include "PermuteTestImpl.hpp"
38 #include "LstmTestImpl.hpp"
39 #include "ConvertFp16ToFp32TestImpl.hpp"
40 #include "ConvertFp32ToFp16TestImpl.hpp"
42 // 3-channel 16x8 image used as common input data for a number of Conv2d tests.
43 static std::vector<float> ConvInput3x8x16({
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.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,
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.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,
48 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,
49 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,
50 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,
51 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,
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 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
70 // 2-channel bias used by a number of Conv2d tests.
71 static std::vector<float> Bias2({0, 2});
73 // Helper function that returns either Bias2 or an empty vector depending on whether bias is enabled.
75 boost::multi_array<T, 1> GetBias2(bool biasEnabled, float qScale, int32_t qOffset)
79 armnn::TensorInfo biasDesc({static_cast<unsigned int>(Bias2.size())}, armnn::GetDataType<T>());
80 boost::multi_array<T, 1> bias = MakeTensor<T, 1>(biasDesc, QuantizedVector<T>(qScale, qOffset, Bias2));
85 return boost::multi_array<T, 1>();
90 LayerTestResult<T, 4> SimpleConvolution2d3x5TestCommon(armnn::IWorkloadFactory& workloadFactory,
95 // Use common single-batch 3-channel 16x8 image.
96 armnn::TensorInfo inputDesc({1, 3, 8, 16}, armnn::GetDataType<T>());
97 boost::multi_array<T, 4> input = MakeTensor<T, 4>(inputDesc, QuantizedVector<T>(qScale, qOffset, ConvInput3x8x16));
99 // Use a 2-element batch with 3-channel 3x5 kernels.
100 armnn::TensorInfo kernelDesc({2, 3, 5, 3}, armnn::GetDataType<T>());
101 boost::multi_array<T, 4> kernel = MakeTensor<T, 4>(kernelDesc, std::vector<T>(
102 QuantizedVector<T>(qScale, qOffset, {
141 // Expected output is 2 batch elements of a 1-channel 14x4 image.
142 armnn::TensorInfo outputDesc({1, 2, 4, 14}, armnn::GetDataType<T>());
143 boost::multi_array<T, 4> expectedOutput = MakeTensor<T, 4>(outputDesc, std::vector<T>(
144 QuantizedVector<T>(qScale, qOffset, {
145 -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
146 -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
147 -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f,
148 -23.5f, -23.5f, -23.5f,
149 -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f, -23.5f,
150 -23.5f, -23.5f, -23.5f,
152 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
154 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
155 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
158 return SimpleConvolution2dTestImpl<T>(workloadFactory,
161 GetBias2<typename FullyConnectedBiasTypeForInputType<T>::Type>(biasEnabled, qScale, qOffset),
168 LayerTestResult<T, 4> SimpleConvolution2d3x3TestCommon(armnn::IWorkloadFactory& workloadFactory,
173 // Use a 3x3 kernel, which exercises ArmCompute's direct convolution path.
175 // Use common single-batch 3-channel 16x8 image.
176 armnn::TensorInfo inputDesc({1, 3, 8, 16}, armnn::GetDataType<T>());
177 boost::multi_array<T, 4> input = MakeTensor<T, 4>(inputDesc, QuantizedVector<T>(qScale, qOffset, ConvInput3x8x16));
179 // Use a 2-element batch of 3-channel 3x3 kernels.
180 armnn::TensorInfo kernelDesc({2, 3, 3, 3}, armnn::GetDataType<T>());
181 boost::multi_array<T, 4> kernel = MakeTensor<T, 4>(kernelDesc, std::vector<T>(
182 QuantizedVector<T>(qScale, qOffset, {
209 // Expected output is 1 batch of a 2-channel 14x6 image.
210 armnn::TensorInfo outputDesc({1, 2, 6, 14}, armnn::GetDataType<T>());
211 boost::multi_array<T, 4> expectedOutput = MakeTensor<T, 4>(outputDesc, std::vector<T>(
212 QuantizedVector<T>(qScale, qOffset, {
213 -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15,
214 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
215 -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,
216 -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,
217 -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,
218 -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,
220 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
228 return SimpleConvolution2dTestImpl<T>(workloadFactory,
231 GetBias2<typename FullyConnectedBiasTypeForInputType<T>::Type>(biasEnabled, qScale, qOffset),
237 LayerTestResult<float, 4> SimpleConvolution2d3x5Test(armnn::IWorkloadFactory& workloadFactory,
240 return SimpleConvolution2d3x5TestCommon<float>(workloadFactory, 0.f, 0, biasEnabled);
243 LayerTestResult<uint8_t, 4> SimpleConvolution2d3x5Uint8Test(armnn::IWorkloadFactory& workloadFactory,
246 return SimpleConvolution2d3x5TestCommon<uint8_t>(workloadFactory, 0.5f, 50, biasEnabled);
249 LayerTestResult<float, 4> SimpleConvolution2d3x3Test(armnn::IWorkloadFactory& workloadFactory,
252 return SimpleConvolution2d3x3TestCommon<float>(workloadFactory, 0.f, 0, biasEnabled);
255 LayerTestResult<uint8_t, 4> SimpleConvolution2d3x3Uint8Test(armnn::IWorkloadFactory& workloadFactory,
258 return SimpleConvolution2d3x3TestCommon<uint8_t>(workloadFactory, 0.5f, 50, biasEnabled);
262 LayerTestResult<T, 4> Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTestCommon(
263 armnn::IWorkloadFactory& workloadFactory,
267 // Use a single-batch 1-channel 3x3 image as input.
268 armnn::TensorInfo inputDesc({1, 1, 3, 3}, armnn::GetDataType<T>());
269 boost::multi_array<T, 4> input = MakeTensor<T, 4>(inputDesc, std::vector<T>(
270 QuantizedVector<T>(qScale, qOffset, {
276 // Use 1 batch of a 1-channel 2x2 kernel.
277 armnn::TensorInfo kernelDesc({1, 1, 2, 2}, armnn::GetDataType<T>());
278 boost::multi_array<T, 4> kernel = MakeTensor<T, 4>(kernelDesc, std::vector<T>(
279 QuantizedVector<T>(qScale, qOffset, {
284 // Expected output is 1 batch of a 1-channel 6x8 image.
285 // Manually calculated like this:
286 //[-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 ..]
287 //[-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 ..]
288 //[-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 ..]
289 //[-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 ..]
290 //[-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 ..]
291 //[-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 ..]
292 //[..... ..... ..... ..... ; ..... ..... ..... ..... ; ..... ..... ..... ..... ; ..... ..... ..... ..... ..]
293 armnn::TensorInfo outputDesc({1, 1, 8, 6}, armnn::GetDataType<T>());
294 boost::multi_array<T, 4> expectedOutput = MakeTensor<T, 4>(outputDesc, std::vector<T>(
295 QuantizedVector<T>(qScale, qOffset, {
297 -242, -594, -934, -372, 0, 0,
298 -495, -1190, -1850, -725, 0, 0,
299 -538, -1256, -1916, -748, 0, 0,
300 -273, -626, -946, -363, 0, 0,
306 return SimpleConvolution2dTestImpl<T>(workloadFactory,
309 GetBias2<typename FullyConnectedBiasTypeForInputType<T>::Type>(false, qScale, qOffset),
316 4); // Padding bottom.
320 LayerTestResult<T, 4> SimpleConvolution2dAsymmetricPaddingTestCommon(armnn::IWorkloadFactory& workloadFactory,
324 // Use a single-batch 1-channel 5x5 image as input.
325 armnn::TensorInfo inputDesc({ 1, 1, 5, 5 }, armnn::GetDataType<T>());
326 boost::multi_array<T, 4> input = MakeTensor<T, 4>(inputDesc, std::vector<T>(
327 QuantizedVector<T>(qScale, qOffset, {
335 // Use 1 batch of a 1-channel 4x4 kernel.
336 armnn::TensorInfo kernelDesc({ 1, 1, 4, 4 }, armnn::GetDataType<T>());
337 boost::multi_array<T, 4> kernel = MakeTensor<T, 4>(kernelDesc, std::vector<T>(
338 QuantizedVector<T>(qScale, qOffset, {
345 // Expected output is 1 batch of a 1-channel 5x5 image.
346 armnn::TensorInfo outputDesc({ 1, 1, 5, 5 }, armnn::GetDataType<T>());
347 std::vector<T> myVec(outputDesc.GetNumElements(), 0);
348 boost::multi_array<T, 4> expectedOutput = MakeTensor<T, 4>(outputDesc, std::vector<T>(
349 QuantizedVector<T>(qScale, qOffset, {
350 -7140, -10580, -13940, -9300, -5230,
351 -9590, -14120, -18520, -12290, -6860,
352 -9980, -14560, -18960, -12560, -7000,
353 -7518, -10904, -14144, -9318, -5152,
354 -5032, -7256, -9376, -6142, -3368,
357 return SimpleConvolution2dTestImpl<T>(workloadFactory,
360 GetBias2<typename FullyConnectedBiasTypeForInputType<T>::Type>(false, qScale, qOffset),
367 2); // Padding bottom.
371 LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestCommon(armnn::IWorkloadFactory& workloadFactory,
376 // Use a single-batch 2-channel 5x5 image as input.
377 armnn::TensorInfo inputTensorInfo({ 1, 2, 5, 5 }, armnn::GetDataType<T>());
378 auto input = MakeTensor<T, 4>(inputTensorInfo, std::vector<T>(
379 QuantizedVector<T>(inputTensorInfo.GetQuantizationScale(), inputTensorInfo.GetQuantizationOffset(), {
393 // Use a depth multiplier of 1 on a 2-channel 4x4 kernel.
394 armnn::TensorInfo kernelTensorInfo({ 1, 2, 4, 4 }, armnn::GetDataType<T>());
395 auto kernel = MakeTensor<T, 4>(kernelTensorInfo, std::vector<T>(
396 QuantizedVector<T>(kernelTensorInfo.GetQuantizationScale(), kernelTensorInfo.GetQuantizationOffset(), {
408 // Expected output is 1 batch of a 2-channel 5x5 image.
409 // Calculated using the python tensorflow library with strideX=1, strideY=1.
410 armnn::TensorInfo outputTensorInfo({ 1, 2, 5, 5 }, armnn::GetDataType<T>());
411 boost::multi_array<T, 4> expectedOutput = MakeTensor<T, 4>(outputTensorInfo, std::vector<T>(
412 QuantizedVector<T>(outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(), {
413 1062, 1580, 1850, 1530, 1117,
414 2140, 3108, 3500, 2842, 2042,
415 3580, 5068, 5460, 4342, 3062,
416 3618, 5072, 5390, 4248, 2971,
417 3074, 4282, 4510, 3533, 2457,
418 1550, 2284, 2362, 1955, 1428,
419 2910, 4206, 4342, 3528, 2536,
420 3390, 4886, 5022, 4068, 2916,
421 3566, 5056, 5182, 4133, 2922,
422 3100, 4352, 4452, 3517, 2465
425 return DepthwiseConvolution2dAsymmetricTestImpl<T>(workloadFactory,
428 GetBias2<typename FullyConnectedBiasTypeForInputType<T>::Type>(biasEnabled, qScale, qOffset),
435 2, // Padding bottom.
440 LayerTestResult<float, 4>
441 Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTest(armnn::IWorkloadFactory& workloadFactory)
443 return Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTestCommon<float>(workloadFactory, 0.0f, 0);
446 LayerTestResult<float, 4> Convolution2dAsymmetricPaddingTest(armnn::IWorkloadFactory& workloadFactory)
448 return SimpleConvolution2dAsymmetricPaddingTestCommon<float>(workloadFactory, 0.0f, 0);
451 LayerTestResult<float, 4> DepthwiseConvolution2dTest(armnn::IWorkloadFactory& workloadFactory,
454 return DepthwiseConvolution2dTestImpl<float, float>(workloadFactory, 0.0f, 0, biasEnabled);
457 LayerTestResult<float, 4> DepthwiseConvolution2dDepthMul1Test(armnn::IWorkloadFactory& workloadFactory,
460 return DepthwiseConvolution2dDepthMul1TestImpl<float, float>(workloadFactory, 0.0f, 0, biasEnabled);
463 LayerTestResult<float, 4> DepthwiseConvolution2dAsymmetricTest(armnn::IWorkloadFactory& workloadFactory,
466 return DepthwiseConvolution2dAsymmetricTestCommon<float>(workloadFactory, 0.0f, 0, biasEnabled);
469 LayerTestResult<uint8_t, 4> DepthwiseConvolution2dUint8Test(armnn::IWorkloadFactory& workloadFactory,
472 return DepthwiseConvolution2dTestImpl<uint8_t, int32_t>(workloadFactory, 0.5f, 50, biasEnabled);
475 LayerTestResult<uint8_t, 4> DepthwiseConvolution2dDepthMul1Uint8Test(armnn::IWorkloadFactory& workloadFactory,
478 return DepthwiseConvolution2dDepthMul1TestImpl<uint8_t, int32_t>(workloadFactory, 0.5f, 50, biasEnabled);
481 LayerTestResult<float, 4> Convolution1dTest(armnn::IWorkloadFactory& workloadFactory, bool biasEnabled)
483 return Convolution1dTestImpl<float>(workloadFactory, 0.0f, 0, biasEnabled);
486 LayerTestResult<uint8_t, 4> Convolution1dUint8Test(armnn::IWorkloadFactory& workloadFactory, bool biasEnabled)
488 return Convolution1dTestImpl<uint8_t>(workloadFactory, 0.1f, 128, biasEnabled);
491 LayerTestResult<float,4> CompareConvolution2dTest(armnn::IWorkloadFactory& workloadFactory,
492 armnn::IWorkloadFactory& refWorkloadFactory)
494 return CompareConvolution2dTestImpl<float>(workloadFactory, refWorkloadFactory);
498 LayerTestResult<T,4> CompareDepthwiseConvolution2dTest(armnn::IWorkloadFactory& workloadFactory,
499 armnn::IWorkloadFactory& refWorkloadFactory)
501 return CompareDepthwiseConvolution2dTestImpl<T>(workloadFactory, refWorkloadFactory);
504 template LayerTestResult<float, 4> CompareDepthwiseConvolution2dTest<float>(
505 armnn::IWorkloadFactory&, armnn::IWorkloadFactory&);
506 template LayerTestResult<uint8_t, 4> CompareDepthwiseConvolution2dTest<uint8_t>(
507 armnn::IWorkloadFactory&, armnn::IWorkloadFactory&);
509 LayerTestResult<float,4> SimpleNormalizationAcrossTest(armnn::IWorkloadFactory& workloadFactory)
511 auto normMethod = armnn::NormalizationAlgorithmMethod::LocalBrightness;
512 auto normChannel = armnn::NormalizationAlgorithmChannel::Across;
513 return SimpleNormalizationTestImpl(workloadFactory, normChannel, normMethod);
516 LayerTestResult<float,4> SimpleNormalizationWithinTest(armnn::IWorkloadFactory& workloadFactory)
518 auto normMethod = armnn::NormalizationAlgorithmMethod::LocalBrightness;
519 auto normChannel = armnn::NormalizationAlgorithmChannel::Within;
520 return SimpleNormalizationTestImpl(workloadFactory, normChannel, normMethod);
523 LayerTestResult<float,2> SimpleSoftmaxTest(armnn::IWorkloadFactory& workloadFactory, float beta)
525 return SimpleSoftmaxTestImpl<float>(workloadFactory, beta);
528 LayerTestResult<uint8_t,2> SimpleSoftmaxUint8Test(armnn::IWorkloadFactory& workloadFactory, float beta)
530 return SimpleSoftmaxTestImpl<uint8_t>(workloadFactory, beta);
533 LayerTestResult<float,4> CompareNormalizationTest(armnn::IWorkloadFactory& workloadFactory,
534 armnn::IWorkloadFactory& refWorkloadFactory,
535 armnn::NormalizationAlgorithmChannel normChannel,
536 armnn::NormalizationAlgorithmMethod normMethod)
538 return CompareNormalizationTestImpl(workloadFactory, refWorkloadFactory, normChannel, normMethod);
541 LayerTestResult<float,2> CompareSoftmaxTest(armnn::IWorkloadFactory& workloadFactory,
542 armnn::IWorkloadFactory& refWorkloadFactory,
545 return CompareSoftmaxTestImpl<float>(workloadFactory, refWorkloadFactory, beta);
548 LayerTestResult<uint8_t,2> CompareSoftmaxUint8Test(armnn::IWorkloadFactory& workloadFactory,
549 armnn::IWorkloadFactory& refWorkloadFactory,
552 return CompareSoftmaxTestImpl<uint8_t>(workloadFactory, refWorkloadFactory, beta);
555 std::vector<LayerTestResult<float,3>> SplitterTest(armnn::IWorkloadFactory& workloadFactory)
557 return SplitterTestCommon<float>(workloadFactory);
560 std::vector<LayerTestResult<uint8_t,3>> SplitterUint8Test(armnn::IWorkloadFactory& workloadFactory)
562 return SplitterTestCommon<uint8_t>(workloadFactory, 1.0f, 0);
565 LayerTestResult<float, 3> CopyViaSplitterTest(armnn::IWorkloadFactory& workloadFactory)
567 return CopyViaSplitterTestImpl<float>(workloadFactory, 0.0f, 0);
570 LayerTestResult<uint8_t, 3> CopyViaSplitterUint8Test(armnn::IWorkloadFactory& workloadFactory)
572 return CopyViaSplitterTestImpl<uint8_t>(workloadFactory, 1.0f, 0);
575 LayerTestResult<float, 2> LstmLayerFloat32WithCifgWithPeepholeNoProjectionTest(
576 armnn::IWorkloadFactory& workloadFactory)
578 armnn::TensorInfo inputDesc({ 2, 2 }, armnn::GetDataType<float>());
579 boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
580 { 2., 3., 3., 4. }));
582 armnn::TensorInfo outputDesc({ 2, 4 }, armnn::GetDataType<float>());
583 boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
584 {-0.36444446f, -0.00352185f, 0.12886585f, -0.05163646f,
585 -0.42734814f, -0.00478661f, 0.13455015f, -0.03560682f}));
586 return LstmLayerWithCifgWithPeepholeNoProjectionTestImpl(workloadFactory, input, expectedOutput);
589 LayerTestResult<float, 2> LstmLayerFloat32NoCifgWithPeepholeWithProjectionTest(
590 armnn::IWorkloadFactory& workloadFactory)
592 armnn::TensorInfo inputDesc({ 2, 5 }, armnn::GetDataType<float>());
593 boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
594 {0.787926f, 0.151646f, 0.071352f, 0.118426f, 0.458058f,
595 0.295743f, 0.544053f, 0.690064f, 0.858138f, 0.497181f}));
597 armnn::TensorInfo outputDesc({ 2, 16 }, armnn::GetDataType<float>());
598 boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
599 {-0.00396806f, 0.029352f, -0.00279226f, 0.0159977f, -0.00835576f,
600 -0.0211779f, 0.0283512f, -0.0114597f, 0.00907307f, -0.0244004f,
601 -0.0152191f, -0.0259063f, 0.00914318f, 0.00415118f, 0.017147f,
602 0.0134203f, -0.013869f, 0.0287268f, -0.00334693f, 0.00733398f, -0.0287926f,
603 -0.0186926f, 0.0193662f, -0.0115437f, 0.00422612f, -0.0345232f,
604 0.00223253f, -0.00957321f, 0.0210624f, 0.013331f, 0.0150954f,
606 return LstmLayerFloat32NoCifgWithPeepholeWithProjectionTestImpl(workloadFactory, input, expectedOutput);
609 LayerTestResult<float, 2> LstmLayerFloat32NoCifgNoPeepholeNoProjectionTest(armnn::IWorkloadFactory& workloadFactory)
611 armnn::TensorInfo inputDesc({2, 2}, armnn::GetDataType<float>());
612 boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
616 armnn::TensorInfo outputDesc({2, 4}, armnn::GetDataType<float>());
617 boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
618 {{-0.02973187f, 0.1229473f, 0.20885126f, -0.15358765f,
619 -0.0185422f, 0.11281417f, 0.24466537f, -0.1826292f}}));
621 return LstmNoCifgNoPeepholeNoProjectionTestImpl(workloadFactory, input, expectedOutput);
624 LayerTestResult<float,3> MergerTest(armnn::IWorkloadFactory& workloadFactory)
626 unsigned int outputWidth = 3;
627 unsigned int outputHeight = 6;
628 unsigned int outputChannels = 3;
630 unsigned int inputWidth1 = 3;
631 unsigned int inputHeight1 = 6;
632 unsigned int inputChannels1 = 2;
634 unsigned int inputWidth2 = 3;
635 unsigned int inputHeight2 = 6;
636 unsigned int inputChannels2 = 1;
638 // Define the tensor descriptors.
639 armnn::TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, armnn::DataType::Float32);
640 armnn::TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, armnn::DataType::Float32);
641 armnn::TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, armnn::DataType::Float32);
643 LayerTestResult<float,3> ret(outputTensorInfo);
645 ret.outputExpected = MakeTensor<float, 3>(outputTensorInfo, std::vector<float>(
670 auto input1 = MakeTensor<float, 3>(inputTensorInfo1, std::vector<float>(
688 auto input2 = MakeTensor<float, 3>(inputTensorInfo2, std::vector<float>(
699 std::vector<unsigned int> wOrigin1 = {0, 0, 0}; //Extent of the window is defined by size of input[0].
700 armnn::MergerQueueDescriptor::ViewOrigin window1(wOrigin1);
702 std::vector<unsigned int> wOrigin2 = {2, 0, 0}; //Extent of the window is defined by size of input[1].
703 armnn::MergerQueueDescriptor::ViewOrigin window2(wOrigin2);
705 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
707 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
709 std::unique_ptr<armnn::ITensorHandle> inputHandle1 =
710 subTensorsSupported ?
711 workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
712 workloadFactory.CreateTensorHandle(inputTensorInfo1);
714 std::unique_ptr<armnn::ITensorHandle> inputHandle2 =
715 subTensorsSupported ?
716 workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
717 workloadFactory.CreateTensorHandle(inputTensorInfo2);
719 armnn::MergerQueueDescriptor data;
720 armnn::WorkloadInfo info;
721 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
722 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
723 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
725 data.m_ViewOrigins.push_back(window1);
726 data.m_ViewOrigins.push_back(window2);
728 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMerger(data, info);
730 inputHandle1->Allocate();
731 inputHandle2->Allocate();
732 outputHandle->Allocate();
734 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
735 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
737 workloadFactory.Finalize();
740 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
745 LayerTestResult<float,4> AdditionTest(armnn::IWorkloadFactory& workloadFactory)
747 unsigned int batchSize = 2;
748 unsigned int channels = 2;
749 unsigned int height = 2;
750 unsigned int width = 3;
752 armnn::TensorInfo inputTensorInfo1, inputTensorInfo2;
753 armnn::TensorInfo outputTensorInfo;
755 unsigned int shape[] = {batchSize, channels, height, width};
757 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
758 inputTensorInfo2 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
759 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
762 auto input1 = MakeTensor<float, 4>(inputTensorInfo1, std::vector<float>(
777 auto input2 = MakeTensor<float, 4>(inputTensorInfo2, std::vector<float>(
792 LayerTestResult<float,4> ret(outputTensorInfo);
793 ret.outputExpected = MakeTensor<float, 4>(outputTensorInfo, std::vector<float>(
808 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
809 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = workloadFactory.CreateTensorHandle(inputTensorInfo2);
810 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
812 armnn::AdditionQueueDescriptor data;
813 armnn::WorkloadInfo info;
814 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
815 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
816 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
818 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
820 inputHandle1->Allocate();
821 inputHandle2->Allocate();
822 outputHandle->Allocate();
824 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
825 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
827 workloadFactory.Finalize();
830 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
835 template <typename T>
836 LayerTestResult<T, 4> AdditionBroadcastTestImpl(armnn::IWorkloadFactory& workloadFactory,
840 armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({1, 3, 2, 1}, armnn::GetDataType<T>());
841 armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({1, 1, 2, 3}, armnn::GetDataType<T>());
842 armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 3}, armnn::GetDataType<T>());
844 if (armnn::IsQuantizedType<T>())
846 inputTensorInfo1.SetQuantizationScale(qScale);
847 inputTensorInfo1.SetQuantizationOffset(qOffset);
848 inputTensorInfo2.SetQuantizationScale(qScale);
849 inputTensorInfo2.SetQuantizationOffset(qOffset);
850 outputTensorInfo.SetQuantizationScale(qScale);
851 outputTensorInfo.SetQuantizationOffset(qOffset);
854 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(qScale, qOffset,
866 auto input2 = MakeTensor<T, 4>(inputTensorInfo2, QuantizedVector<T>(qScale, qOffset,
872 LayerTestResult<T,4> ret(outputTensorInfo);
873 ret.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset,
885 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
886 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = workloadFactory.CreateTensorHandle(inputTensorInfo2);
887 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
889 armnn::AdditionQueueDescriptor data;
890 armnn::WorkloadInfo info;
891 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
892 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
893 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
895 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
897 inputHandle1->Allocate();
898 inputHandle2->Allocate();
899 outputHandle->Allocate();
901 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
902 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
904 workloadFactory.Finalize();
907 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
912 template <typename T>
913 LayerTestResult<T, 4> AdditionBroadcast1ElementTestImpl(armnn::IWorkloadFactory& workloadFactory,
917 armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({1, 3, 2, 3}, armnn::GetDataType<T>());
918 armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({1, 1, 1, 1}, armnn::GetDataType<T>());
919 armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 3}, armnn::GetDataType<T>());
921 if (armnn::IsQuantizedType<T>())
923 inputTensorInfo1.SetQuantizationScale(qScale);
924 inputTensorInfo1.SetQuantizationOffset(qOffset);
925 inputTensorInfo2.SetQuantizationScale(qScale);
926 inputTensorInfo2.SetQuantizationOffset(qOffset);
927 outputTensorInfo.SetQuantizationScale(qScale);
928 outputTensorInfo.SetQuantizationOffset(qOffset);
931 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(qScale, qOffset,
941 auto input2 = MakeTensor<T, 4>(inputTensorInfo2, QuantizedVector<T>(qScale, qOffset,
946 LayerTestResult<T,4> ret(outputTensorInfo);
947 ret.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset,
957 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
958 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = workloadFactory.CreateTensorHandle(inputTensorInfo2);
959 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
961 armnn::AdditionQueueDescriptor data;
962 armnn::WorkloadInfo info;
963 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
964 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
965 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
967 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
969 inputHandle1->Allocate();
970 inputHandle2->Allocate();
971 outputHandle->Allocate();
973 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
974 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
976 workloadFactory.Finalize();
979 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
984 LayerTestResult<float, 4> AdditionBroadcastTest(armnn::IWorkloadFactory& workloadFactory)
986 return AdditionBroadcastTestImpl<float>(workloadFactory, 0.0f, 0);
989 LayerTestResult<uint8_t, 4> AdditionBroadcastUint8Test(armnn::IWorkloadFactory& workloadFactory)
991 return AdditionBroadcastTestImpl<uint8_t>(workloadFactory, 2.f, 0);
994 LayerTestResult<float, 4> AdditionBroadcast1ElementTest(armnn::IWorkloadFactory& workloadFactory)
996 return AdditionBroadcast1ElementTestImpl<float>(workloadFactory, 0.0f, 0);
999 LayerTestResult<uint8_t, 4> AdditionBroadcast1ElementUint8Test(armnn::IWorkloadFactory& workloadFactory)
1001 return AdditionBroadcast1ElementTestImpl<uint8_t>(workloadFactory, 0.1333333f, 128);
1004 LayerTestResult<float,4> CompareAdditionTest(armnn::IWorkloadFactory& workloadFactory,
1005 armnn::IWorkloadFactory& refWorkloadFactory)
1007 unsigned int batchSize = 4;
1008 unsigned int channels = 1;
1009 unsigned int height = 2;
1010 unsigned int width = 3;
1012 armnn::TensorInfo inputTensorInfo1, inputTensorInfo2;
1013 armnn::TensorInfo outputTensorInfo;
1015 unsigned int shape[] = {batchSize, channels, height, width};
1017 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1018 inputTensorInfo2 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1019 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1021 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 1232);
1022 auto input2 = MakeRandomTensor<float, 4>(inputTensorInfo2, 456);
1024 LayerTestResult<float,4> ret(outputTensorInfo);
1026 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
1027 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = workloadFactory.CreateTensorHandle(inputTensorInfo2);
1028 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1030 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo1);
1031 std::unique_ptr<armnn::ITensorHandle> inputHandle2Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo2);
1032 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
1034 armnn::AdditionQueueDescriptor data;
1035 armnn::WorkloadInfo info;
1036 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
1037 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
1038 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1040 armnn::AdditionQueueDescriptor refData = data;
1041 armnn::WorkloadInfo refInfo = info;
1042 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo1, inputHandle1Ref.get());
1043 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo2, inputHandle2Ref.get());
1044 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1046 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
1047 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateAddition(refData, refInfo);
1049 inputHandle1->Allocate();
1050 inputHandle2->Allocate();
1051 outputHandle->Allocate();
1052 inputHandle1Ref->Allocate();
1053 inputHandle2Ref->Allocate();
1054 outputHandleRef->Allocate();
1056 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
1057 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
1058 CopyDataToITensorHandle(inputHandle1Ref.get(), &input1[0][0][0][0]);
1059 CopyDataToITensorHandle(inputHandle2Ref.get(), &input2[0][0][0][0]);
1061 workloadFactory.Finalize();
1062 workload->Execute();
1063 refWorkloadFactory.Finalize();
1064 workloadRef->Execute();
1066 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
1067 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
1073 LayerTestResult<float,4> MultiplicationTestHelper(armnn::IWorkloadFactory& workloadFactory,
1074 const unsigned int shape0[4],
1075 const std::vector<float> & values0,
1076 const unsigned int shape1[4],
1077 const std::vector<float> & values1,
1078 const unsigned int outShape[4],
1079 const std::vector<float> & outValues)
1081 const size_t dimensionCount = 4;
1082 armnn::TensorInfo inputTensorInfo0{dimensionCount, shape0, armnn::DataType::Float32};
1083 armnn::TensorInfo inputTensorInfo1{dimensionCount, shape1, armnn::DataType::Float32};
1084 armnn::TensorInfo outputTensorInfo{dimensionCount, outShape, armnn::DataType::Float32};
1086 auto input0 = MakeTensor<float, 4>(inputTensorInfo0, values0);
1087 auto input1 = MakeTensor<float, 4>(inputTensorInfo1, values1);
1089 LayerTestResult<float,4> ret(outputTensorInfo);
1091 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
1092 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
1093 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1095 armnn::MultiplicationQueueDescriptor data;
1096 armnn::WorkloadInfo info;
1097 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
1098 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
1099 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1101 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
1103 inputHandle0->Allocate();
1104 inputHandle1->Allocate();
1105 outputHandle->Allocate();
1107 CopyDataToITensorHandle(inputHandle0.get(), &input0[0][0][0][0]);
1108 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
1110 workloadFactory.Finalize();
1111 workload->Execute();
1113 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
1115 ret.outputExpected = MakeTensor<float, 4>(outputTensorInfo, outValues);
1118 } // anonymous namespace
1121 LayerTestResult<float,4> MultiplicationTest(armnn::IWorkloadFactory& workloadFactory)
1123 const unsigned int width = 2;
1124 const unsigned int height = 2;
1125 const unsigned int channelCount = 2;
1126 const unsigned int batchSize = 2;
1128 unsigned int shape[] = { batchSize, channelCount, height, width };
1130 std::vector<float> input0({
1131 1, 1, 1, 1, 2, 2, 2, 2,
1132 3, 3, 3, 3, 4, 4, 4, 4 });
1134 std::vector<float> input1({
1135 2, 2, 2, 2, 3, 3, 3, 3,
1136 4, 4, 4, 4, 5, 5, 5, 5 });
1138 std::vector<float> output({
1139 2, 2, 2, 2, 6, 6, 6, 6,
1140 12, 12, 12, 12, 20, 20, 20, 20 });
1142 return MultiplicationTestHelper(workloadFactory,
1151 LayerTestResult<float, 4> MultiplicationBroadcast1ElementTest(armnn::IWorkloadFactory& workloadFactory)
1153 unsigned int shape0[] = { 1, 2, 2, 2 };
1154 std::vector<float> input0({ 1, 2, 3, 4, 5, 6, 7, 8});
1156 unsigned int shape1[] = { 1, 1, 1, 1 };
1157 std::vector<float> input1({ 2 });
1159 std::vector<float> output({ 2, 4, 6, 8, 10, 12, 14, 16});
1161 return MultiplicationTestHelper(workloadFactory,
1170 LayerTestResult<float, 4> MultiplicationBroadcast1DVectorTest(armnn::IWorkloadFactory& workloadFactory)
1172 unsigned int shape0[] = { 1, 3, 3, 2 };
1173 std::vector<float> input0({
1175 7, 8, 9, 10, 11, 12,
1176 13, 14, 15, 16, 17, 18});
1178 unsigned int shape1[] = { 1, 1, 1, 2 };
1179 std::vector<float> input1({ 1, 2 });
1181 std::vector<float> output({
1183 7, 16, 9, 20, 11, 24,
1184 13, 28, 15, 32, 17, 36});
1186 return MultiplicationTestHelper(workloadFactory,
1195 LayerTestResult<float,4> CompareMultiplicationTest(armnn::IWorkloadFactory& workloadFactory,
1196 armnn::IWorkloadFactory& refWorkloadFactory)
1198 const unsigned int width = 16;
1199 const unsigned int height = 32;
1200 const unsigned int channelCount = 2;
1201 const unsigned int batchSize = 5;
1203 armnn::TensorInfo inputTensorInfo0;
1204 armnn::TensorInfo inputTensorInfo1;
1205 armnn::TensorInfo outputTensorInfo;
1207 constexpr unsigned int shape[] = { batchSize, channelCount, height, width };
1209 inputTensorInfo0 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1210 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1211 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1213 LayerTestResult<float,4> comparisonResult(outputTensorInfo);
1215 auto input0 = MakeRandomTensor<float, 4>(inputTensorInfo0, 803506992);
1216 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 54902257);
1218 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
1219 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
1220 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1222 std::unique_ptr<armnn::ITensorHandle> inputHandle0Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo0);
1223 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo1);
1224 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
1226 armnn::MultiplicationQueueDescriptor data;
1227 armnn::WorkloadInfo info;
1228 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
1229 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
1230 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1232 armnn::MultiplicationQueueDescriptor refData = data;
1233 armnn::WorkloadInfo refInfo = info;
1234 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo0, inputHandle0Ref.get());
1235 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo1, inputHandle1Ref.get());
1236 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1238 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
1239 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateMultiplication(refData, refInfo);
1241 inputHandle0->Allocate();
1242 inputHandle1->Allocate();
1243 outputHandle->Allocate();
1244 inputHandle0Ref->Allocate();
1245 inputHandle1Ref->Allocate();
1246 outputHandleRef->Allocate();
1248 CopyDataToITensorHandle(inputHandle0.get(), &input0[0][0][0][0]);
1249 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
1250 CopyDataToITensorHandle(inputHandle0Ref.get(), &input0[0][0][0][0]);
1251 CopyDataToITensorHandle(inputHandle1Ref.get(), &input1[0][0][0][0]);
1253 workloadFactory.Finalize();
1254 workload->Execute();
1255 refWorkloadFactory.Finalize();
1256 workloadRef->Execute();
1258 CopyDataFromITensorHandle(&comparisonResult.output[0][0][0][0], outputHandle.get());
1259 CopyDataFromITensorHandle(&comparisonResult.outputExpected[0][0][0][0], outputHandleRef.get());
1261 return comparisonResult;
1264 LayerTestResult<float,4> CompareBatchNormTest(armnn::IWorkloadFactory& workloadFactory,
1265 armnn::IWorkloadFactory& refWorkloadFactory)
1267 const unsigned int width = 2;
1268 const unsigned int height = 3;
1269 const unsigned int channels = 5;
1270 const unsigned int batchSize = 3;
1272 armnn::TensorInfo inputTensorInfo;
1273 armnn::TensorInfo outputTensorInfo;
1274 armnn::TensorInfo tensorInfo;
1276 constexpr unsigned int shape[] = {batchSize, channels, height, width};
1277 constexpr unsigned int tensorShape[] = {channels};
1279 inputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1280 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
1281 tensorInfo = armnn::TensorInfo(1, tensorShape, armnn::DataType::Float32);
1283 auto input = MakeRandomTensor<float, 4>(inputTensorInfo, 21312);
1285 auto mean = MakeRandomTensor<float, 1>(tensorInfo, 123);
1286 auto variance = MakeRandomTensor<float, 1>(tensorInfo, 234, 0.0f);
1287 auto beta = MakeRandomTensor<float, 1>(tensorInfo, 123);
1288 auto gamma = MakeRandomTensor<float, 1>(tensorInfo, 345);
1290 LayerTestResult<float,4> ret(outputTensorInfo);
1292 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
1293 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1295 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refWorkloadFactory.CreateTensorHandle(inputTensorInfo);
1296 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
1298 armnn::BatchNormalizationQueueDescriptor data;
1299 armnn::WorkloadInfo info;
1300 armnn::ScopedCpuTensorHandle meanTensor(tensorInfo);
1301 armnn::ScopedCpuTensorHandle varianceTensor(tensorInfo);
1302 armnn::ScopedCpuTensorHandle betaTensor(tensorInfo);
1303 armnn::ScopedCpuTensorHandle gammaTensor(tensorInfo);
1305 AllocateAndCopyDataToITensorHandle(&meanTensor, &mean[0]);
1306 AllocateAndCopyDataToITensorHandle(&varianceTensor, &variance[0]);
1307 AllocateAndCopyDataToITensorHandle(&betaTensor, &beta[0]);
1308 AllocateAndCopyDataToITensorHandle(&gammaTensor, &gamma[0]);
1310 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1311 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1312 data.m_Mean = &meanTensor;
1313 data.m_Variance = &varianceTensor;
1314 data.m_Beta = &betaTensor;
1315 data.m_Gamma = &gammaTensor;
1316 data.m_Parameters.m_Eps = 0.01f;
1318 armnn::BatchNormalizationQueueDescriptor refData = data;
1319 armnn::WorkloadInfo refInfo = info;
1320 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
1321 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1323 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateBatchNormalization(data, info);
1324 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateBatchNormalization(refData, refInfo);
1326 inputHandle->Allocate();
1327 outputHandle->Allocate();
1328 inputHandleRef->Allocate();
1329 outputHandleRef->Allocate();
1331 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
1332 CopyDataToITensorHandle(inputHandleRef.get(), &input[0][0][0][0]);
1334 workloadFactory.Finalize();
1335 workload->Execute();
1336 refWorkloadFactory.Finalize();
1337 workloadRef->Execute();
1339 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
1340 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
1345 template<typename T>
1346 void PermuteTensorData(
1347 armnn::IWorkloadFactory& workloadFactory,
1348 const armnn::PermutationVector& mappings,
1349 armnn::TensorInfo & inputTensorInfo,
1350 const T * inputData,
1351 std::vector<T>& outputData)
1353 BOOST_ASSERT_MSG(inputData != nullptr, "inputData must not be null");
1354 if (inputData == nullptr)
1356 // Nullptr is an error in the test. By returning without doing the concatenation
1357 // I expect the caller to fail the test. It still makes sense to report this as
1358 // an assert for Debug builds.
1362 armnn::TensorInfo outputTensorInfo = armnnUtils::Permuted(inputTensorInfo, mappings);
1364 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
1365 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1367 armnn::PermuteQueueDescriptor queueDescriptor;
1368 queueDescriptor.m_Parameters = armnn::PermuteDescriptor{mappings};
1369 armnn::WorkloadInfo workloadInfo;
1370 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get());
1371 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
1373 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePermute(queueDescriptor, workloadInfo);
1375 inputHandle->Allocate();
1376 outputHandle->Allocate();
1378 CopyDataToITensorHandle(inputHandle.get(), inputData);
1380 workload->Execute();
1382 outputData.resize(outputTensorInfo.GetNumElements());
1383 CopyDataFromITensorHandle(&outputData[0], outputHandle.get());
1384 inputTensorInfo = outputTensorInfo;
1387 armnn::OriginsDescriptor CreateMergerDescriptorForConcatenation(
1388 const std::vector<armnn::TensorInfo> & inputTensorInfos,
1389 unsigned int concatDim)
1391 std::vector<armnn::TensorShape> shapes;
1392 shapes.reserve(inputTensorInfos.size());
1393 for (const armnn::TensorInfo& it: inputTensorInfos)
1395 shapes.push_back(it.GetShape());
1398 return armnn::CreateMergerDescriptorForConcatenation(shapes.begin(),
1404 // Concatenation is only supported for N and C dimensions for NCHW. In case of
1405 // <4 dimensions we need to make sure that the concat dimensions are at least
1406 // the 3rd slowest iterating one.
1409 bool NeedPermuteForConcat(
1410 const std::vector<armnn::TensorInfo> & inputTensorInfos,
1411 unsigned int concatDim)
1413 // See note above. Additionally we expect the input shapes to have the
1414 // same number of dimensions.
1415 unsigned int nDimensions = 0;
1417 // Determine the number of dimensions as well as sanity check them
1418 // agains test implementation issues.
1419 for (auto && tensorInfo : inputTensorInfos)
1423 nDimensions = tensorInfo.GetShape().GetNumDimensions();
1427 BOOST_ASSERT_MSG(nDimensions == tensorInfo.GetShape().GetNumDimensions(),
1428 "Input shapes must have the same number of dimensions");
1432 return (nDimensions-concatDim) < 3;
1435 armnn::TensorShape ExpandTensorShapeTo3dForPermute(const armnn::TensorShape & inputShape)
1437 unsigned int numDims = inputShape.GetNumDimensions();
1440 // Nothing to do if the inputShape has at least 3 dimensions.
1444 std::vector<unsigned int> newDims(size_t(3), 1u);
1445 unsigned int expandedBy = 3 - numDims;
1446 for (unsigned int i=0; i<numDims; ++i)
1448 newDims[expandedBy+i] = inputShape[i];
1450 return armnn::TensorShape(3u, &newDims[0]);
1453 void Generate3dPermuteVectorForConcat(
1454 unsigned int numDimensions,
1455 unsigned int & concatDim,
1456 std::pair<armnn::PermutationVector, armnn::PermutationVector> & permutations)
1458 BOOST_ASSERT_MSG(numDimensions <= 3,
1459 "Only dimensions 1,2 and 3 are supported by this helper");
1461 unsigned int expandedBy = 3 - numDimensions;
1462 unsigned int expandedConcatAxis = concatDim + expandedBy;
1464 if (expandedConcatAxis == 2)
1467 armnn::PermutationVector forwardPermutation({1, 2, 0});
1468 armnn::PermutationVector reversePermutation({2, 0, 1});
1469 permutations = std::make_pair(forwardPermutation, reversePermutation);
1471 else if (expandedConcatAxis == 1)
1474 armnn::PermutationVector forwardPermutation({2, 0, 1});
1475 armnn::PermutationVector reversePermutation({1, 2, 0});
1476 permutations = std::make_pair(forwardPermutation, reversePermutation);
1480 BOOST_ASSERT(expandedConcatAxis == 0);
1486 // Permute the input tensors so we can do a supported concatenation.
1487 // Also treat lower than 3d tensors as 3d by adding dummy 1 dimensions
1488 // at the front. Finally this function tells what the output shape
1489 // of the permuted concatenated tensor is going to be.
1491 template <typename T>
1492 void PermuteInputsForConcat(
1493 armnn::IWorkloadFactory& workloadFactory,
1494 std::vector<armnn::TensorInfo> & inputTensorInfos,
1495 std::vector<T *> & inputData,
1496 std::vector<std::vector<T>> & inputDataStorage,
1497 armnn::PermutationVector & permuteVector,
1498 unsigned int & concatDim,
1499 armnn::TensorInfo & outputTensorInfo)
1501 BOOST_ASSERT_MSG(inputTensorInfos.size() > 1,
1502 "Expecting more than one tensor to be concatenated here");
1504 unsigned int numDims = 0;
1505 unsigned int nthInput = 0;
1506 const armnn::PermutationVector identity({0, 1, 2});
1508 std::pair<armnn::PermutationVector, armnn::PermutationVector> permutations =
1509 std::make_pair(identity, identity);
1511 inputDataStorage.resize(inputData.size());
1513 for (auto && tensorInfo : inputTensorInfos)
1517 numDims = tensorInfo.GetShape().GetNumDimensions();
1518 Generate3dPermuteVectorForConcat(numDims, concatDim, permutations);
1519 // Store the reverese permutation.
1520 permuteVector = permutations.second;
1521 BOOST_ASSERT_MSG(!permuteVector.IsEqual(identity),
1522 "Test logic error, we don't need permutation, so we shouldn't arrive here");
1526 BOOST_ASSERT_MSG(numDims == tensorInfo.GetShape().GetNumDimensions(),
1527 "All inputs must have the same number of dimensions");
1530 armnn::TensorInfo newTensorInfo = tensorInfo;
1531 newTensorInfo.SetShape(ExpandTensorShapeTo3dForPermute(tensorInfo.GetShape()));
1533 PermuteTensorData<T>(workloadFactory,
1536 inputData[nthInput],
1537 inputDataStorage[nthInput]);
1539 inputData[nthInput] = inputDataStorage[nthInput].data();
1540 inputTensorInfos[nthInput] = newTensorInfo;
1545 outputTensorInfo.SetShape(
1546 armnnUtils::Permuted(
1547 ExpandTensorShapeTo3dForPermute(outputTensorInfo.GetShape()),
1548 permutations.first));
1553 // This is the pair of PermuteInputsForConcat(...) which permutes back
1554 // the output of the concatenation so we can check it against an expected
1557 template <typename T>
1558 void PermuteOutputForConcat(
1559 armnn::IWorkloadFactory& workloadFactory,
1560 const armnn::TensorInfo & tensorInfo,
1561 const armnn::PermutationVector & permuteVector,
1562 std::unique_ptr<armnn::ITensorHandle> && inputDataHandle,
1565 BOOST_ASSERT_MSG(data != nullptr, "data must not be null");
1566 if (data == nullptr)
1568 // Nullptr is an error in the test. By returning without doing the permutation
1569 // I expect the caller to fail the test. It still makes sense to report this as
1570 // an assert for Debug builds.
1574 armnn::TensorInfo resultTensorInfo = tensorInfo;
1575 std::vector<T> inputData(tensorInfo.GetNumElements());
1576 std::vector<T> outputData;
1578 CopyDataFromITensorHandle(&inputData[0], inputDataHandle.get());
1580 PermuteTensorData<T>(workloadFactory,
1586 ::memcpy(data, &outputData[0], sizeof(T)*outputData.size());
1589 template <typename T>
1590 void Concatenate(armnn::IWorkloadFactory& workloadFactory,
1591 std::initializer_list<const armnn::TensorInfo> inputTensorInfosOrig,
1592 std::initializer_list<T *> inputsOrig,
1593 const armnn::TensorInfo& outputTensorInfoOrig,
1595 unsigned int concatDim)
1597 BOOST_ASSERT_MSG(output != nullptr, "output must not be null");
1598 if (output == nullptr)
1600 // Nullptr is an error in the test. By returning without doing the permutation
1601 // I expect the caller to fail the test. It still makes sense to report this as
1602 // an assert for Debug builds.
1606 armnn::MergerQueueDescriptor queueDescriptor;
1608 // Saves a copy of the parameters which we might need to change.
1609 std::vector<armnn::TensorInfo> inputTensorInfos(inputTensorInfosOrig.begin(), inputTensorInfosOrig.end());
1610 std::vector<T *> inputs = inputsOrig;
1611 armnn::TensorInfo outputTensorInfo = outputTensorInfoOrig;
1613 armnn::PermutationVector permuteVector{0, 1, 2};
1615 // Holds and automatically releases memory for the reshaped input data.
1616 std::vector<std::vector<T>> tmpInputDataStorage;
1618 const size_t inputCount = inputTensorInfos.size();
1620 bool needPermuteForConcat = NeedPermuteForConcat(inputTensorInfos, concatDim);
1622 if (needPermuteForConcat)
1625 // We need to permute the inputs, because concatenation along
1626 // the requested axis is not supported.
1628 PermuteInputsForConcat<T>(workloadFactory,
1631 tmpInputDataStorage,
1637 armnn::OriginsDescriptor viewsDescriptor = CreateMergerDescriptorForConcatenation(inputTensorInfos, concatDim);
1639 queueDescriptor.m_ViewOrigins.reserve(viewsDescriptor.GetNumViews());
1640 for (unsigned int i = 0; i < viewsDescriptor.GetNumViews(); ++i)
1642 queueDescriptor.m_ViewOrigins.emplace_back(std::vector<unsigned int>(viewsDescriptor.GetViewOrigin(i),
1643 viewsDescriptor.GetViewOrigin(i) + viewsDescriptor.GetNumDimensions()));
1646 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1648 std::vector<std::unique_ptr<armnn::ITensorHandle>> inputHandles;
1649 inputHandles.reserve(inputCount);
1651 const bool subTensorsSupported = workloadFactory.SupportsSubTensors();
1652 for (unsigned int i = 0; i < inputCount; ++i)
1654 const armnn::TensorInfo& inputTensorInfo = inputTensorInfos[i];
1656 std::unique_ptr<armnn::ITensorHandle> inputHandle = subTensorsSupported ?
1657 workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo.GetShape(),
1658 queueDescriptor.m_ViewOrigins[i].m_Origin.data())
1659 : workloadFactory.CreateTensorHandle(inputTensorInfo);
1661 inputHandles.emplace_back(std::move(inputHandle));
1664 armnn::WorkloadInfo workloadInfo;
1666 for (unsigned int i = 0; i < inputCount; ++i)
1668 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfos[i], inputHandles[i].get());
1671 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
1673 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMerger(queueDescriptor, workloadInfo);
1675 for (auto& inputHandle : inputHandles)
1677 inputHandle->Allocate();
1680 outputHandle->Allocate();
1682 unsigned int nextInputId = 0;
1683 for (auto& inputHandle : inputHandles)
1685 CopyDataToITensorHandle(inputHandle.get(), inputs[nextInputId]);
1689 workloadFactory.Finalize();
1690 workload->Execute();
1692 if (needPermuteForConcat)
1694 PermuteOutputForConcat<T>(workloadFactory,
1697 std::move(outputHandle),
1702 CopyDataFromITensorHandle(output, outputHandle.get());
1706 template <typename T>
1707 LayerTestResult<T, 1> Concatenation1dTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale, int32_t qOffset)
1709 armnn::TensorInfo inputTensorInfo({ 3 }, armnn::GetDataType<T>());
1711 auto input0 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, { 1.0f, 2.0f, 3.0f }));
1712 auto input1 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, { 4.0f, 5.0f, 6.0f }));
1713 auto input2 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, { 7.0f, 8.0f, 9.0f }));
1715 armnn::TensorInfo outputTensorInfo({ 9 }, armnn::GetDataType<T>());
1717 LayerTestResult<T, 1> result(outputTensorInfo);
1719 std::vector<T> output;
1720 output.resize(outputTensorInfo.GetNumElements());
1721 Concatenate<T>(workloadFactory,
1722 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
1723 { input0.data(), input1.data(), input2.data() },
1728 result.output = MakeTensor<T, 1>(outputTensorInfo, output);
1729 result.outputExpected = MakeTensor<T, 1>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1730 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
1736 LayerTestResult<float, 1> Concatenation1dTest(armnn::IWorkloadFactory& workloadFactory)
1738 return Concatenation1dTestImpl<float>(workloadFactory, 0.0f, 0);
1741 template <typename T>
1742 LayerTestResult<T, 2> Concatenation2dTestImpl(armnn::IWorkloadFactory& workloadFactory,
1743 const armnn::TensorInfo& outputTensorInfo,
1744 unsigned int dimension,
1746 const int32_t qOffset)
1748 armnn::TensorInfo inputTensorInfo({ 2, 3 }, armnn::GetDataType<T>());
1750 auto input0 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1755 10.0f, 11.0f, 12.0f,
1758 auto input1 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1763 13.0f, 14.0f, 15.0f,
1766 auto input2 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1771 16.0f, 17.0f, 18.0f,
1774 LayerTestResult<T, 2> result(outputTensorInfo);
1776 std::vector<T> output;
1777 output.resize(outputTensorInfo.GetNumElements());
1778 Concatenate<T>(workloadFactory,
1779 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
1780 { input0.data(), input1.data(), input2.data() },
1785 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
1789 template <typename T>
1790 LayerTestResult<T, 2> Concatenation2dDim0TestImpl(armnn::IWorkloadFactory& workloadFactory,
1791 float qScale, int32_t qOffset)
1793 armnn::TensorInfo outputTensorInfo({ 6, 3 }, armnn::GetDataType<T>());
1795 LayerTestResult<T, 2> result = Concatenation2dTestImpl<T>(workloadFactory, outputTensorInfo, 0, qScale, qOffset);
1796 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1801 10.0f, 11.0f, 12.0f,
1807 13.0f, 14.0f, 15.0f,
1813 16.0f, 17.0f, 18.0f,
1819 LayerTestResult<float, 2> Concatenation2dDim0Test(armnn::IWorkloadFactory& workloadFactory)
1821 return Concatenation2dDim0TestImpl<float>(workloadFactory, 0.0f, 0);
1824 template <typename T>
1825 LayerTestResult<T, 2> Concatenation2dDim1TestImpl(armnn::IWorkloadFactory& workloadFactory,
1826 float qScale, int32_t qOffset)
1828 armnn::TensorInfo outputTensorInfo({ 2, 9 }, armnn::GetDataType<T>());
1830 LayerTestResult<T, 2> result = Concatenation2dTestImpl<T>(workloadFactory, outputTensorInfo, 1, qScale, qOffset);
1831 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1833 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,
1836 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f
1842 LayerTestResult<float, 2> Concatenation2dDim1Test(armnn::IWorkloadFactory& workloadFactory)
1844 return Concatenation2dDim1TestImpl<float>(workloadFactory, 0.0f, 0);
1847 template <typename T>
1848 LayerTestResult<T, 2> Concatenation2dDim0DiffInputDimsTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
1851 armnn::TensorInfo input0TensorInfo({ 2, 3 }, armnn::GetDataType<T>());
1852 auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1857 10.0f, 11.0f, 12.0f,
1860 armnn::TensorInfo input1TensorInfo({ 3, 3 }, armnn::GetDataType<T>());
1861 auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1866 13.0f, 14.0f, 15.0f,
1872 armnn::TensorInfo input2TensorInfo({ 1, 3 }, armnn::GetDataType<T>());
1873 auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1875 16.0f, 17.0f, 18.0f,
1878 armnn::TensorInfo outputTensorInfo({ 6, 3 }, armnn::GetDataType<T>());
1879 LayerTestResult<T, 2> result(outputTensorInfo);
1881 std::vector<T> output;
1882 output.resize(outputTensorInfo.GetNumElements());
1883 Concatenate<T>(workloadFactory,
1884 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1885 { input0.data(), input1.data(), input2.data() },
1890 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
1891 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1896 10.0f, 11.0f, 12.0f,
1902 13.0f, 14.0f, 15.0f,
1908 16.0f, 17.0f, 18.0f,
1914 LayerTestResult<float, 2> Concatenation2dDim0DiffInputDimsTest(armnn::IWorkloadFactory& workloadFactory)
1916 return Concatenation2dDim0DiffInputDimsTestImpl<float>(workloadFactory, 0.0f, 0);
1919 template <typename T>
1920 LayerTestResult<T, 2> Concatenation2dDim1DiffInputDimsTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
1923 armnn::TensorInfo input0TensorInfo({ 2, 3 }, armnn::GetDataType<T>());
1924 auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1929 10.0f, 11.0f, 12.0f,
1932 armnn::TensorInfo input1TensorInfo({ 2, 5 }, armnn::GetDataType<T>());
1933 auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1935 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
1938 13.0f, 14.0f, 15.0f, 16.0f, 17.0f,
1941 armnn::TensorInfo input2TensorInfo({ 2, 1 }, armnn::GetDataType<T>());
1942 auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(qScale, qOffset, {
1950 armnn::TensorInfo outputTensorInfo({ 2, 9 }, armnn::GetDataType<T>());
1951 LayerTestResult<T, 2> result(outputTensorInfo);
1953 std::vector<T> output;
1954 output.resize(outputTensorInfo.GetNumElements());
1955 Concatenate<T>(workloadFactory,
1956 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1957 { input0.data(), input1.data(), input2.data() },
1962 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
1963 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1965 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,
1968 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f,
1974 LayerTestResult<float, 2> Concatenation2dDim1DiffInputDimsTest(armnn::IWorkloadFactory& workloadFactory)
1976 return Concatenation2dDim1DiffInputDimsTestImpl<float>(workloadFactory, 0.0f, 0);
1979 template <typename T>
1980 LayerTestResult<T, 3> Concatenation3dTestImpl(armnn::IWorkloadFactory& workloadFactory,
1981 const armnn::TensorInfo& outputTensorInfo,
1982 unsigned int dimension,
1986 armnn::TensorInfo inputTensorInfo({ 2, 3, 2 }, armnn::GetDataType<T>());
1988 auto input0 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
1989 // Batch 0, Channel 0
1992 // Batch 0, Channel 1
1995 // Batch 0, Channel 2
1998 // Batch 1, Channel 0
2001 // Batch 1, Channel 1
2004 // Batch 1, Channel 2
2008 auto input1 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2009 // Batch 0, Channel 0
2012 // Batch 0, Channel 1
2015 // Batch 0, Channel 2
2018 // Batch 1, Channel 0
2021 // Batch 1, Channel 1
2024 // Batch 1, Channel 2
2028 auto input2 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2029 // Batch 0, Channel 0
2032 // Batch 0, Channel 1
2035 // Batch 0, Channel 2
2038 // Batch 1, Channel 0
2041 // Batch 1, Channel 1
2044 // Batch 1, Channel 2
2048 LayerTestResult<T, 3> result(outputTensorInfo);
2050 std::vector<T> output;
2051 output.resize(outputTensorInfo.GetNumElements());
2052 Concatenate<T>(workloadFactory,
2053 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
2054 { input0.data(), input1.data(), input2.data() },
2059 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
2063 template <typename T>
2064 LayerTestResult<T, 3> Concatenation3dDim0TestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
2067 armnn::TensorInfo outputTensorInfo({ 6, 3, 2 }, armnn::GetDataType<T>());
2069 LayerTestResult<T, 3> result = Concatenation3dTestImpl<T>(workloadFactory, outputTensorInfo, 0,
2071 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2072 // Batch 0, Channel 0
2075 // Batch 0, Channel 1
2078 // Batch 0, Channel 2
2081 // Batch 1, Channel 0
2084 // Batch 1, Channel 1
2087 // Batch 1, Channel 2
2090 // Batch 2, Channel 0
2093 // Batch 2, Channel 1
2096 // Batch 2, Channel 2
2099 // Batch 3, Channel 0
2102 // Batch 3, Channel 1
2105 // Batch 3, Channel 2
2108 // Batch 4, Channel 0
2111 // Batch 4, Channel 1
2114 // Batch 4, Channel 2
2117 // Batch 5, Channel 0
2120 // Batch 5, Channel 1
2123 // Batch 5, Channel 2
2129 LayerTestResult<float, 3> Concatenation3dDim0Test(armnn::IWorkloadFactory& workloadFactory)
2131 return Concatenation3dDim0TestImpl<float>(workloadFactory, 0.0f, 0);
2134 template <typename T>
2135 LayerTestResult<T, 3> Concatenation3dDim1TestImpl(armnn::IWorkloadFactory& workloadFactory,
2136 float qScale, int32_t qOffset)
2138 armnn::TensorInfo outputTensorInfo({ 2, 9, 2 }, armnn::GetDataType<T>());
2140 LayerTestResult<T, 3> result = Concatenation3dTestImpl<T>(workloadFactory, outputTensorInfo, 1, qScale, qOffset);
2141 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2142 // Batch 0, Channel 0
2145 // Batch 0, Channel 1
2148 // Batch 0, Channel 2
2151 // Batch 0, Channel 3
2154 // Batch 0, Channel 4
2157 // Batch 0, Channel 5
2160 // Batch 0, Channel 6
2163 // Batch 0, Channel 7
2166 // Batch 0, Channel 8
2169 // Batch 1, Channel 0
2172 // Batch 1, Channel 1
2175 // Batch 1, Channel 2
2178 // Batch 1, Channel 3
2181 // Batch 1, Channel 4
2184 // Batch 1, Channel 5
2187 // Batch 1, Channel 6
2190 // Batch 1, Channel 7
2193 // Batch 1, Channel 8
2200 LayerTestResult<float, 3> Concatenation3dDim1Test(armnn::IWorkloadFactory& workloadFactory)
2202 return Concatenation3dDim1TestImpl<float>(workloadFactory, 0.0f, 0);
2205 template <typename T>
2206 LayerTestResult<T, 3> Concatenation3dDim2TestImpl(armnn::IWorkloadFactory& workloadFactory,
2207 float qScale, int32_t qOffset)
2209 armnn::TensorInfo outputTensorInfo({ 2, 3, 6 }, armnn::GetDataType<T>());
2211 LayerTestResult<T, 3> result = Concatenation3dTestImpl<T>(workloadFactory, outputTensorInfo, 2, qScale, qOffset);
2212 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2213 // Batch 0, Channel 0
2214 1.0f, 2.0f, 7.0f, 8.0f, 13.0f, 14.0f,
2216 // Batch 0, Channel 1
2217 3.0f, 4.0f, 9.0f, 10.0f, 15.0f, 16.0f,
2219 // Batch 0, Channel 2
2220 5.0f, 6.0f, 11.0f, 12.0f, 17.0f, 18.0f,
2222 // Batch 1, Channel 0
2223 19.0f, 20.0f, 25.0f, 26.0f, 31.0f, 32.0f,
2225 // Batch 1, Channel 1
2226 21.0f, 22.0f, 27.0f, 28.0f, 33.0f, 34.0f,
2228 // Batch 1, Channel 2
2229 23.0f, 24.0f, 29.0f, 30.0f, 35.0f, 36.0f,
2235 LayerTestResult<float, 3> Concatenation3dDim2Test(armnn::IWorkloadFactory& workloadFactory)
2237 return Concatenation3dDim2TestImpl<float>(workloadFactory, 0.0f, 0);
2240 template <typename T>
2241 LayerTestResult<T, 3> Concatenation3dDim0DiffInputDimsTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
2244 armnn::TensorInfo input0TensorInfo({ 2, 3, 2 }, armnn::GetDataType<T>());
2245 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2246 // Batch 0, Channel 0
2249 // Batch 0, Channel 1
2252 // Batch 0, Channel 2
2255 // Batch 1, Channel 0
2258 // Batch 1, Channel 1
2261 // Batch 1, Channel 2
2265 armnn::TensorInfo input1TensorInfo({ 1, 3, 2 }, armnn::GetDataType<T>());
2266 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2267 // Batch 0, Channel 0
2270 // Batch 0, Channel 1
2273 // Batch 0, Channel 2
2277 armnn::TensorInfo input2TensorInfo({ 3, 3, 2 }, armnn::GetDataType<T>());
2278 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2279 // Batch 0, Channel 0
2282 // Batch 0, Channel 1
2285 // Batch 0, Channel 2
2288 // Batch 1, Channel 0
2291 // Batch 1, Channel 1
2294 // Batch 1, Channel 2
2297 // Batch 2, Channel 0
2300 // Batch 2, Channel 1
2303 // Batch 2, Channel 2
2307 armnn::TensorInfo outputTensorInfo({ 6, 3, 2 }, armnn::GetDataType<T>());
2308 LayerTestResult<T, 3> result(outputTensorInfo);
2310 std::vector<T> output;
2311 output.resize(outputTensorInfo.GetNumElements());
2312 Concatenate<T>(workloadFactory,
2313 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
2314 { input0.data(), input1.data(), input2.data() },
2319 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
2320 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2321 // Batch 0, Channel 0
2324 // Batch 0, Channel 1
2327 // Batch 0, Channel 2
2330 // Batch 1, Channel 0
2333 // Batch 1, Channel 1
2336 // Batch 1, Channel 2
2339 // Batch 2, Channel 0
2342 // Batch 2, Channel 1
2345 // Batch 2, Channel 2
2348 // Batch 3, Channel 0
2351 // Batch 3, Channel 1
2354 // Batch 3, Channel 2
2357 // Batch 4, Channel 0
2360 // Batch 4, Channel 1
2363 // Batch 4, Channel 2
2366 // Batch 5, Channel 0
2369 // Batch 5, Channel 1
2372 // Batch 5, Channel 2
2379 LayerTestResult<float, 3> Concatenation3dDim0DiffInputDimsTest(armnn::IWorkloadFactory& workloadFactory)
2381 return Concatenation3dDim0DiffInputDimsTestImpl<float>(workloadFactory, 0.0f, 0);
2384 template <typename T>
2385 LayerTestResult<T, 3> Concatenation3dDim1DiffInputDimsTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
2388 armnn::TensorInfo input0TensorInfo({ 2, 3, 2 }, armnn::GetDataType<T>());
2389 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2390 // Batch 0, Channel 0
2393 // Batch 0, Channel 1
2396 // Batch 0, Channel 2
2399 // Batch 1, Channel 0
2402 // Batch 1, Channel 1
2405 // Batch 1, Channel 2
2409 armnn::TensorInfo input1TensorInfo({ 2, 4, 2 }, armnn::GetDataType<T>());
2410 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2411 // Batch 0, Channel 0
2414 // Batch 0, Channel 1
2417 // Batch 0, Channel 2
2420 // Batch 0, Channel 3
2423 // Batch 1, Channel 0
2426 // Batch 1, Channel 1
2429 // Batch 1, Channel 2
2432 // Batch 1, Channel 3
2436 armnn::TensorInfo input2TensorInfo({ 2, 1, 2 }, armnn::GetDataType<T>());
2437 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2438 // Batch 0, Channel 0
2441 // Batch 1, Channel 0
2445 armnn::TensorInfo outputTensorInfo({ 2, 8, 2 }, armnn::GetDataType<T>());
2446 LayerTestResult<T, 3> result(outputTensorInfo);
2448 std::vector<T> output;
2449 output.resize(outputTensorInfo.GetNumElements());
2450 Concatenate<T>(workloadFactory,
2451 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
2452 { input0.data(), input1.data(), input2.data() },
2457 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
2458 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2459 // Batch 0, Channel 0
2462 // Batch 0, Channel 1
2465 // Batch 0, Channel 2
2468 // Batch 0, Channel 3
2471 // Batch 0, Channel 4
2474 // Batch 0, Channel 5
2477 // Batch 0, Channel 6
2480 // Batch 0, Channel 7
2483 // Batch 1, Channel 0
2486 // Batch 1, Channel 1
2489 // Batch 1, Channel 2
2492 // Batch 1, Channel 3
2495 // Batch 1, Channel 4
2498 // Batch 1, Channel 5
2501 // Batch 1, Channel 6
2504 // Batch 1, Channel 7
2511 LayerTestResult<float, 3> Concatenation3dDim1DiffInputDimsTest(armnn::IWorkloadFactory& workloadFactory)
2513 return Concatenation3dDim1DiffInputDimsTestImpl<float>(workloadFactory, 0.0f, 0);
2516 template <typename T>
2517 LayerTestResult<T, 3> Concatenation3dDim2DiffInputDimsTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale,
2520 armnn::TensorInfo input0TensorInfo({ 2, 3, 2 }, armnn::GetDataType<T>());
2521 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2522 // Batch 0, Channel 0
2525 // Batch 0, Channel 1
2528 // Batch 0, Channel 2
2531 // Batch 1, Channel 0
2534 // Batch 1, Channel 1
2537 // Batch 1, Channel 2
2541 armnn::TensorInfo input1TensorInfo({ 2, 3, 1 }, armnn::GetDataType<T>());
2542 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2543 // Batch 0, Channel 0
2546 // Batch 0, Channel 1
2549 // Batch 0, Channel 2
2552 // Batch 1, Channel 0
2555 // Batch 1, Channel 1
2558 // Batch 1, Channel 2
2562 armnn::TensorInfo input2TensorInfo({ 2, 3, 3 }, armnn::GetDataType<T>());
2563 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(qScale, qOffset, {
2564 // Batch 0, Channel 0
2565 13.0f, 14.0f, 50.0f,
2567 // Batch 0, Channel 1
2568 15.0f, 16.0f, 51.0f,
2570 // Batch 0, Channel 2
2571 17.0f, 18.0f, 52.0f,
2573 // Batch 1, Channel 0
2574 31.0f, 32.0f, 53.0f,
2576 // Batch 1, Channel 1
2577 33.0f, 34.0f, 54.0f,
2579 // Batch 1, Channel 2
2580 35.0f, 36.0f, 55.0f,
2583 armnn::TensorInfo outputTensorInfo({ 2, 3, 6 }, armnn::GetDataType<T>());
2584 LayerTestResult<T, 3> result(outputTensorInfo);
2586 std::vector<T> output;
2587 output.resize(outputTensorInfo.GetNumElements());
2588 Concatenate<T>(workloadFactory,
2589 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
2590 { input0.data(), input1.data(), input2.data() },
2595 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
2596 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, {
2597 // Batch 0, Channel 0
2598 1.0f, 2.0f, 7.0f, 13.0f, 14.0f, 50.0f,
2600 // Batch 0, Channel 1
2601 3.0f, 4.0f, 9.0f, 15.0f, 16.0f, 51.0f,
2603 // Batch 0, Channel 2
2604 5.0f, 6.0f, 11.0f, 17.0f, 18.0f, 52.0f,
2606 // Batch 1, Channel 0
2607 19.0f, 20.0f, 25.0f, 31.0f, 32.0f, 53.0f,
2609 // Batch 1, Channel 1
2610 21.0f, 22.0f, 27.0f, 33.0f, 34.0f, 54.0f,
2612 // Batch 1, Channel 2
2613 23.0f, 24.0f, 29.0f, 35.0f, 36.0f, 55.0f,
2619 LayerTestResult<float, 3> Concatenation3dDim2DiffInputDimsTest(armnn::IWorkloadFactory& workloadFactory)
2621 return Concatenation3dDim2DiffInputDimsTestImpl<float>(workloadFactory, 0.0f, 0);
2624 LayerTestResult<float, 4> ResizeBilinearNopTest(armnn::IWorkloadFactory& workloadFactory)
2626 constexpr unsigned int inputWidth = 4;
2627 constexpr unsigned int inputHeight = 4;
2628 constexpr unsigned int inputChannels = 1;
2629 constexpr unsigned int inputBatchSize = 1;
2631 constexpr unsigned int outputWidth = inputWidth;
2632 constexpr unsigned int outputHeight = inputHeight;
2633 constexpr unsigned int outputChannels = inputChannels;
2634 constexpr unsigned int outputBatchSize = inputBatchSize;
2636 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2637 armnn::DataType::Float32);
2638 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2639 armnn::DataType::Float32);
2641 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2642 1.0f, 2.0f, 3.0f, 4.0f,
2643 2.0f, 3.0f, 4.0f, 5.0f,
2644 3.0f, 4.0f, 5.0f, 6.0f,
2645 4.0f, 5.0f, 6.0f, 7.0f
2648 LayerTestResult<float, 4> result(outputTensorInfo);
2649 result.outputExpected = input;
2651 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2652 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2654 armnn::ResizeBilinearQueueDescriptor descriptor;
2655 armnn::WorkloadInfo info;
2656 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2657 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2659 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
2661 inputHandle->Allocate();
2662 outputHandle->Allocate();
2663 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2665 workloadFactory.Finalize();
2666 workload->Execute();
2668 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2672 LayerTestResult<float, 4> SimpleResizeBilinearTest(armnn::IWorkloadFactory& workloadFactory)
2674 constexpr unsigned int inputWidth = 2;
2675 constexpr unsigned int inputHeight = 2;
2676 constexpr unsigned int inputChannels = 1;
2677 constexpr unsigned int inputBatchSize = 1;
2679 constexpr unsigned int outputWidth = inputWidth / 2;
2680 constexpr unsigned int outputHeight = inputHeight / 2;
2681 constexpr unsigned int outputChannels = inputChannels;
2682 constexpr unsigned int outputBatchSize = inputBatchSize;
2684 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2685 armnn::DataType::Float32);
2686 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2687 armnn::DataType::Float32);
2689 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2694 // The 'resize bilinear' operation projects the top-left corner of output texels into the input image,
2695 // then figures out the interpolants and weights. Note this is different to projecting the centre of the
2696 // output texel - and thus we'll expect the output 1x1 matrix to contain, as its single element, the value
2697 // that was at position (0,0) of the input matrix (rather than an average, which we would expect if projecting
2699 LayerTestResult<float, 4> result(outputTensorInfo);
2700 result.outputExpected = MakeTensor<float, 4>(outputTensorInfo, std::vector<float>({
2704 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2705 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2707 armnn::ResizeBilinearQueueDescriptor descriptor;
2708 armnn::WorkloadInfo info;
2709 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2710 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2712 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
2714 inputHandle->Allocate();
2715 outputHandle->Allocate();
2716 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2718 workloadFactory.Finalize();
2719 workload->Execute();
2721 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2725 LayerTestResult<float, 4> ResizeBilinearSqMinTest(armnn::IWorkloadFactory& workloadFactory)
2727 constexpr unsigned int inputWidth = 4;
2728 constexpr unsigned int inputHeight = 4;
2729 constexpr unsigned int inputChannels = 1;
2730 constexpr unsigned int inputBatchSize = 1;
2732 constexpr unsigned int outputWidth = inputWidth / 2;
2733 constexpr unsigned int outputHeight = inputHeight / 2;
2734 constexpr unsigned int outputChannels = inputChannels;
2735 constexpr unsigned int outputBatchSize = inputBatchSize;
2737 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2738 armnn::DataType::Float32);
2739 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2740 armnn::DataType::Float32);
2742 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2743 1.0f, 2.0f, 3.0f, 4.0f,
2744 2.0f, 3.0f, 4.0f, 5.0f,
2745 3.0f, 4.0f, 5.0f, 6.0f,
2746 4.0f, 5.0f, 6.0f, 7.0f
2749 LayerTestResult<float, 4> result(outputTensorInfo);
2750 result.outputExpected = MakeTensor<float, 4>(outputTensorInfo, std::vector<float>({
2755 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2756 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2758 armnn::ResizeBilinearQueueDescriptor descriptor;
2759 armnn::WorkloadInfo info;
2760 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2761 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2763 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
2765 inputHandle->Allocate();
2766 outputHandle->Allocate();
2767 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2769 workloadFactory.Finalize();
2770 workload->Execute();
2772 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2776 LayerTestResult<float, 4> ResizeBilinearMinTest(armnn::IWorkloadFactory& workloadFactory)
2778 constexpr unsigned int inputWidth = 5;
2779 constexpr unsigned int inputHeight = 3;
2780 constexpr unsigned int inputChannels = 1;
2781 constexpr unsigned int inputBatchSize = 1;
2783 constexpr unsigned int outputWidth = 3;
2784 constexpr unsigned int outputHeight = 2;
2785 constexpr unsigned int outputChannels = inputChannels;
2786 constexpr unsigned int outputBatchSize = inputBatchSize;
2788 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2789 armnn::DataType::Float32);
2790 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2791 armnn::DataType::Float32);
2793 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2794 1.0f, 2.0f, 3.0f, 5.0f, 8.0f,
2795 13.0f, 21.0f, 34.0f, 55.0f, 89.0f,
2796 144.0f, 233.0f, 377.0f, 610.0f, 987.0f
2799 LayerTestResult<float, 4> result(outputTensorInfo);
2800 result.outputExpected = MakeTensor<float, 4>(outputTensorInfo, std::vector<float>({
2801 1.0f, 2.6666f, 6.0f,
2802 78.5f, 179.3333f, 401.f
2805 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2806 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2808 armnn::ResizeBilinearQueueDescriptor descriptor;
2809 armnn::WorkloadInfo info;
2810 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2811 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2813 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
2815 inputHandle->Allocate();
2816 outputHandle->Allocate();
2817 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2819 workloadFactory.Finalize();
2820 workload->Execute();
2822 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2826 LayerTestResult<float, 4> ResizeBilinearMagTest(armnn::IWorkloadFactory& workloadFactory)
2828 constexpr unsigned int inputWidth = 2;
2829 constexpr unsigned int inputHeight = 3;
2830 constexpr unsigned int inputChannels = 1;
2831 constexpr unsigned int inputBatchSize = 1;
2833 constexpr unsigned int outputWidth = 5;
2834 constexpr unsigned int outputHeight = 3;
2835 constexpr unsigned int outputChannels = inputChannels;
2836 constexpr unsigned int outputBatchSize = inputBatchSize;
2838 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2839 armnn::DataType::Float32);
2840 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2841 armnn::DataType::Float32);
2843 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2849 LayerTestResult<float, 4> result(outputTensorInfo);
2850 result.outputExpected = MakeTensor<float, 4>(outputTensorInfo, std::vector<float>({
2851 1.0f, 1.4f, 1.8f, 2.f, 2.f,
2852 13.f, 16.2f, 19.4f, 21.f, 21.f,
2853 144.f, 179.6f, 215.2f, 233.f, 233.f
2856 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2857 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2859 armnn::ResizeBilinearQueueDescriptor descriptor;
2860 armnn::WorkloadInfo info;
2861 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2862 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2864 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
2866 inputHandle->Allocate();
2867 outputHandle->Allocate();
2868 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2870 workloadFactory.Finalize();
2871 workload->Execute();
2873 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2877 LayerTestResult<float, 2> FakeQuantizationTest(armnn::IWorkloadFactory& workloadFactory)
2879 constexpr unsigned int width = 2;
2880 constexpr unsigned int height = 3;
2882 const armnn::TensorInfo tensorInfo({height, width },
2883 armnn::DataType::Float32);
2884 auto input = MakeTensor<float, 2>(tensorInfo, std::vector<float>({
2890 LayerTestResult<float, 2> ret(tensorInfo);
2892 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(tensorInfo);
2894 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(tensorInfo);
2896 armnn::FakeQuantizationQueueDescriptor data;
2897 armnn::WorkloadInfo info;
2899 AddInputToWorkload(data, info, tensorInfo, inputHandle.get());
2900 AddOutputToWorkload(data, info, tensorInfo, outputHandle.get());
2904 data.m_Parameters.m_Min = min;
2905 data.m_Parameters.m_Max = max;
2907 armnn::PassthroughCpuTensorHandle refHandle(tensorInfo, &ret.outputExpected[0][0]);
2908 armnn::FakeQuantizationQueueDescriptor refData = data;
2909 armnn::WorkloadInfo refInfo = info;
2910 SetWorkloadOutput(refData, refInfo, 0, tensorInfo, &refHandle);
2912 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateFakeQuantization(data, info);
2914 inputHandle->Allocate();
2915 outputHandle->Allocate();
2917 CopyDataToITensorHandle(inputHandle.get(), &input[0][0]);
2919 workloadFactory.Finalize();
2920 workload->Execute();
2922 CopyDataFromITensorHandle(&ret.output[0][0], outputHandle.get());
2924 ret.outputExpected = MakeTensor<float, 2>(tensorInfo, std::vector<float>({
2932 LayerTestResult<float, 4> L2Normalization1dTest(armnn::IWorkloadFactory& workloadFactory)
2934 constexpr unsigned int inputWidth = 1;
2935 constexpr unsigned int inputHeight = 1;
2936 constexpr unsigned int inputChannels = 10;
2937 constexpr unsigned int inputBatchSize = 1;
2939 constexpr unsigned int outputWidth = inputWidth;
2940 constexpr unsigned int outputHeight = inputHeight;
2941 constexpr unsigned int outputChannels = inputChannels;
2942 constexpr unsigned int outputBatchSize = inputBatchSize;
2944 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
2945 armnn::DataType::Float32);
2946 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
2947 armnn::DataType::Float32);
2949 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2950 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f
2953 const float approxInvL2Norm = 0.050964719f;
2954 LayerTestResult<float, 4> result(outputTensorInfo);
2955 result.outputExpected = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
2956 1.0f * approxInvL2Norm,
2957 2.0f * approxInvL2Norm,
2958 3.0f * approxInvL2Norm,
2959 4.0f * approxInvL2Norm,
2960 5.0f * approxInvL2Norm,
2961 6.0f * approxInvL2Norm,
2962 7.0f * approxInvL2Norm,
2963 8.0f * approxInvL2Norm,
2964 9.0f * approxInvL2Norm,
2965 10.0f * approxInvL2Norm
2968 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
2969 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
2971 armnn::L2NormalizationQueueDescriptor descriptor;
2972 armnn::WorkloadInfo info;
2973 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
2974 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
2976 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
2978 inputHandle->Allocate();
2979 outputHandle->Allocate();
2980 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
2982 workloadFactory.Finalize();
2983 workload->Execute();
2985 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
2992 float CalcInvL2Norm(std::initializer_list<float> elements)
2994 const float reduction = std::accumulate(elements.begin(), elements.end(), 0.0f,
2995 [](float acc, float element) { return acc + element * element; });
2996 return 1.0f / sqrtf(reduction);
3001 LayerTestResult<float, 4> L2Normalization2dTest(armnn::IWorkloadFactory& workloadFactory)
3003 constexpr unsigned int inputWidth = 5;
3004 constexpr unsigned int inputHeight = 1;
3005 constexpr unsigned int inputChannels = 2;
3006 constexpr unsigned int inputBatchSize = 1;
3008 constexpr unsigned int outputWidth = inputWidth;
3009 constexpr unsigned int outputHeight = inputHeight;
3010 constexpr unsigned int outputChannels = inputChannels;
3011 constexpr unsigned int outputBatchSize = inputBatchSize;
3013 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3014 armnn::DataType::Float32);
3015 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3016 armnn::DataType::Float32);
3018 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3019 1.0f, 3.0f, 5.0f, 7.0f, 9.0f,
3020 2.0f, 4.0f, 6.0f, 8.0f, 10.0f
3023 LayerTestResult<float, 4> result(outputTensorInfo);
3024 result.outputExpected = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3025 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
3026 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
3027 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
3028 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
3029 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
3031 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
3032 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
3033 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
3034 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
3035 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
3038 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3039 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3041 armnn::L2NormalizationQueueDescriptor descriptor;
3042 armnn::WorkloadInfo info;
3043 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3044 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3046 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
3048 inputHandle->Allocate();
3049 outputHandle->Allocate();
3050 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3052 workloadFactory.Finalize();
3053 workload->Execute();
3055 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3059 LayerTestResult<float, 4> L2Normalization3dTest(armnn::IWorkloadFactory& workloadFactory)
3061 constexpr unsigned int inputWidth = 3;
3062 constexpr unsigned int inputHeight = 4;
3063 constexpr unsigned int inputChannels = 2;
3064 constexpr unsigned int inputBatchSize = 1;
3066 constexpr unsigned int outputWidth = inputWidth;
3067 constexpr unsigned int outputHeight = inputHeight;
3068 constexpr unsigned int outputChannels = inputChannels;
3069 constexpr unsigned int outputBatchSize = inputBatchSize;
3071 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3072 armnn::DataType::Float32);
3073 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3074 armnn::DataType::Float32);
3076 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3078 119.0f, 21.0f, 150.0f,
3079 149.0f, 32.0f, 179.0f,
3080 15.0f, 227.0f, 141.0f,
3081 147.0f, 199.0f, 220.0f,
3084 110.0f, 140.0f, 73.0f,
3085 211.0f, 212.0f, 89.0f,
3086 24.0f, 138.0f, 188.0f,
3087 162.0f, 12.0f, 161.0f,
3090 LayerTestResult<float, 4> result(outputTensorInfo);
3091 result.outputExpected = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3092 119.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
3093 21.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
3094 150.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
3095 149.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
3096 32.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
3097 179.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
3098 15.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
3099 227.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
3100 141.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
3101 147.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
3102 199.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
3103 220.0f * CalcInvL2Norm({ 220.0f, 161.0f }),
3105 110.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
3106 140.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
3107 73.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
3108 211.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
3109 212.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
3110 89.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
3111 24.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
3112 138.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
3113 188.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
3114 162.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
3115 12.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
3116 161.0f * CalcInvL2Norm({ 220.0f, 161.0f }),
3119 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3120 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3122 armnn::L2NormalizationQueueDescriptor descriptor;
3123 armnn::WorkloadInfo info;
3124 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3125 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3127 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
3129 inputHandle->Allocate();
3130 outputHandle->Allocate();
3131 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3133 workloadFactory.Finalize();
3134 workload->Execute();
3136 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3140 LayerTestResult<float, 4> L2Normalization4dTest(armnn::IWorkloadFactory& workloadFactory)
3142 constexpr unsigned int inputWidth = 3;
3143 constexpr unsigned int inputHeight = 4;
3144 constexpr unsigned int inputChannels = 3;
3145 constexpr unsigned int inputBatchSize = 2;
3147 constexpr unsigned int outputWidth = inputWidth;
3148 constexpr unsigned int outputHeight = inputHeight;
3149 constexpr unsigned int outputChannels = inputChannels;
3150 constexpr unsigned int outputBatchSize = inputBatchSize;
3152 const armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3153 armnn::DataType::Float32);
3154 const armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3155 armnn::DataType::Float32);
3157 auto input = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3158 // Batch 0, Channel 0
3159 235.0f, 46.0f, 178.0f,
3160 100.0f, 123.0f, 19.0f,
3161 172.0f, 74.0f, 250.0f,
3162 6.0f, 195.0f, 80.0f,
3164 // Batch 0, Channel 1
3165 113.0f, 95.0f, 202.0f,
3166 77.0f, 114.0f, 71.0f,
3167 122.0f, 246.0f, 166.0f,
3168 82.0f, 28.0f, 37.0f,
3170 // Batch 0, Channel 2
3171 56.0f, 170.0f, 162.0f,
3172 194.0f, 89.0f, 254.0f,
3173 12.0f, 209.0f, 200.0f,
3176 // Batch 1, Channel 0
3177 67.0f, 90.0f, 49.0f,
3178 7.0f, 163.0f, 18.0f,
3179 25.0f, 117.0f, 103.0f,
3180 247.0f, 59.0f, 189.0f,
3182 // Batch 1, Channel 1
3183 239.0f, 104.0f, 199.0f,
3184 17.0f, 124.0f, 153.0f,
3185 222.0f, 217.0f, 75.0f,
3186 32.0f, 126.0f, 21.0f,
3188 // Batch 1, Channel 2
3189 97.0f, 145.0f, 215.0f,
3190 115.0f, 116.0f, 238.0f,
3191 226.0f, 16.0f, 132.0f,
3192 92.0f, 125.0f, 88.0f,
3195 LayerTestResult<float, 4> result(outputTensorInfo);
3196 result.outputExpected = MakeTensor<float, 4>(inputTensorInfo, std::vector<float>({
3198 // Batch 0, Channel 0
3199 235.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
3200 46.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
3201 178.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
3202 100.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
3203 123.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
3204 19.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
3205 172.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
3206 74.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
3207 250.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
3208 6.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
3209 195.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
3210 80.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
3212 // Batch 0, Channel 1
3213 113.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
3214 95.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
3215 202.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
3216 77.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
3217 114.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
3218 71.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
3219 122.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
3220 246.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
3221 166.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
3222 82.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
3223 28.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
3224 37.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
3226 // Batch 0, Channel 2
3227 56.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
3228 170.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
3229 162.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
3230 194.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
3231 89.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
3232 254.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
3233 12.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
3234 209.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
3235 200.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
3236 1.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
3237 64.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
3238 54.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
3240 // Batch 1, Channel 0
3241 67.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
3242 90.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
3243 49.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
3244 7.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
3245 163.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
3246 18.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
3247 25.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
3248 117.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
3249 103.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
3250 247.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
3251 59.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
3252 189.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
3254 // Batch 1, Channel 1
3255 239.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
3256 104.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
3257 199.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
3258 17.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
3259 124.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
3260 153.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
3261 222.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
3262 217.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
3263 75.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
3264 32.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
3265 126.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
3266 21.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
3268 // Batch 1, Channel 2
3269 97.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
3270 145.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
3271 215.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
3272 115.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
3273 116.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
3274 238.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
3275 226.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
3276 16.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
3277 132.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
3278 92.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
3279 125.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
3280 88.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
3283 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3284 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3286 armnn::L2NormalizationQueueDescriptor descriptor;
3287 armnn::WorkloadInfo info;
3288 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3289 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3291 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
3293 inputHandle->Allocate();
3294 outputHandle->Allocate();
3295 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3297 workloadFactory.Finalize();
3298 workload->Execute();
3300 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3304 template <typename T>
3305 LayerTestResult<T, 4> ConstantTestImpl(armnn::IWorkloadFactory& workloadFactory,
3309 constexpr unsigned int inputWidth = 3;
3310 constexpr unsigned int inputHeight = 4;
3311 constexpr unsigned int inputChannels = 3;
3312 constexpr unsigned int inputBatchSize = 2;
3314 constexpr unsigned int outputWidth = inputWidth;
3315 constexpr unsigned int outputHeight = inputHeight;
3316 constexpr unsigned int outputChannels = inputChannels;
3317 constexpr unsigned int outputBatchSize = inputBatchSize;
3319 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3320 armnn::GetDataType<T>());
3322 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3323 armnn::GetDataType<T>());
3325 // Set quantization parameters if the requested type is a quantized type.
3326 if(armnn::IsQuantizedType<T>())
3328 inputTensorInfo.SetQuantizationScale(qScale);
3329 inputTensorInfo.SetQuantizationOffset(qOffset);
3330 outputTensorInfo.SetQuantizationScale(qScale);
3331 outputTensorInfo.SetQuantizationOffset(qOffset);
3334 auto input = MakeTensor<T, 4>(inputTensorInfo, std::vector<T>(
3335 QuantizedVector<T>(qScale, qOffset, {
3336 // Batch 0, Channel 0
3337 235.0f, 46.0f, 178.0f,
3338 100.0f, 123.0f, 19.0f,
3339 172.0f, 74.0f, 250.0f,
3340 6.0f, 195.0f, 80.0f,
3342 // Batch 0, Channel 1
3343 113.0f, 95.0f, 202.0f,
3344 77.0f, 114.0f, 71.0f,
3345 122.0f, 246.0f, 166.0f,
3346 82.0f, 28.0f, 37.0f,
3348 // Batch 0, Channel 2
3349 56.0f, 170.0f, 162.0f,
3350 194.0f, 89.0f, 254.0f,
3351 12.0f, 209.0f, 200.0f,
3354 // Batch 1, Channel 0
3355 67.0f, 90.0f, 49.0f,
3356 7.0f, 163.0f, 18.0f,
3357 25.0f, 117.0f, 103.0f,
3358 247.0f, 59.0f, 189.0f,
3360 // Batch 1, Channel 1
3361 239.0f, 104.0f, 199.0f,
3362 17.0f, 124.0f, 153.0f,
3363 222.0f, 217.0f, 75.0f,
3364 32.0f, 126.0f, 21.0f,
3366 // Batch 1, Channel 2
3367 97.0f, 145.0f, 215.0f,
3368 115.0f, 116.0f, 238.0f,
3369 226.0f, 16.0f, 132.0f,
3370 92.0f, 125.0f, 88.0f,
3373 LayerTestResult<T, 4> result(outputTensorInfo);
3374 result.outputExpected = input;
3376 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3378 armnn::ScopedCpuTensorHandle constantTensor(inputTensorInfo);
3379 AllocateAndCopyDataToITensorHandle(&constantTensor, &input[0][0][0][0]);
3381 armnn::ConstantQueueDescriptor descriptor;
3382 descriptor.m_LayerOutput = &constantTensor;
3384 armnn::WorkloadInfo info;
3385 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3387 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateConstant(descriptor, info);
3389 outputHandle->Allocate();
3391 workloadFactory.Finalize();
3392 workload->Execute();
3394 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3398 LayerTestResult<float, 4> ConstantTest(armnn::IWorkloadFactory& workloadFactory)
3400 return ConstantTestImpl<float>(workloadFactory, 0.0f, 0);
3403 LayerTestResult<uint8_t, 4> ConstantTestUint8(armnn::IWorkloadFactory& workloadFactory)
3405 return ConstantTestImpl<uint8_t>(workloadFactory, 1.0f, 0);
3408 LayerTestResult<uint8_t, 3> MergerUint8Test(armnn::IWorkloadFactory& workloadFactory)
3410 unsigned int outputWidth = 3;
3411 unsigned int outputHeight = 6;
3412 unsigned int outputChannels = 3;
3414 unsigned int inputWidth1 = 3;
3415 unsigned int inputHeight1 = 6;
3416 unsigned int inputChannels1 = 2;
3418 unsigned int inputWidth2 = 3;
3419 unsigned int inputHeight2 = 6;
3420 unsigned int inputChannels2 = 1;
3422 // Defines the tensor descriptors.
3423 armnn::TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, armnn::DataType::QuantisedAsymm8);
3424 armnn::TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, armnn::DataType::QuantisedAsymm8);
3425 armnn::TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, armnn::DataType::QuantisedAsymm8);
3427 // Arbitrary scale and offsets. They don't really matter as the merger operator doesn't dequantize/quantize them.
3428 const float scale = 0.13497836f;
3429 const int32_t offset = -7;
3431 outputTensorInfo.SetQuantizationScale(scale);
3432 outputTensorInfo.SetQuantizationOffset(offset);
3433 inputTensorInfo1.SetQuantizationScale(scale);
3434 inputTensorInfo1.SetQuantizationOffset(offset);
3435 inputTensorInfo2.SetQuantizationScale(scale);
3436 inputTensorInfo2.SetQuantizationOffset(offset);
3438 LayerTestResult<uint8_t, 3> ret(outputTensorInfo);
3440 ret.outputExpected = MakeTensor<uint8_t, 3>(outputTensorInfo, std::vector<uint8_t>(
3465 auto input1 = MakeTensor<uint8_t, 3>(inputTensorInfo1, std::vector<uint8_t>(
3483 auto input2 = MakeTensor<uint8_t, 3>(inputTensorInfo2, std::vector<uint8_t>(
3494 std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
3495 armnn::MergerQueueDescriptor::ViewOrigin window1(wOrigin1);
3497 std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
3498 armnn::MergerQueueDescriptor::ViewOrigin window2(wOrigin2);
3501 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3503 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
3505 std::unique_ptr<armnn::ITensorHandle> inputHandle1 =
3506 subTensorsSupported ?
3507 workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
3508 workloadFactory.CreateTensorHandle(inputTensorInfo1);
3510 std::unique_ptr<armnn::ITensorHandle> inputHandle2 =
3511 subTensorsSupported ?
3512 workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
3513 workloadFactory.CreateTensorHandle(inputTensorInfo2);
3516 armnn::MergerQueueDescriptor data;
3517 armnn::WorkloadInfo info;
3518 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
3519 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
3520 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
3522 data.m_ViewOrigins.push_back(window1);
3523 data.m_ViewOrigins.push_back(window2);
3525 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMerger(data, info);
3527 inputHandle1->Allocate();
3528 inputHandle2->Allocate();
3529 outputHandle->Allocate();
3531 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
3532 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
3534 workloadFactory.Finalize();
3535 workload->Execute();
3537 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
3542 LayerTestResult<uint8_t, 4> AdditionUint8Test(armnn::IWorkloadFactory& workloadFactory)
3544 unsigned int batchSize = 1;
3545 unsigned int channels = 2;
3546 unsigned int height = 2;
3547 unsigned int width = 3;
3549 const float scale = 7.0f;
3550 const int32_t offset = 3;
3552 armnn::TensorInfo inputTensorInfo1, inputTensorInfo2;
3553 armnn::TensorInfo outputTensorInfo;
3555 const unsigned int shape[] = { batchSize, channels, height, width };
3556 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::QuantisedAsymm8);
3557 inputTensorInfo1.SetQuantizationScale(scale);
3558 inputTensorInfo1.SetQuantizationOffset(offset);
3560 inputTensorInfo2 = armnn::TensorInfo(4, shape, armnn::DataType::QuantisedAsymm8);
3561 inputTensorInfo2.SetQuantizationScale(scale);
3562 inputTensorInfo2.SetQuantizationOffset(offset);
3564 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::QuantisedAsymm8);
3565 outputTensorInfo.SetQuantizationScale(scale);
3566 outputTensorInfo.SetQuantizationOffset(offset);
3568 // See dequantized values to the right.
3569 auto input1 = MakeTensor<uint8_t, 4>(inputTensorInfo1, std::vector<uint8_t>(
3571 63, 35, 77, 70, 56, 112, // 420, 224, 518, 469, 371, 763
3572 203, 28, 252, 168, 245, 91 // 1400, 175, 1743, 1155, 1694, 616
3575 // See dequantized values to the right.
3576 auto input2 = MakeTensor<uint8_t, 4>(inputTensorInfo1, std::vector<uint8_t>(
3578 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
3579 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
3582 // See dequantized values to the right.
3583 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3584 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, std::vector<uint8_t>(
3586 81, 39, 249, 255, 228, 255, // 546, 252, 1722, 2065(clamped), 1575, 2212(clamped)
3587 255, 186, 255, 186, 255, 214, // 2261(clamped), 1281, 2163(clamped), 1281, 2408(clamped), 1477
3590 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
3591 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = workloadFactory.CreateTensorHandle(inputTensorInfo2);
3592 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3594 armnn::AdditionQueueDescriptor data;
3595 armnn::WorkloadInfo info;
3596 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
3597 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
3598 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
3600 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
3602 inputHandle1->Allocate();
3603 inputHandle2->Allocate();
3604 outputHandle->Allocate();
3606 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
3607 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
3609 workloadFactory.Finalize();
3610 workload->Execute();
3612 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3619 LayerTestResult<uint8_t, 4> MultiplicationUint8TestHelper(armnn::IWorkloadFactory& workloadFactory,
3620 const unsigned int shape0[4],
3621 const std::vector<uint8_t> & values0,
3624 const unsigned int shape1[4],
3625 const std::vector<uint8_t> & values1,
3628 const unsigned int outShape[4],
3629 const std::vector<uint8_t> & outValues,
3633 armnn::TensorInfo inputTensorInfo0(4, shape0, armnn::DataType::QuantisedAsymm8);
3634 armnn::TensorInfo inputTensorInfo1(4, shape1, armnn::DataType::QuantisedAsymm8);
3635 armnn::TensorInfo outputTensorInfo(4, outShape, armnn::DataType::QuantisedAsymm8);
3637 inputTensorInfo0.SetQuantizationScale(scale0);
3638 inputTensorInfo0.SetQuantizationOffset(offset0);
3640 inputTensorInfo1.SetQuantizationScale(scale1);
3641 inputTensorInfo1.SetQuantizationOffset(offset1);
3643 outputTensorInfo.SetQuantizationScale(outScale);
3644 outputTensorInfo.SetQuantizationOffset(outOffset);
3646 auto input0 = MakeTensor<uint8_t, 4>(inputTensorInfo0, values0);
3647 auto input1 = MakeTensor<uint8_t, 4>(inputTensorInfo1, values1);
3649 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3650 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, outValues);
3652 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
3653 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
3654 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3656 armnn::MultiplicationQueueDescriptor data;
3657 armnn::WorkloadInfo info;
3658 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
3659 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
3660 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
3662 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
3664 inputHandle0->Allocate();
3665 inputHandle1->Allocate();
3666 outputHandle->Allocate();
3668 CopyDataToITensorHandle(inputHandle0.get(), &input0[0][0][0][0]);
3669 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
3671 workloadFactory.Finalize();
3672 workload->Execute();
3674 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3678 } // anonymous namespace
3680 LayerTestResult<uint8_t, 4> MultiplicationUint8Test(armnn::IWorkloadFactory& workloadFactory)
3682 unsigned int batchSize = 1;
3683 unsigned int channels = 2;
3684 unsigned int height = 2;
3685 unsigned int width = 3;
3686 const unsigned int shape[] = { batchSize, channels, height, width };
3688 // See dequantized values to the right.
3689 std::vector<uint8_t> input0({
3690 62, 37, 3, 172, 13, 111, // 244, 144, 8, 684, 48, 440,
3691 188, 20, 73, 31, 23, 31 // 748, 76, 288, 120, 88, 120
3694 // See dequantized values to the right.
3695 std::vector<uint8_t> input1({
3696 126, 240, 252, 183, 121, 247, // 384, 726, 762, 555, 369, 747,
3697 48, 115, 151, 79, 78, 97 // 150, 351, 459, 243, 240, 297
3700 // See dequantized values to the right.
3701 std::vector<uint8_t> output(
3703 64, 72, 0, 255, 8, 236, // 93696, 104544, 6096(clamped), 379620(clamped), 17712, 328680,
3704 77, 15, 92, 16, 10, 21, // 112200, 26676, 132192, 29160, 21120, 35640
3707 return MultiplicationUint8TestHelper(workloadFactory,
3718 1366.255f, // Scale/offset chosen to have output values out of range.
3722 LayerTestResult<uint8_t, 4> MultiplicationBroadcast1ElementUint8Test(armnn::IWorkloadFactory& workloadFactory)
3724 const unsigned int shape0[] = { 1, 2, 2, 3 };
3725 const unsigned int shape1[] = { 1, 1, 1, 1 };
3727 std::vector<uint8_t> input0({
3732 std::vector<uint8_t> input1({2});
3734 std::vector<uint8_t> output({
3736 14, 16, 18, 20, 22, 24
3739 return MultiplicationUint8TestHelper(workloadFactory,
3754 LayerTestResult<uint8_t, 4> MultiplicationBroadcast1DVectorUint8Test(armnn::IWorkloadFactory& workloadFactory)
3756 const unsigned int shape0[] = { 1, 2, 2, 3 };
3757 const unsigned int shape1[] = { 1, 1, 1, 3 };
3759 std::vector<uint8_t> input0({
3764 std::vector<uint8_t> input1({1, 2, 3});
3766 std::vector<uint8_t> output({
3768 7, 16, 27, 10, 22, 36
3771 return MultiplicationUint8TestHelper(workloadFactory,
3786 LayerTestResult<uint8_t, 4> ResizeBilinearNopUint8Test(armnn::IWorkloadFactory& workloadFactory)
3788 constexpr unsigned int inputWidth = 4;
3789 constexpr unsigned int inputHeight = 4;
3790 constexpr unsigned int inputChannels = 1;
3791 constexpr unsigned int inputBatchSize = 1;
3793 constexpr unsigned int outputWidth = inputWidth;
3794 constexpr unsigned int outputHeight = inputHeight;
3795 constexpr unsigned int outputChannels = inputChannels;
3796 constexpr unsigned int outputBatchSize = inputBatchSize;
3798 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3799 armnn::DataType::QuantisedAsymm8);
3800 inputTensorInfo.SetQuantizationScale(1.5f);
3801 inputTensorInfo.SetQuantizationOffset(-3);
3803 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3804 armnn::DataType::QuantisedAsymm8);
3805 outputTensorInfo.SetQuantizationScale(1.5f);
3806 outputTensorInfo.SetQuantizationOffset(-3);
3808 auto input = MakeTensor<uint8_t, 4>(inputTensorInfo, std::vector<uint8_t>({
3815 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3816 result.outputExpected = input;
3818 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3819 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3821 armnn::ResizeBilinearQueueDescriptor descriptor;
3822 armnn::WorkloadInfo info;
3823 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3824 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3826 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
3828 inputHandle->Allocate();
3829 outputHandle->Allocate();
3830 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3832 workloadFactory.Finalize();
3833 workload->Execute();
3835 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3839 LayerTestResult<uint8_t, 4> SimpleResizeBilinearUint8Test(armnn::IWorkloadFactory& workloadFactory)
3841 constexpr unsigned int inputWidth = 2;
3842 constexpr unsigned int inputHeight = 2;
3843 constexpr unsigned int inputChannels = 1;
3844 constexpr unsigned int inputBatchSize = 1;
3846 constexpr unsigned int outputWidth = inputWidth / 2;
3847 constexpr unsigned int outputHeight = inputHeight / 2;
3848 constexpr unsigned int outputChannels = inputChannels;
3849 constexpr unsigned int outputBatchSize = inputBatchSize;
3851 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3852 armnn::DataType::QuantisedAsymm8);
3853 inputTensorInfo.SetQuantizationScale(0.1567f);
3854 inputTensorInfo.SetQuantizationOffset(1);
3856 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3857 armnn::DataType::QuantisedAsymm8);
3858 outputTensorInfo.SetQuantizationScale(0.1567f);
3859 outputTensorInfo.SetQuantizationOffset(1);
3861 auto input = MakeTensor<uint8_t, 4>(inputTensorInfo, std::vector<uint8_t>({
3866 // The 'resize bilinear' operation projects the top-left corner of output texels into the input image,
3867 // then figures out the interpolants and weights. Note this is different to projecting the centre of the
3868 // output texel - and thus we'll expect the output 1x1 matrix to contain, as its single element, the value
3869 // that was at position (0,0) of the input matrix (rather than an average, which we would expect if projecting
3871 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3872 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, std::vector<uint8_t>({
3876 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3877 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3879 armnn::ResizeBilinearQueueDescriptor descriptor;
3880 armnn::WorkloadInfo info;
3881 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3882 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3884 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
3886 inputHandle->Allocate();
3887 outputHandle->Allocate();
3888 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3890 workloadFactory.Finalize();
3891 workload->Execute();
3893 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3897 LayerTestResult<uint8_t, 4> ResizeBilinearSqMinUint8Test(armnn::IWorkloadFactory& workloadFactory)
3899 constexpr unsigned int inputWidth = 4;
3900 constexpr unsigned int inputHeight = 4;
3901 constexpr unsigned int inputChannels = 1;
3902 constexpr unsigned int inputBatchSize = 1;
3904 constexpr unsigned int outputWidth = inputWidth / 2;
3905 constexpr unsigned int outputHeight = inputHeight / 2;
3906 constexpr unsigned int outputChannels = inputChannels;
3907 constexpr unsigned int outputBatchSize = inputBatchSize;
3909 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3910 armnn::DataType::QuantisedAsymm8);
3911 inputTensorInfo.SetQuantizationScale(3.141592f);
3912 inputTensorInfo.SetQuantizationOffset(3);
3914 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3915 armnn::DataType::QuantisedAsymm8);
3916 outputTensorInfo.SetQuantizationScale(3.141592f);
3917 outputTensorInfo.SetQuantizationOffset(3);
3919 auto input = MakeTensor<uint8_t, 4>(inputTensorInfo, std::vector<uint8_t>({
3926 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3927 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, std::vector<uint8_t>({
3932 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3933 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3935 armnn::ResizeBilinearQueueDescriptor descriptor;
3936 armnn::WorkloadInfo info;
3937 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3938 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3940 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
3942 inputHandle->Allocate();
3943 outputHandle->Allocate();
3944 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
3946 workloadFactory.Finalize();
3947 workload->Execute();
3949 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
3953 LayerTestResult<uint8_t, 4> ResizeBilinearMinUint8Test(armnn::IWorkloadFactory& workloadFactory)
3955 constexpr unsigned int inputWidth = 3;
3956 constexpr unsigned int inputHeight = 2;
3957 constexpr unsigned int inputChannels = 1;
3958 constexpr unsigned int inputBatchSize = 1;
3960 constexpr unsigned int outputWidth = 2;
3961 constexpr unsigned int outputHeight = 1;
3962 constexpr unsigned int outputChannels = inputChannels;
3963 constexpr unsigned int outputBatchSize = inputBatchSize;
3965 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
3966 armnn::DataType::QuantisedAsymm8);
3967 inputTensorInfo.SetQuantizationScale(1.5f);
3968 inputTensorInfo.SetQuantizationOffset(-1);
3970 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
3971 armnn::DataType::QuantisedAsymm8);
3972 outputTensorInfo.SetQuantizationScale(1.5f);
3973 outputTensorInfo.SetQuantizationOffset(-1);
3975 auto input = MakeTensor<uint8_t, 4>(inputTensorInfo, std::vector<uint8_t>({
3976 1, 2, 3, // 3.0, 4.5, 6.0
3977 5, 8, 13 // 9.0, 13.5, 21.0
3980 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
3981 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, std::vector<uint8_t>({
3985 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
3986 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
3988 armnn::ResizeBilinearQueueDescriptor descriptor;
3989 armnn::WorkloadInfo info;
3990 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
3991 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
3993 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
3995 inputHandle->Allocate();
3996 outputHandle->Allocate();
3998 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
4000 workloadFactory.Finalize();
4001 workload->Execute();
4003 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
4007 LayerTestResult<uint8_t, 4> ResizeBilinearMagUint8Test(armnn::IWorkloadFactory& workloadFactory)
4009 constexpr unsigned int inputWidth = 2;
4010 constexpr unsigned int inputHeight = 3;
4011 constexpr unsigned int inputChannels = 1;
4012 constexpr unsigned int inputBatchSize = 1;
4014 constexpr unsigned int outputWidth = 5;
4015 constexpr unsigned int outputHeight = 3;
4016 constexpr unsigned int outputChannels = inputChannels;
4017 constexpr unsigned int outputBatchSize = inputBatchSize;
4019 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
4020 armnn::DataType::QuantisedAsymm8);
4021 inputTensorInfo.SetQuantizationScale(0.010765f);
4022 inputTensorInfo.SetQuantizationOffset(7);
4024 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
4025 armnn::DataType::QuantisedAsymm8);
4026 outputTensorInfo.SetQuantizationScale(0.010132f);
4027 outputTensorInfo.SetQuantizationOffset(-18);
4029 auto input = MakeTensor<uint8_t, 4>(inputTensorInfo, std::vector<uint8_t>({
4030 24, 228, // 0.183005, 2.379065,
4031 105, 128, // 1.05497, 1.302565
4032 230, 71 // 2.400595, 0.68896
4035 LayerTestResult<uint8_t, 4> result(outputTensorInfo);
4036 result.outputExpected = MakeTensor<uint8_t, 4>(outputTensorInfo, std::vector<uint8_t>({
4037 0, 87, 173, 217, 217, // 0.18300501, 1.06142902, 1.93985295, 2.37906504, 2.37906504
4038 86, 96, 106, 111, 111, // 1.05497003, 1.15400803, 1.25304604, 1.30256498, 1.30256498
4039 219, 151, 84, 50, 50 // 2.40059495, 1.71594095, 1.03128707, 0.68896002, 0.68896002
4042 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
4043 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
4045 armnn::ResizeBilinearQueueDescriptor descriptor;
4046 armnn::WorkloadInfo info;
4047 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
4048 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
4050 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateResizeBilinear(descriptor, info);
4052 inputHandle->Allocate();
4053 outputHandle->Allocate();
4054 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
4056 workloadFactory.Finalize();
4057 workload->Execute();
4059 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
4063 LayerTestResult<float, 4> BatchNormTest(armnn::IWorkloadFactory& workloadFactory)
4065 auto ret = BatchNormTestImpl<float>(workloadFactory, 0.f, 0);
4069 LayerTestResult<uint8_t, 4> BatchNormUint8Test(armnn::IWorkloadFactory& workloadFactory)
4071 auto ret = BatchNormTestImpl<uint8_t>(workloadFactory, 1.f/20.f, 50);
4075 LayerTestResult<uint8_t, 4> ConstantUint8Test(armnn::IWorkloadFactory& workloadFactory)
4077 return ConstantTestImpl<uint8_t>(workloadFactory, 2e-6f, 1);
4080 LayerTestResult<uint8_t, 1> Concatenation1dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4082 return Concatenation1dTestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4085 LayerTestResult<uint8_t, 2> Concatenation2dDim0Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4087 return Concatenation2dDim0TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4090 LayerTestResult<uint8_t, 2> Concatenation2dDim1Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4092 return Concatenation2dDim1TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4095 LayerTestResult<uint8_t, 2> Concatenation2dDim0DiffInputDimsUint8Test(armnn::IWorkloadFactory& workloadFactory)
4097 return Concatenation2dDim0DiffInputDimsTestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4100 LayerTestResult<uint8_t, 2> Concatenation2dDim1DiffInputDimsUint8Test(armnn::IWorkloadFactory& workloadFactory)
4102 return Concatenation2dDim1DiffInputDimsTestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4105 LayerTestResult<uint8_t, 3> Concatenation3dDim0Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4107 return Concatenation3dDim0TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4110 LayerTestResult<uint8_t, 3> Concatenation3dDim1Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4112 return Concatenation3dDim1TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4115 LayerTestResult<uint8_t, 3> Concatenation3dDim2Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4117 return Concatenation3dDim2TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4120 LayerTestResult<uint8_t, 3> Concatenation3dDim0DiffInputDimsUint8Test(armnn::IWorkloadFactory& workloadFactory)
4122 return Concatenation3dDim0TestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4125 LayerTestResult<uint8_t, 3> Concatenation3dDim1DiffInputDimsUint8Test(armnn::IWorkloadFactory& workloadFactory)
4127 return Concatenation3dDim1DiffInputDimsTestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4130 LayerTestResult<uint8_t, 3> Concatenation3dDim2DiffInputDimsUint8Test(armnn::IWorkloadFactory& workloadFactory)
4132 return Concatenation3dDim2DiffInputDimsTestImpl<uint8_t>(workloadFactory, 0.5f, -1);
4135 LayerTestResult<float, 4> SimpleMaxPooling2dSize2x2Stride2x2Test(armnn::IWorkloadFactory& workloadFactory,
4136 bool forceNoPadding)
4138 return SimpleMaxPooling2dSize2x2Stride2x2TestCommon<float>(workloadFactory, forceNoPadding);
4141 LayerTestResult<uint8_t, 4> SimpleMaxPooling2dSize2x2Stride2x2Uint8Test(armnn::IWorkloadFactory& workloadFactory,
4142 bool forceNoPadding)
4144 return SimpleMaxPooling2dSize2x2Stride2x2TestCommon<uint8_t>(workloadFactory, forceNoPadding, 3.0f, -5);
4147 LayerTestResult<float, 4> SimpleMaxPooling2dSize3x3Stride2x4Test(armnn::IWorkloadFactory& workloadFactory,
4148 bool forceNoPadding)
4150 return SimpleMaxPooling2dSize3x3Stride2x4TestCommon<float>(workloadFactory, forceNoPadding);
4153 LayerTestResult<uint8_t, 4> SimpleMaxPooling2dSize3x3Stride2x4Uint8Test(armnn::IWorkloadFactory& workloadFactory,
4154 bool forceNoPadding)
4156 return SimpleMaxPooling2dSize3x3Stride2x4TestCommon<uint8_t>(workloadFactory, forceNoPadding, 0.1f, 128);
4159 LayerTestResult<float, 4> SimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4161 return SimpleAveragePooling2dTestCommon<float>(workloadFactory);
4164 LayerTestResult<uint8_t, 4> SimpleAveragePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4166 return SimpleAveragePooling2dTestCommon<uint8_t>(workloadFactory, 0.5, -1);
4169 LayerTestResult<float, 4> IgnorePaddingAveragePooling2dSize3x2Stride2x2Test(armnn::IWorkloadFactory& workloadFactory,
4170 bool forceNoPadding)
4172 return IgnorePaddingAveragePooling2dSize3x2Stride2x2TestCommon<float>(workloadFactory, forceNoPadding);
4175 LayerTestResult<float, 4> LargeTensorsAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4177 return LargeTensorsAveragePooling2dTestCommon<float>(workloadFactory);
4180 LayerTestResult<uint8_t, 4> LargeTensorsAveragePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4182 return LargeTensorsAveragePooling2dTestCommon<uint8_t>(workloadFactory, 0.5, -1);
4185 LayerTestResult<float, 4> SimpleL2Pooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4187 return SimpleL2Pooling2dTestCommon<float>(workloadFactory);
4190 LayerTestResult<uint8_t, 4> SimpleL2Pooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4192 return SimpleL2Pooling2dTestCommon<uint8_t>(workloadFactory);
4195 LayerTestResult<float, 4> L2Pooling2dSize3Stride1Test(armnn::IWorkloadFactory& workloadFactory)
4197 return L2Pooling2dSize3Stride1TestCommon<float>(workloadFactory);
4200 LayerTestResult<uint8_t, 4> L2Pooling2dSize3Stride1Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4202 return L2Pooling2dSize3Stride1TestCommon<uint8_t>(workloadFactory);
4205 LayerTestResult<float, 4> L2Pooling2dSize3Stride3Test(armnn::IWorkloadFactory& workloadFactory)
4207 return L2Pooling2dSize3Stride3TestCommon<float>(workloadFactory);
4210 LayerTestResult<uint8_t, 4> L2Pooling2dSize3Stride3Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4212 return L2Pooling2dSize3Stride3TestCommon<uint8_t>(workloadFactory);
4215 LayerTestResult<float, 4> L2Pooling2dSize3Stride4Test(armnn::IWorkloadFactory& workloadFactory)
4217 return L2Pooling2dSize3Stride4TestCommon<float>(workloadFactory);
4220 LayerTestResult<uint8_t, 4> L2Pooling2dSize3Stride4Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4222 return L2Pooling2dSize3Stride4TestCommon<uint8_t>(workloadFactory);
4225 LayerTestResult<float, 4> L2Pooling2dSize7Test(armnn::IWorkloadFactory& workloadFactory)
4227 return L2Pooling2dSize7TestCommon<float>(workloadFactory);
4230 LayerTestResult<uint8_t, 4> L2Pooling2dSize7Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4232 return L2Pooling2dSize7TestCommon<uint8_t>(workloadFactory);
4235 LayerTestResult<float, 4> L2Pooling2dSize9Test(armnn::IWorkloadFactory& workloadFactory)
4237 return L2Pooling2dSize9TestCommon<float>(workloadFactory);
4240 LayerTestResult<uint8_t, 4> L2Pooling2dSize9Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4242 return L2Pooling2dSize9TestCommon<uint8_t>(workloadFactory);
4245 LayerTestResult<float, 4> AsymmetricNonSquarePooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4247 return AsymmetricNonSquarePooling2dTestCommon<float>(workloadFactory);
4250 LayerTestResult<uint8_t, 4> AsymmetricNonSquarePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4252 return AsymmetricNonSquarePooling2dTestCommon<uint8_t>(workloadFactory);
4255 LayerTestResult<float, 4> ComparePooling2dTest(armnn::IWorkloadFactory& workloadFactory,
4256 armnn::IWorkloadFactory& refWorkloadFactory,
4257 armnn::PoolingAlgorithm poolingType)
4259 return ComparePooling2dTestCommon<float>(workloadFactory, refWorkloadFactory, poolingType);
4262 LayerTestResult<uint8_t, 4> ComparePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory,
4263 armnn::IWorkloadFactory& refWorkloadFactory,
4264 armnn::PoolingAlgorithm poolingType)
4266 return ComparePooling2dTestCommon<uint8_t>(workloadFactory, refWorkloadFactory, poolingType, 0.1f, 128);
4269 LayerTestResult<float, 2> FullyConnectedLargeTest(armnn::IWorkloadFactory& workloadFactory,
4270 bool transposeWeights)
4272 return FullyConnectedLargeTestCommon<float>(workloadFactory, transposeWeights);
4275 LayerTestResult<float, 4> IgnorePaddingSimpleMaxPooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4277 return IgnorePaddingSimpleMaxPooling2dTestCommon<float>(workloadFactory);
4280 LayerTestResult<uint8_t, 4> IgnorePaddingSimpleMaxPooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4282 return IgnorePaddingSimpleMaxPooling2dTestCommon<uint8_t>(workloadFactory, 1.0f, -5);
4285 LayerTestResult<float, 4> IgnorePaddingMaxPooling2dSize3Test(armnn::IWorkloadFactory& workloadFactory)
4287 return IgnorePaddingMaxPooling2dSize3TestCommon<float>(workloadFactory);
4290 LayerTestResult<uint8_t, 4> IgnorePaddingMaxPooling2dSize3Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4292 return IgnorePaddingMaxPooling2dSize3TestCommon<uint8_t>(workloadFactory, 1.0f, -5);
4295 LayerTestResult<float, 4> IgnorePaddingSimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4297 return IgnorePaddingSimpleAveragePooling2dTestCommon<float>(workloadFactory);
4300 LayerTestResult<uint8_t, 4> IgnorePaddingSimpleAveragePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4302 return IgnorePaddingSimpleAveragePooling2dTestCommon<uint8_t>(workloadFactory);
4305 LayerTestResult<float, 4> IgnorePaddingSimpleAveragePooling2dNoPaddingTest(armnn::IWorkloadFactory& workloadFactory)
4307 return IgnorePaddingSimpleAveragePooling2dNoPaddingTestCommon<float>(workloadFactory);
4310 LayerTestResult<uint8_t, 4> IgnorePaddingSimpleAveragePooling2dNoPaddingUint8Test(
4311 armnn::IWorkloadFactory& workloadFactory)
4313 return IgnorePaddingSimpleAveragePooling2dNoPaddingTestCommon<uint8_t>(workloadFactory);
4316 LayerTestResult<float, 4> IgnorePaddingAveragePooling2dSize3Test(armnn::IWorkloadFactory& workloadFactory)
4318 return IgnorePaddingAveragePooling2dSize3TestCommon<float>(workloadFactory);
4321 LayerTestResult<uint8_t, 4> IgnorePaddingAveragePooling2dSize3Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4323 return IgnorePaddingAveragePooling2dSize3TestCommon<uint8_t>(workloadFactory);
4326 LayerTestResult<float, 4> IgnorePaddingSimpleL2Pooling2dTest(armnn::IWorkloadFactory& workloadFactory)
4328 return IgnorePaddingSimpleL2Pooling2dTestCommon<float>(workloadFactory);
4331 LayerTestResult<uint8_t, 4> IgnorePaddingSimpleL2Pooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory)
4333 return IgnorePaddingSimpleL2Pooling2dTestCommon<uint8_t>(workloadFactory);
4336 LayerTestResult<float, 4> IgnorePaddingL2Pooling2dSize3Test(armnn::IWorkloadFactory& workloadFactory)
4338 return IgnorePaddingL2Pooling2dSize3TestCommon<float>(workloadFactory);
4341 LayerTestResult<uint8_t, 4> IgnorePaddingL2Pooling2dSize3Uint8Test(armnn::IWorkloadFactory& workloadFactory)
4343 return IgnorePaddingL2Pooling2dSize3TestCommon<uint8_t>(workloadFactory);
4346 LayerTestResult<float, 4> SimplePermuteFloat32Test(armnn::IWorkloadFactory& workloadFactory)
4348 return SimplePermuteFloat32TestCommon(workloadFactory);
4351 LayerTestResult<uint8_t, 4> SimplePermuteUint8Test(armnn::IWorkloadFactory& workloadFactory)
4353 return SimplePermuteUint8TestCommon(workloadFactory);
4356 LayerTestResult<float, 4> PermuteFloat32ValueSet1Test(armnn::IWorkloadFactory& workloadFactory)
4358 return PermuteFloat32ValueSet1TestCommon(workloadFactory);
4361 LayerTestResult<float, 4> PermuteFloat32ValueSet2Test(armnn::IWorkloadFactory& workloadFactory)
4363 return PermuteFloat32ValueSet2TestCommon(workloadFactory);
4366 LayerTestResult<float, 4> PermuteFloat32ValueSet3Test(armnn::IWorkloadFactory& workloadFactory)
4368 return PermuteFloat32ValueSet3TestCommon(workloadFactory);