From cec6b655d9f6ddb73c721ca47a7d67eeaad5c043 Mon Sep 17 00:00:00 2001 From: Nikhil Raj Date: Fri, 12 Oct 2018 13:51:57 +0100 Subject: IVGCVSW-1922 Unit test for DepthwiseConvolution with NHWC Change-Id: I3e6e5b9a62f30d03c05bd7178adea8f4c8275da8 --- src/backends/test/Conv2dTestImpl.hpp | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) mode change 100644 => 100755 src/backends/test/Conv2dTestImpl.hpp (limited to 'src/backends/test/Conv2dTestImpl.hpp') diff --git a/src/backends/test/Conv2dTestImpl.hpp b/src/backends/test/Conv2dTestImpl.hpp old mode 100644 new mode 100755 index 8e29615c47..d8c104007c --- a/src/backends/test/Conv2dTestImpl.hpp +++ b/src/backends/test/Conv2dTestImpl.hpp @@ -691,6 +691,106 @@ LayerTestResult DepthwiseConvolution2dTestImpl(armnn::IWorkloadFactory& wo return ret; } +template +LayerTestResult DepthwiseConvolution2dNhwcTestImpl(armnn::IWorkloadFactory& workloadFactory, + const boost::multi_array& input, + const boost::multi_array& kernel, + const boost::multi_array& bias, + const boost::multi_array& outputExpected, + float qScale, + int32_t qOffset, + uint32_t padLeft = 0, + uint32_t padTop = 0, + uint32_t padRight = 0, + uint32_t padBottom = 0, + uint32_t strideX = 1, + uint32_t strideY = 1) +{ + unsigned int inputNum = boost::numeric_cast(input.shape()[0]); + unsigned int inputChannels = boost::numeric_cast(input.shape()[3]); + unsigned int inputHeight = boost::numeric_cast(input.shape()[1]); + unsigned int inputWidth = boost::numeric_cast(input.shape()[2]); + + unsigned int kernelChanMul = boost::numeric_cast(kernel.shape()[0]); + unsigned int kernelChannels = boost::numeric_cast(kernel.shape()[3]); + unsigned int kernelHeight = boost::numeric_cast(kernel.shape()[1]); + unsigned int kernelWidth = boost::numeric_cast(kernel.shape()[2]); + + unsigned int outputNum = boost::numeric_cast(outputExpected.shape()[0]); + unsigned int outputChannels = boost::numeric_cast(outputExpected.shape()[3]); + unsigned int outputHeight = boost::numeric_cast(outputExpected.shape()[1]); + unsigned int outputWidth = boost::numeric_cast(outputExpected.shape()[2]); + + // Creates the tensors. + armnn::TensorInfo inputTensorInfo({inputNum, inputHeight, inputWidth, inputChannels}, armnn::GetDataType()); + armnn::TensorInfo outputTensorInfo({outputNum, outputHeight, outputWidth, outputChannels}, + armnn::GetDataType()); + armnn::TensorInfo kernelDesc({kernelChanMul, kernelHeight, kernelWidth, kernelChannels}, armnn::GetDataType()); + armnn::TensorInfo biasDesc({static_cast(bias.size())}, 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); + kernelDesc.SetQuantizationScale(qScale); + kernelDesc.SetQuantizationOffset(qOffset); + biasDesc.SetQuantizationScale(qScale*qScale); + biasDesc.SetQuantizationOffset(0); + } + + // Construct the input data. + std::vector inputData; + inputData.assign(input.data(), input.data() + inputHeight*inputWidth*inputChannels); + auto batchedInput = MakeTensor(inputTensorInfo, inputData); + + // Construct the output data, with bias applied, as appropriate. + std::vector outputData; + outputData.assign(outputExpected.data(), outputExpected.data() + outputHeight*outputWidth*outputChannels); + + LayerTestResult ret(outputTensorInfo); + ret.outputExpected = MakeTensor(outputTensorInfo, outputData); + + std::unique_ptr inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo); + std::unique_ptr outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo); + + armnn::ScopedCpuTensorHandle weightsTensor(kernelDesc); + AllocateAndCopyDataToITensorHandle(&weightsTensor, &kernel[0][0][0][0]); + + armnn::ScopedCpuTensorHandle biasTensor(biasDesc); + + armnn::DepthwiseConvolution2dQueueDescriptor data; + data.m_Weight = &weightsTensor; + data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - it can be a source of bugs. + data.m_Parameters.m_StrideX = strideX; + data.m_Parameters.m_StrideY = strideY; + data.m_Parameters.m_PadLeft = padLeft; + data.m_Parameters.m_PadRight = padRight; + data.m_Parameters.m_PadTop = padTop; + data.m_Parameters.m_PadBottom = padBottom; + data.m_Parameters.m_DataLayout = armnn::DataLayout::NHWC; + + armnn::WorkloadInfo info; + AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get()); + AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get()); + + std::unique_ptr workload = workloadFactory.CreateDepthwiseConvolution2d(data, info); + + inputHandle->Allocate(); + outputHandle->Allocate(); + + CopyDataToITensorHandle(inputHandle.get(), &batchedInput[0][0][0][0]); + + workloadFactory.Finalize(); + workload->Execute(); + + CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get()); + + return ret; +} + template LayerTestResult Convolution1dTestImpl(armnn::IWorkloadFactory& workloadFactory, float qScale, -- cgit v1.2.1