From 69482271d3e02af950d2d0f1947ae6c3eeed537b Mon Sep 17 00:00:00 2001 From: James Conroy Date: Fri, 19 Oct 2018 10:41:35 +0100 Subject: IVGCVSW-2024: Support NHWC for Pooling2D CpuRef * Adds implementation to plumb DataLayout parameter for Pooling2D on CpuRef. * Adds unit tests to execute Pooling2D on CpuRef using NHWC data layout. * Refactors original tests to use DataLayoutIndexed and removes duplicate code. Change-Id: Ife7e0861a886cf58a2042e5be20e5b27af4528c9 --- include/armnn/Descriptors.hpp | 2 +- src/armnn/test/CreateWorkload.hpp | 4 +- src/backends/cl/test/ClCreateWorkloadTests.cpp | 3 +- src/backends/cl/workloads/ClPooling2dWorkload.cpp | 8 +- .../neon/workloads/NeonPooling2dWorkload.cpp | 8 +- .../reference/test/RefCreateWorkloadTests.cpp | 50 ++++-- src/backends/reference/test/RefLayerTests.cpp | 2 + src/backends/reference/workloads/Pooling2d.cpp | 14 +- src/backends/test/LayerTests.cpp | 11 +- src/backends/test/LayerTests.hpp | 1 + src/backends/test/Pooling2dTestImpl.hpp | 177 ++++++--------------- 11 files changed, 125 insertions(+), 155 deletions(-) diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index a7eca43da3..648477e09b 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -194,7 +194,7 @@ struct Pooling2dDescriptor uint32_t m_StrideY; OutputShapeRounding m_OutputShapeRounding; PaddingMethod m_PaddingMethod; - DataLayout m_DataLayout; + DataLayoutIndexed m_DataLayout; }; struct FullyConnectedDescriptor diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp index 01c5e9f689..aac0a4ae6d 100644 --- a/src/armnn/test/CreateWorkload.hpp +++ b/src/armnn/test/CreateWorkload.hpp @@ -609,6 +609,7 @@ std::unique_ptr CreatePooling2dWorkloadTest(armnn::IWorkloadF BOOST_TEST(queueDescriptor.m_Parameters.m_PadRight == 2); BOOST_TEST(queueDescriptor.m_Parameters.m_PadTop == 1); BOOST_TEST(queueDescriptor.m_Parameters.m_PadBottom == 1); + BOOST_TEST((queueDescriptor.m_Parameters.m_DataLayout == dataLayout)); BOOST_TEST(queueDescriptor.m_Inputs.size() == 1); BOOST_TEST(queueDescriptor.m_Outputs.size() == 1); @@ -856,7 +857,8 @@ std::unique_ptr CreateResizeBilinearWorkloadTest(armnn:: inputShape = { 2, 4, 4, 3 }; outputShape = { 2, 2, 2, 3 }; break; - default: // NCHW + case DataLayout::NCHW: + default: inputShape = { 2, 3, 4, 4 }; outputShape = { 2, 3, 2, 2 }; } diff --git a/src/backends/cl/test/ClCreateWorkloadTests.cpp b/src/backends/cl/test/ClCreateWorkloadTests.cpp index b5fc031461..4f9989405d 100644 --- a/src/backends/cl/test/ClCreateWorkloadTests.cpp +++ b/src/backends/cl/test/ClCreateWorkloadTests.cpp @@ -712,7 +712,8 @@ static void ClResizeBilinearWorkloadTest(DataLayout dataLayout) BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 })); BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 2, 2, 3 })); break; - default: // NCHW + case DataLayout::NCHW: + default: BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 })); BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 2, 2 })); } diff --git a/src/backends/cl/workloads/ClPooling2dWorkload.cpp b/src/backends/cl/workloads/ClPooling2dWorkload.cpp index 255f57341e..68512ff980 100644 --- a/src/backends/cl/workloads/ClPooling2dWorkload.cpp +++ b/src/backends/cl/workloads/ClPooling2dWorkload.cpp @@ -19,8 +19,10 @@ arm_compute::Status ClPooling2dWorkloadValidate(const TensorInfo& input, const TensorInfo& output, const Pooling2dDescriptor& descriptor) { - const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout); - const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout); + const arm_compute::TensorInfo aclInputInfo = + BuildArmComputeTensorInfo(input, descriptor.m_DataLayout.GetDataLayout()); + const arm_compute::TensorInfo aclOutputInfo = + BuildArmComputeTensorInfo(output, descriptor.m_DataLayout.GetDataLayout()); arm_compute::PoolingLayerInfo layerInfo = BuildArmComputePoolingLayerInfo(descriptor); @@ -36,7 +38,7 @@ ClPooling2dWorkload::ClPooling2dWorkload( arm_compute::ICLTensor& input = static_cast(m_Data.m_Inputs[0])->GetTensor(); arm_compute::ICLTensor& output = static_cast(m_Data.m_Outputs[0])->GetTensor(); - arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout); + arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout.GetDataLayout()); input.info()->set_data_layout(aclDataLayout); output.info()->set_data_layout(aclDataLayout); diff --git a/src/backends/neon/workloads/NeonPooling2dWorkload.cpp b/src/backends/neon/workloads/NeonPooling2dWorkload.cpp index 7892b3a315..a4ed33b3fa 100644 --- a/src/backends/neon/workloads/NeonPooling2dWorkload.cpp +++ b/src/backends/neon/workloads/NeonPooling2dWorkload.cpp @@ -17,8 +17,10 @@ arm_compute::Status NeonPooling2dWorkloadValidate(const TensorInfo& input, const TensorInfo& output, const Pooling2dDescriptor& descriptor) { - const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout); - const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout); + const arm_compute::TensorInfo aclInputInfo = + BuildArmComputeTensorInfo(input, descriptor.m_DataLayout.GetDataLayout()); + const arm_compute::TensorInfo aclOutputInfo = + BuildArmComputeTensorInfo(output, descriptor.m_DataLayout.GetDataLayout()); arm_compute::PoolingLayerInfo layerInfo = BuildArmComputePoolingLayerInfo(descriptor); @@ -34,7 +36,7 @@ NeonPooling2dWorkload::NeonPooling2dWorkload( arm_compute::ITensor& input = boost::polymorphic_downcast(m_Data.m_Inputs[0])->GetTensor(); arm_compute::ITensor& output = boost::polymorphic_downcast(m_Data.m_Outputs[0])->GetTensor(); - arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout); + arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout.GetDataLayout()); input.info()->set_data_layout(aclDataLayout); output.info()->set_data_layout(aclDataLayout); diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp index 8bad5497a2..d9322709b2 100644 --- a/src/backends/reference/test/RefCreateWorkloadTests.cpp +++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp @@ -308,27 +308,51 @@ BOOST_AUTO_TEST_CASE(CreateRefNormalizationNhwcWorkload) } template -static void RefCreatePooling2dWorkloadTest() +static void RefCreatePooling2dWorkloadTest(DataLayout dataLayout) { Graph graph; RefWorkloadFactory factory; - auto workload = CreatePooling2dWorkloadTest(factory, graph); + auto workload = CreatePooling2dWorkloadTest(factory, graph, dataLayout); + + TensorShape inputShape; + TensorShape outputShape; + + switch (dataLayout) + { + case DataLayout::NHWC: + inputShape = { 3, 5, 5, 2 }; + outputShape = { 3, 2, 4, 2 }; + break; + case DataLayout::NCHW: + default: + inputShape = { 3, 2, 5, 5 }; + outputShape = { 3, 2, 2, 4 }; + } // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest). - CheckInputOutput( - std::move(workload), - TensorInfo({3, 2, 5, 5}, DataType), - TensorInfo({3, 2, 2, 4}, DataType)); + CheckInputOutput(std::move(workload), + TensorInfo(inputShape, DataType), + TensorInfo(outputShape, DataType)); } BOOST_AUTO_TEST_CASE(CreatePooling2dFloat32Workload) { - RefCreatePooling2dWorkloadTest(); + RefCreatePooling2dWorkloadTest(DataLayout::NCHW); +} + +BOOST_AUTO_TEST_CASE(CreatePooling2dFloat32NhwcWorkload) +{ + RefCreatePooling2dWorkloadTest(DataLayout::NHWC); } BOOST_AUTO_TEST_CASE(CreatePooling2dUint8Workload) { - RefCreatePooling2dWorkloadTest(); + RefCreatePooling2dWorkloadTest(DataLayout::NCHW); +} + +BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload) +{ + RefCreatePooling2dWorkloadTest(DataLayout::NHWC); } template @@ -496,16 +520,16 @@ static void RefCreateResizeBilinearTest(DataLayout dataLayout) inputShape = { 2, 4, 4, 3 }; outputShape = { 2, 2, 2, 3 }; break; - default: // NCHW + case DataLayout::NCHW: + default: inputShape = { 2, 3, 4, 4 }; outputShape = { 2, 3, 2, 2 }; } // Checks that outputs and inputs are as we expect them (see definition of CreateResizeBilinearWorkloadTest). - CheckInputOutput( - std::move(workload), - TensorInfo(inputShape, DataType), - TensorInfo(outputShape, DataType)); + CheckInputOutput(std::move(workload), + TensorInfo(inputShape, DataType), + TensorInfo(outputShape, DataType)); } BOOST_AUTO_TEST_CASE(CreateResizeBilinearFloat32) diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index 9f044cdbaf..30f5b10b0e 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -80,7 +80,9 @@ ARMNN_AUTO_TEST_CASE(IgnorePaddingL2Pooling2dSize3, IgnorePaddingL2Pooling2dSize ARMNN_AUTO_TEST_CASE(IgnorePaddingL2Pooling2dSize3Uint8, IgnorePaddingL2Pooling2dSize3Uint8Test) ARMNN_AUTO_TEST_CASE(SimpleAveragePooling2d, SimpleAveragePooling2dTest) +ARMNN_AUTO_TEST_CASE(SimpleAveragePooling2dNhwc, SimpleAveragePooling2dNhwcTest) ARMNN_AUTO_TEST_CASE(SimpleAveragePooling2dUint8, SimpleAveragePooling2dUint8Test) +ARMNN_AUTO_TEST_CASE(SimpleAveragePooling2dUint8Nhwc, SimpleAveragePooling2dUint8NhwcTest) ARMNN_AUTO_TEST_CASE(IgnorePaddingAveragePooling2dSize3x2Stride2x2, IgnorePaddingAveragePooling2dSize3x2Stride2x2Test, false) ARMNN_AUTO_TEST_CASE(IgnorePaddingAveragePooling2dSize3x2Stride2x2NoPadding, diff --git a/src/backends/reference/workloads/Pooling2d.cpp b/src/backends/reference/workloads/Pooling2d.cpp index 5812a290e7..9890920113 100644 --- a/src/backends/reference/workloads/Pooling2d.cpp +++ b/src/backends/reference/workloads/Pooling2d.cpp @@ -143,12 +143,16 @@ void Pooling2d(const float* in, const TensorInfo& outputInfo, const Pooling2dDescriptor& params) { + const unsigned int channelsIndex = params.m_DataLayout.GetChannelsIndex(); + const unsigned int heightIndex = params.m_DataLayout.GetHeightIndex(); + const unsigned int widthIndex = params.m_DataLayout.GetWidthIndex(); + const int batchSize = boost::numeric_cast(outputInfo.GetShape()[0]); - const int channels = boost::numeric_cast(outputInfo.GetShape()[1]); - const int heightOutput = boost::numeric_cast(outputInfo.GetShape()[2]); - const int widthOutput = boost::numeric_cast(outputInfo.GetShape()[3]); - const int heightInput = boost::numeric_cast(inputInfo.GetShape()[2]); - const int widthInput = boost::numeric_cast(inputInfo.GetShape()[3]); + const int channels = boost::numeric_cast(outputInfo.GetShape()[channelsIndex]); + const int heightOutput = boost::numeric_cast(outputInfo.GetShape()[heightIndex]); + const int widthOutput = boost::numeric_cast(outputInfo.GetShape()[widthIndex]); + const int heightInput = boost::numeric_cast(inputInfo.GetShape()[heightIndex]); + const int widthInput = boost::numeric_cast(inputInfo.GetShape()[widthIndex]); const int padLeft = boost::numeric_cast(params.m_PadLeft); const int padRight = boost::numeric_cast(params.m_PadRight); const int padTop = boost::numeric_cast(params.m_PadTop); diff --git a/src/backends/test/LayerTests.cpp b/src/backends/test/LayerTests.cpp index e762152b67..5c7a887552 100755 --- a/src/backends/test/LayerTests.cpp +++ b/src/backends/test/LayerTests.cpp @@ -5585,17 +5585,22 @@ LayerTestResult SimpleMaxPooling2dSize3x3Stride2x4Uint8Test(armnn::I LayerTestResult SimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory) { - return SimpleAveragePooling2dTestCommon(workloadFactory); + return SimpleAveragePooling2dTest(workloadFactory); } LayerTestResult SimpleAveragePooling2dNhwcTest(armnn::IWorkloadFactory& workloadFactory) { - return SimpleAveragePooling2dNhwcTestCommon(workloadFactory); + return SimpleAveragePooling2dNhwcTest(workloadFactory); } LayerTestResult SimpleAveragePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory) { - return SimpleAveragePooling2dTestCommon(workloadFactory, 0.5, -1); + return SimpleAveragePooling2dTest(workloadFactory, 0.5, -1); +} + +LayerTestResult SimpleAveragePooling2dUint8NhwcTest(armnn::IWorkloadFactory& workloadFactory) +{ + return SimpleAveragePooling2dNhwcTest(workloadFactory, 0.5, -1); } LayerTestResult IgnorePaddingAveragePooling2dSize3x2Stride2x2Test(armnn::IWorkloadFactory& workloadFactory, diff --git a/src/backends/test/LayerTests.hpp b/src/backends/test/LayerTests.hpp index 5790869366..9aae5da6e0 100644 --- a/src/backends/test/LayerTests.hpp +++ b/src/backends/test/LayerTests.hpp @@ -93,6 +93,7 @@ LayerTestResult IgnorePaddingMaxPooling2dSize3Uint8Test(armnn::IWork LayerTestResult SimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory); LayerTestResult SimpleAveragePooling2dNhwcTest(armnn::IWorkloadFactory& workloadFactory); LayerTestResult SimpleAveragePooling2dUint8Test(armnn::IWorkloadFactory& workloadFactory); +LayerTestResult SimpleAveragePooling2dUint8NhwcTest(armnn::IWorkloadFactory& workloadFactory); LayerTestResult IgnorePaddingAveragePooling2dSize3x2Stride2x2Test(armnn::IWorkloadFactory& workloadFactory, bool forceNoPadding); LayerTestResult IgnorePaddingSimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory); diff --git a/src/backends/test/Pooling2dTestImpl.hpp b/src/backends/test/Pooling2dTestImpl.hpp index 7366bcaf44..29263af9bc 100644 --- a/src/backends/test/Pooling2dTestImpl.hpp +++ b/src/backends/test/Pooling2dTestImpl.hpp @@ -15,100 +15,44 @@ #include template -LayerTestResult SimplePooling2dTestImpl( - armnn::IWorkloadFactory& workloadFactory, +LayerTestResult SimplePooling2dTestImpl(armnn::IWorkloadFactory& workloadFactory, armnn::Pooling2dDescriptor descriptor, float qScale, int32_t qOffset, const boost::multi_array& input, const boost::multi_array& outputExpected) { - unsigned int inputHeight = boost::numeric_cast(input.shape()[2]); - unsigned int inputWidth = boost::numeric_cast(input.shape()[3]); - unsigned int inputChannels = boost::numeric_cast(input.shape()[1]); - unsigned int inputBatchSize = boost::numeric_cast(input.shape()[0]); - - unsigned int outputHeight = boost::numeric_cast(outputExpected.shape()[2]); - unsigned int outputWidth = boost::numeric_cast(outputExpected.shape()[3]); - unsigned int outputChannels = boost::numeric_cast(outputExpected.shape()[1]); + const unsigned int channelsIndex = descriptor.m_DataLayout.GetChannelsIndex(); + const unsigned int heightIndex = descriptor.m_DataLayout.GetHeightIndex(); + const unsigned int widthIndex = descriptor.m_DataLayout.GetWidthIndex(); + + unsigned int inputHeight = boost::numeric_cast(input.shape()[heightIndex]); + unsigned int inputWidth = boost::numeric_cast(input.shape()[widthIndex]); + unsigned int inputChannels = boost::numeric_cast(input.shape()[channelsIndex]); + unsigned int inputBatchSize = boost::numeric_cast(input.shape()[0]); + + unsigned int outputHeight = boost::numeric_cast(outputExpected.shape()[heightIndex]); + unsigned int outputWidth = boost::numeric_cast(outputExpected.shape()[widthIndex]); + unsigned int outputChannels = boost::numeric_cast(outputExpected.shape()[channelsIndex]); unsigned int outputBatchSize = boost::numeric_cast(outputExpected.shape()[0]); - armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth }, - armnn::GetDataType()); - armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth }, - armnn::GetDataType()); + armnn::TensorShape inputTensorShape; + armnn::TensorShape outputTensorShape; - // Set quantization parameters if the requested type is a quantized type. - if(armnn::IsQuantizedType()) - { - inputTensorInfo.SetQuantizationScale(qScale); - inputTensorInfo.SetQuantizationOffset(qOffset); - outputTensorInfo.SetQuantizationScale(qScale); - outputTensorInfo.SetQuantizationOffset(qOffset); - } - - LayerTestResult result(outputTensorInfo); - - std::unique_ptr inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo); - std::unique_ptr outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo); - - armnn::Pooling2dQueueDescriptor queueDescriptor; - queueDescriptor.m_Parameters = descriptor; - armnn::WorkloadInfo workloadInfo; - AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get()); - AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get()); - - // Don't execute if Pooling is not supported, as an exception will be raised. - armnn::Compute compute = workloadFactory.GetCompute(); - const size_t reasonIfUnsupportedMaxLen = 255; - char reasonIfUnsupported[reasonIfUnsupportedMaxLen+1]; - result.supported = armnn::IsPooling2dSupported(compute, inputTensorInfo, outputTensorInfo, - queueDescriptor.m_Parameters, - reasonIfUnsupported, reasonIfUnsupportedMaxLen); - if (!result.supported) + switch (descriptor.m_DataLayout.GetDataLayout()) { - return result; + case armnn::DataLayout::NHWC: + inputTensorShape = { inputBatchSize, inputHeight, inputWidth, inputChannels }; + outputTensorShape = { outputBatchSize, outputHeight, outputWidth, outputChannels }; + break; + case armnn::DataLayout::NCHW: + default: + inputTensorShape = { inputBatchSize, inputChannels, inputHeight, inputWidth }; + outputTensorShape = { outputBatchSize, outputChannels, outputHeight, outputWidth }; } - std::unique_ptr workload = workloadFactory.CreatePooling2d(queueDescriptor, workloadInfo); - - inputHandle->Allocate(); - outputHandle->Allocate(); - - CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]); - - workload->Execute(); - - CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get()); - - result.outputExpected = outputExpected; - - return result; -} - -template -LayerTestResult SimplePooling2dNhwcTestImpl( - armnn::IWorkloadFactory& workloadFactory, - armnn::Pooling2dDescriptor descriptor, - float qScale, - int32_t qOffset, - const boost::multi_array& input, - const boost::multi_array& outputExpected) -{ - unsigned int inputHeight = boost::numeric_cast(input.shape()[1]); - unsigned int inputWidth = boost::numeric_cast(input.shape()[2]); - unsigned int inputChannels = boost::numeric_cast(input.shape()[3]); - unsigned int inputBatchSize = boost::numeric_cast(input.shape()[0]); - - unsigned int outputHeight = boost::numeric_cast(outputExpected.shape()[1]); - unsigned int outputWidth = boost::numeric_cast(outputExpected.shape()[2]); - unsigned int outputChannels = boost::numeric_cast(outputExpected.shape()[3]); - unsigned int outputBatchSize = boost::numeric_cast(outputExpected.shape()[0]); - - armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputHeight, inputWidth, inputChannels }, - armnn::GetDataType()); - armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputHeight, outputWidth, outputChannels }, - armnn::GetDataType()); + armnn::TensorInfo inputTensorInfo(inputTensorShape, armnn::GetDataType()); + armnn::TensorInfo outputTensorInfo(outputTensorShape, armnn::GetDataType()); // Set quantization parameters if the requested type is a quantized type. if(armnn::IsQuantizedType()) @@ -126,7 +70,7 @@ LayerTestResult SimplePooling2dNhwcTestImpl( armnn::Pooling2dQueueDescriptor queueDescriptor; queueDescriptor.m_Parameters = descriptor; - queueDescriptor.m_Parameters.m_DataLayout = armnn::DataLayout::NHWC; + queueDescriptor.m_Parameters.m_DataLayout = descriptor.m_DataLayout; armnn::WorkloadInfo workloadInfo; AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get()); @@ -291,6 +235,9 @@ LayerTestResult SimpleMaxPooling2dSize3x3Stride2x4TestCommon(armnn::IWorkl template LayerTestResult SimpleAveragePooling2dTestCommon(armnn::IWorkloadFactory& workloadFactory, + const armnn::TensorShape& inputTensorShape, + const armnn::TensorShape& outputTensorShape, + armnn::DataLayout dataLayout, float qScale = 1.0f, int32_t qOffset = 0) { @@ -303,9 +250,10 @@ LayerTestResult SimpleAveragePooling2dTestCommon(armnn::IWorkloadFactory& descriptor.m_PadTop = 1; descriptor.m_PadBottom = 1; descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude; + descriptor.m_DataLayout = dataLayout; - armnn::TensorInfo inputTensorInfo({ 1, 1, 4, 4 }, armnn::GetDataType()); - armnn::TensorInfo outputTensorInfo({ 1, 1, 3, 3 }, armnn::GetDataType()); + armnn::TensorInfo inputTensorInfo(inputTensorShape, armnn::GetDataType()); + armnn::TensorInfo outputTensorInfo(outputTensorShape, armnn::GetDataType()); // Set quantization parameters if the requested type is a quantized type. if(armnn::IsQuantizedType()) @@ -335,54 +283,33 @@ LayerTestResult SimpleAveragePooling2dTestCommon(armnn::IWorkloadFactory& } template -LayerTestResult SimpleAveragePooling2dNhwcTestCommon(armnn::IWorkloadFactory& workloadFactory, - float qScale = 1.0f, - int32_t qOffset = 0) +LayerTestResult SimpleAveragePooling2dTest(armnn::IWorkloadFactory& workloadFactory, + float qScale = 1.0f, + int32_t qOffset = 0) { - armnn::Pooling2dDescriptor descriptor; - descriptor.m_PoolType = armnn::PoolingAlgorithm::Average; - descriptor.m_PoolWidth = descriptor.m_PoolHeight = 2; - descriptor.m_StrideX = descriptor.m_StrideY = 2; - descriptor.m_PadLeft = 1; - descriptor.m_PadRight = 1; - descriptor.m_PadTop = 1; - descriptor.m_PadBottom = 1; - descriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude; - - armnn::TensorInfo inputTensorInfo({ 1, 4, 4, 1 }, armnn::GetDataType()); - armnn::TensorInfo outputTensorInfo({ 1, 3, 3, 1 }, armnn::GetDataType()); - - // Set quantization parameters if the requested type is a quantized type. - if(armnn::IsQuantizedType()) - { - inputTensorInfo.SetQuantizationScale(qScale); - inputTensorInfo.SetQuantizationOffset(qOffset); - outputTensorInfo.SetQuantizationScale(qScale); - outputTensorInfo.SetQuantizationOffset(qOffset); - } + const armnn::TensorShape inputTensorShape { 1, 1, 4, 4 }; + const armnn::TensorShape outputTensorShape { 1, 1, 3, 3 }; - auto input = MakeTensor(inputTensorInfo, - QuantizedVector(qScale, qOffset, { - 1.0f, 2.0f, 3.0f, 4.0f, - 1.0f, 2.0f, 3.0f, 4.0f, - 1.0f, 2.0f, 3.0f, 4.0f, - 1.0f, 2.0f, 3.0f, 4.0f, - })); + return SimpleAveragePooling2dTestCommon(workloadFactory, inputTensorShape, outputTensorShape, + armnn::DataLayout::NCHW, qScale, qOffset); +} - auto outputExpected = MakeTensor(outputTensorInfo, - QuantizedVector(qScale, qOffset, { - 1.0f, 2.5f, 4.0f, - 1.0f, 2.5f, 4.0f, - 1.0f, 2.5f, 4.0f, - })); +template +LayerTestResult SimpleAveragePooling2dNhwcTest(armnn::IWorkloadFactory& workloadFactory, + float qScale = 1.0f, + int32_t qOffset = 0) +{ + const armnn::TensorShape inputTensorShape { 1, 4, 4, 1 }; + const armnn::TensorShape outputTensorShape { 1, 3, 3, 1 }; - return SimplePooling2dNhwcTestImpl(workloadFactory, descriptor, qScale, qOffset, input, outputExpected); + return SimpleAveragePooling2dTestCommon(workloadFactory, inputTensorShape, outputTensorShape, + armnn::DataLayout::NHWC, qScale, qOffset); } template LayerTestResult LargeTensorsAveragePooling2dTestCommon(armnn::IWorkloadFactory& workloadFactory, - float qScale = 1.0f, - int32_t qOffset = 0) + float qScale = 1.0f, + int32_t qOffset = 0) { armnn::Pooling2dDescriptor descriptor; descriptor.m_PoolType = armnn::PoolingAlgorithm::Average; -- cgit v1.2.1