From 043d0d0e07e0a29648894cb9ba68993e540bb94d Mon Sep 17 00:00:00 2001 From: Francis Murtagh Date: Fri, 5 Oct 2018 14:08:48 +0100 Subject: IVGCVSW-1860 Support NHWC for Pooling2D Change-Id: I9059a292e47867df82a5efbba5808fd264949ec9 --- src/backends/test/Pooling2dTestImpl.hpp | 135 +++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 9 deletions(-) (limited to 'src/backends/test/Pooling2dTestImpl.hpp') diff --git a/src/backends/test/Pooling2dTestImpl.hpp b/src/backends/test/Pooling2dTestImpl.hpp index c87548cd5b..7366bcaf44 100644 --- a/src/backends/test/Pooling2dTestImpl.hpp +++ b/src/backends/test/Pooling2dTestImpl.hpp @@ -5,25 +5,23 @@ #pragma once #include -#include -#include #include #include "QuantizeHelper.hpp" #include #include - +#include #include template LayerTestResult SimplePooling2dTestImpl( - armnn::IWorkloadFactory& workloadFactory, - armnn::Pooling2dDescriptor descriptor, - float qScale, - int32_t qOffset, - const boost::multi_array& input, - const boost::multi_array& outputExpected) + 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]); @@ -88,6 +86,80 @@ LayerTestResult SimplePooling2dTestImpl( 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()); + + // 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; + queueDescriptor.m_Parameters.m_DataLayout = armnn::DataLayout::NHWC; + + 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) + { + return result; + } + + 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; +} + // // Tests max pooling with the following parameters: // @@ -262,6 +334,51 @@ LayerTestResult SimpleAveragePooling2dTestCommon(armnn::IWorkloadFactory& return SimplePooling2dTestImpl(workloadFactory, descriptor, qScale, qOffset, input, outputExpected); } +template +LayerTestResult SimpleAveragePooling2dNhwcTestCommon(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); + } + + 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, + })); + + 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, + })); + + return SimplePooling2dNhwcTestImpl(workloadFactory, descriptor, qScale, qOffset, input, outputExpected); +} + template LayerTestResult LargeTensorsAveragePooling2dTestCommon(armnn::IWorkloadFactory& workloadFactory, float qScale = 1.0f, -- cgit v1.2.1