From 9b3983299f882c8d84c5abd0d40ca75a801ea7f2 Mon Sep 17 00:00:00 2001 From: Mike Kelly Date: Wed, 22 May 2019 17:21:49 +0100 Subject: IVGCVSW-3025: Refactor reference Convolution2d workload * Refactored RefConvolution2dWorkload to support all DataTypes through Encoders and Decoders. * Added Convolute function to ConvImpl that uses Encoders and Decoders to support all DataTypes. * Deleted RefConvolution2dFloat32Workload and RefConvolution2dUint8Workload. Signed-off-by: Mike Kelly Signed-off-by: Teresa Charlin Change-Id: Ic5ef0f499d08b948fa65fdee54b5f681fd0b1c05 --- .../backendsCommon/test/Conv2dTestImpl.hpp | 1 + src/backends/backendsCommon/test/LayerTests.cpp | 18 +-- .../backendsCommon/test/WorkloadTestUtils.hpp | 3 + src/backends/reference/RefWorkloadFactory.cpp | 2 +- src/backends/reference/backend.mk | 3 +- .../reference/test/RefCreateWorkloadTests.cpp | 2 +- src/backends/reference/workloads/BaseIterator.hpp | 15 ++ src/backends/reference/workloads/CMakeLists.txt | 6 +- src/backends/reference/workloads/ConvImpl.cpp | 173 +++++++++++++++++++++ src/backends/reference/workloads/ConvImpl.hpp | 19 +++ src/backends/reference/workloads/Decoders.hpp | 6 + .../workloads/RefConvolution2dFloat32Workload.cpp | 35 ----- .../workloads/RefConvolution2dFloat32Workload.hpp | 27 ---- .../workloads/RefConvolution2dUint8Workload.cpp | 42 ----- .../workloads/RefConvolution2dUint8Workload.hpp | 28 ---- .../workloads/RefConvolution2dWorkload.cpp | 53 +++++++ .../workloads/RefConvolution2dWorkload.hpp | 41 +++++ src/backends/reference/workloads/RefWorkloads.hpp | 3 +- 18 files changed, 326 insertions(+), 151 deletions(-) delete mode 100644 src/backends/reference/workloads/RefConvolution2dFloat32Workload.cpp delete mode 100644 src/backends/reference/workloads/RefConvolution2dFloat32Workload.hpp delete mode 100644 src/backends/reference/workloads/RefConvolution2dUint8Workload.cpp delete mode 100644 src/backends/reference/workloads/RefConvolution2dUint8Workload.hpp create mode 100644 src/backends/reference/workloads/RefConvolution2dWorkload.cpp create mode 100644 src/backends/reference/workloads/RefConvolution2dWorkload.hpp diff --git a/src/backends/backendsCommon/test/Conv2dTestImpl.hpp b/src/backends/backendsCommon/test/Conv2dTestImpl.hpp index bb5656bd01..0533c77d53 100644 --- a/src/backends/backendsCommon/test/Conv2dTestImpl.hpp +++ b/src/backends/backendsCommon/test/Conv2dTestImpl.hpp @@ -1125,6 +1125,7 @@ LayerTestResult CompareConvolution2dTestImpl( ExecuteWorkload(*workload, memoryManager); + workloadRef->PostAllocationConfigure(); workloadRef->Execute(); CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get()); diff --git a/src/backends/backendsCommon/test/LayerTests.cpp b/src/backends/backendsCommon/test/LayerTests.cpp index 5d059598a5..c94dc53291 100644 --- a/src/backends/backendsCommon/test/LayerTests.cpp +++ b/src/backends/backendsCommon/test/LayerTests.cpp @@ -79,12 +79,12 @@ static std::vector Bias2({0, 2}); // Helper function that returns either Bias2 or an empty vector depending on whether bias is enabled. template> -boost::multi_array GetBias2(bool biasEnabled, float qScale, int32_t qOffset) +boost::multi_array GetBias2(bool biasEnabled, float qScale) { if(biasEnabled) { armnn::TensorInfo biasDesc({static_cast(Bias2.size())}, ArmnnType); - boost::multi_array bias = MakeTensor(biasDesc, QuantizedVector(qScale, qOffset, Bias2)); + boost::multi_array bias = MakeTensor(biasDesc, QuantizedVector(qScale, 0.0f, Bias2)); return bias; } else @@ -170,7 +170,7 @@ LayerTestResult SimpleConvolution2d3x5TestCommon( memoryManager, input, kernel, - GetBias2(biasEnabled, qScale, qOffset), + GetBias2(biasEnabled, qScale * qScale), expectedOutput, qScale, qOffset, @@ -247,7 +247,7 @@ LayerTestResult SimpleConvolution2d3x3TestCommon( memoryManager, input, kernel, - GetBias2(biasEnabled, qScale, qOffset), + GetBias2(biasEnabled, qScale * qScale), expectedOutput, qScale, qOffset, @@ -494,7 +494,7 @@ LayerTestResult Convolution2dAsymmetricPaddingLargerThanHalfKernelSizeTest memoryManager, input, kernel, - GetBias2(false, qScale, qOffset), + GetBias2(false, qScale * qScale), expectedOutput, qScale, qOffset, @@ -552,7 +552,7 @@ LayerTestResult SimpleConvolution2dAsymmetricPaddingTestCommon( memoryManager, input, kernel, - GetBias2(false, qScale, qOffset), + GetBias2(false, qScale * qScale), expectedOutput, qScale, qOffset, @@ -627,7 +627,7 @@ LayerTestResult DepthwiseConvolution2dAsymmetricTestCommon( memoryManager, input, kernel, - GetBias2(biasEnabled, qScale, qOffset), + GetBias2(biasEnabled, qScale * qScale), expectedOutput, qScale, qOffset, @@ -736,7 +736,7 @@ LayerTestResult DepthwiseConvolution2dNhwcTestCommon( memoryManager, input, kernel, - GetBias2(biasEnabled, qScale, qOffset), + GetBias2(biasEnabled, qScale * qScale), expectedOutput, qScale, qOffset, @@ -802,7 +802,7 @@ LayerTestResult SimpleDepthwiseConvolution2d3x3Dilation3x3NhwcTestCommon( memoryManager, input, kernel, - GetBias2(biasEnabled, qScale, qOffset), + GetBias2(biasEnabled, qScale * qScale), expectedOutput, qScale, qOffset, diff --git a/src/backends/backendsCommon/test/WorkloadTestUtils.hpp b/src/backends/backendsCommon/test/WorkloadTestUtils.hpp index d03c5a9210..212fea34a6 100644 --- a/src/backends/backendsCommon/test/WorkloadTestUtils.hpp +++ b/src/backends/backendsCommon/test/WorkloadTestUtils.hpp @@ -73,6 +73,9 @@ inline void ExecuteWorkload(armnn::IWorkload& workload, memoryManager->Acquire(); } + // Perform PostAllocationConfiguration + workload.PostAllocationConfigure(); + // Execute the workload workload.Execute(); diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp index 65448568f7..be920943d1 100644 --- a/src/backends/reference/RefWorkloadFactory.cpp +++ b/src/backends/reference/RefWorkloadFactory.cpp @@ -160,7 +160,7 @@ std::unique_ptr RefWorkloadFactory::CreatePooling2d(const Pool std::unique_ptr RefWorkloadFactory::CreateConvolution2d( const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { - return MakeWorkload(descriptor, info); + return std::make_unique(descriptor, info); } std::unique_ptr RefWorkloadFactory::CreateDepthwiseConvolution2d( diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk index 1d635aaa21..3146fca3c7 100644 --- a/src/backends/reference/backend.mk +++ b/src/backends/reference/backend.mk @@ -33,8 +33,7 @@ BACKEND_SOURCES := \ workloads/RefConstantWorkload.cpp \ workloads/RefConvertFp16ToFp32Workload.cpp \ workloads/RefConvertFp32ToFp16Workload.cpp \ - workloads/RefConvolution2dFloat32Workload.cpp \ - workloads/RefConvolution2dUint8Workload.cpp \ + workloads/RefConvolution2dWorkload.cpp \ workloads/RefDebugWorkload.cpp \ workloads/RefDepthwiseConvolution2dFloat32Workload.cpp \ workloads/RefDepthwiseConvolution2dUint8Workload.cpp \ diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp index 4827d2867d..62e8788fe6 100644 --- a/src/backends/reference/test/RefCreateWorkloadTests.cpp +++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp @@ -254,7 +254,7 @@ static void RefCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayou { Graph graph; RefWorkloadFactory factory; - auto workload = CreateConvolution2dWorkloadTest + auto workload = CreateConvolution2dWorkloadTest (factory, graph, dataLayout); std::initializer_list inputShape = (dataLayout == DataLayout::NCHW) ? diff --git a/src/backends/reference/workloads/BaseIterator.hpp b/src/backends/reference/workloads/BaseIterator.hpp index 97af95a0eb..ab6de2b37f 100644 --- a/src/backends/reference/workloads/BaseIterator.hpp +++ b/src/backends/reference/workloads/BaseIterator.hpp @@ -123,6 +123,21 @@ public: } }; +class ScaledInt32Decoder : public TypedIterator> +{ +public: + ScaledInt32Decoder(const int32_t* data, const float scale) + : TypedIterator(data), m_Scale(scale) {} + + float Get() const override + { + return static_cast(*m_Iterator) * m_Scale; + } + +private: + const float m_Scale; +}; + class QASymm8Encoder : public TypedIterator> { public: diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index 6e4d7637bd..ab4fea619a 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -51,10 +51,8 @@ list(APPEND armnnRefBackendWorkloads_sources RefConvertFp16ToFp32Workload.hpp RefConvertFp32ToFp16Workload.cpp RefConvertFp32ToFp16Workload.hpp - RefConvolution2dFloat32Workload.cpp - RefConvolution2dFloat32Workload.hpp - RefConvolution2dUint8Workload.cpp - RefConvolution2dUint8Workload.hpp + RefConvolution2dWorkload.cpp + RefConvolution2dWorkload.hpp RefElementwiseWorkload.cpp RefElementwiseWorkload.hpp RefDebugWorkload.cpp diff --git a/src/backends/reference/workloads/ConvImpl.cpp b/src/backends/reference/workloads/ConvImpl.cpp index 8743a2bd0d..6a5ac535e4 100644 --- a/src/backends/reference/workloads/ConvImpl.cpp +++ b/src/backends/reference/workloads/ConvImpl.cpp @@ -68,4 +68,177 @@ int32_t QuantizedMultiplierSmallerThanOne::RoundingDivideByPOT(int32_t x, int ex return (x >> exponent) + (remainder > threshold ? 1 : 0); } +inline unsigned int GetOffset(DataLayout& dataLayout, const TensorShape& shape, unsigned int b, unsigned int c, + unsigned int h, unsigned int w) +{ + switch (dataLayout) + { + case DataLayout::NHWC: + b *= shape[1] * shape[2] * shape[3]; + h *= shape[2] * shape[3]; + w *= shape[3]; + break; + case DataLayout::NCHW: + default: + b *= shape[1] * shape[2] * shape[3]; + c *= shape[2] * shape[3]; + h *= shape[3]; + break; + } + return b + c + h + w; +} + +void Convolve(const TensorShape& rInputShape, + Decoder& rInputDecoder, + const TensorShape& rOutputShape, + Encoder& rOutputEncoder, + const TensorShape& rFilterShape, + Decoder& rFilterDecoder, + bool biasEnabled, + Decoder* pBiasDecoder, + DataLayout dataLayout, + unsigned int paddingTop, + unsigned int paddingLeft, + unsigned int xStride, + unsigned int yStride, + unsigned int xDilation, + unsigned int yDilation, + bool depthwise) +{ + if (biasEnabled && !pBiasDecoder) + { + throw InvalidArgumentException("Bias is enabled but the bias data is invalid"); + } + const armnnUtils::DataLayoutIndexed dataLayoutIndexed(dataLayout); + + const unsigned int channelsIndex = dataLayoutIndexed.GetChannelsIndex(); + const unsigned int heightIndex = dataLayoutIndexed.GetHeightIndex(); + const unsigned int widthIndex = dataLayoutIndexed.GetWidthIndex(); + + unsigned int depthMultiplier = depthwise ? rFilterShape[0] : 1; + unsigned int inputChannels = depthwise ? rFilterShape[1] : rFilterShape[channelsIndex]; + unsigned int outputChannels = depthwise ? inputChannels * depthMultiplier : rFilterShape[0]; + + unsigned int batchSize = rOutputShape[0]; + unsigned int outputHeight = rOutputShape[heightIndex]; + unsigned int outputWidth = rOutputShape[widthIndex]; + unsigned int inputHeight = rInputShape[heightIndex]; + unsigned int inputWidth = rInputShape[widthIndex]; + + unsigned int filterHeight = depthwise ? rFilterShape[2] : rFilterShape[heightIndex]; + unsigned int filterWidth = depthwise ? rFilterShape[3] : rFilterShape[widthIndex]; + + for (unsigned int batchIdx = 0; batchIdx < batchSize; batchIdx++) + { + for (unsigned int cOutput = 0; cOutput < outputChannels; cOutput++) + { + for (unsigned int yOutput = 0; yOutput < outputHeight; yOutput++) + { + for (unsigned int xOutput = 0; xOutput < outputWidth; xOutput++) + { + // This loop goes over each output element. + float sum = 0.0f; + + // For depthwise, each output channel corresponds to exactly one input channel. + // For normal, must loop over each input channel. + for (unsigned int cInput = 0; cInput < (depthwise ? 1 : inputChannels); cInput++) + { + unsigned int depthwiseMultiplierIdx = 0; + if (depthwise) + { + cInput = cOutput / depthMultiplier; + depthwiseMultiplierIdx = cOutput % depthMultiplier; + } + + for (unsigned int yFilter = 0; yFilter < filterHeight; yFilter++) + { + for (unsigned int xFilter = 0; xFilter < filterWidth; xFilter++) + { + // This loop goes over each input element for each output element. + unsigned int filterIndex = 0; + + // Since dimensionality of kernel depends on depthwiseness, so does index. + if (depthwise) + { + filterIndex = depthwiseMultiplierIdx * filterWidth * filterHeight * inputChannels + + cInput * filterWidth * filterHeight + + yFilter * filterWidth + + xFilter; + } + else + { + if (dataLayout == DataLayout::NHWC) + { + filterIndex = cOutput * filterHeight * filterWidth * inputChannels + + yFilter * filterWidth * inputChannels + + xFilter * inputChannels + + cInput; + } + else + { + filterIndex = cOutput * filterWidth * filterHeight * inputChannels + + cInput * filterWidth * filterHeight + + yFilter * filterWidth + + xFilter; + } + } + rFilterDecoder += filterIndex; + float filterValue = rFilterDecoder.Get(); + rFilterDecoder -= filterIndex; + + unsigned int yInput = yOutput * yStride + yFilter * yDilation; + unsigned int xInput = xOutput * xStride + xFilter * xDilation; + + float inputValue; + + // Check if we're in the padding. + if (yInput < paddingTop || yInput >= inputHeight + paddingTop || + xInput < paddingLeft || xInput >= inputWidth + paddingLeft ) + { + inputValue = 0.0f; + } + else + { + unsigned int inputIndex; + + if (dataLayout == DataLayout::NHWC) + { + inputIndex = batchIdx * inputHeight * inputWidth * inputChannels + + (yInput - paddingTop) * inputWidth * inputChannels + + (xInput - paddingLeft) * inputChannels + + cInput; + } + else + { + inputIndex = batchIdx * inputWidth * inputHeight * inputChannels + + inputWidth * inputHeight * cInput + + inputWidth * (yInput - paddingTop) + + xInput - paddingLeft; + } + rInputDecoder += inputIndex; + inputValue = rInputDecoder.Get(); + rInputDecoder -= inputIndex; + } + sum += filterValue * inputValue; + } + } + } + + if (biasEnabled) + { + *pBiasDecoder += cOutput; + sum += pBiasDecoder->Get(); + *pBiasDecoder -= cOutput; + } + unsigned int outIdx = GetOffset(dataLayout, rOutputShape, batchIdx, cOutput, yOutput, xOutput); + + rOutputEncoder += outIdx; + rOutputEncoder.Set(sum); + rOutputEncoder -= outIdx; + } + } + } + } +} + } //namespace armnn diff --git a/src/backends/reference/workloads/ConvImpl.hpp b/src/backends/reference/workloads/ConvImpl.hpp index 23b402aa77..3551ba8f90 100644 --- a/src/backends/reference/workloads/ConvImpl.hpp +++ b/src/backends/reference/workloads/ConvImpl.hpp @@ -7,6 +7,9 @@ #include "RefWorkloadUtils.hpp" #include "TensorBufferArrayView.hpp" +#include "BaseIterator.hpp" +#include "Decoders.hpp" +#include "Encoders.hpp" #include @@ -224,4 +227,20 @@ static void ConvImpl(ConvData data, } } +void Convolve(const TensorShape& rInputShape, + Decoder& rInputDecoder, + const TensorShape& rOutputShape, + Encoder& rOutputEncoder, + const TensorShape& rFilterShape, + Decoder& rFilterDecoder, + bool biasEnabled, + Decoder* pBiasDecoder, + DataLayout dataLayout, + unsigned int paddingTop, + unsigned int paddingLeft, + unsigned int xStride, + unsigned int yStride, + unsigned int xDilation, + unsigned int yDilation, + bool depthwise = false); } //namespace armnn diff --git a/src/backends/reference/workloads/Decoders.hpp b/src/backends/reference/workloads/Decoders.hpp index acf20c4b69..57c19a2a58 100644 --- a/src/backends/reference/workloads/Decoders.hpp +++ b/src/backends/reference/workloads/Decoders.hpp @@ -36,6 +36,12 @@ inline std::unique_ptr> MakeDecoder(const TensorInfo& info, const { return std::make_unique(static_cast(data)); } + case armnn::DataType::Signed32: + { + return std::make_unique( + static_cast(data), + info.GetQuantizationScale()); + } default: { BOOST_ASSERT_MSG(false, "Not supported Data Type!"); diff --git a/src/backends/reference/workloads/RefConvolution2dFloat32Workload.cpp b/src/backends/reference/workloads/RefConvolution2dFloat32Workload.cpp deleted file mode 100644 index 7b298df967..0000000000 --- a/src/backends/reference/workloads/RefConvolution2dFloat32Workload.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "RefConvolution2dFloat32Workload.hpp" - -#include "ConvImpl.hpp" -#include "RefWorkloadUtils.hpp" - -#include "Profiling.hpp" - -namespace armnn -{ -RefConvolution2dFloat32Workload::RefConvolution2dFloat32Workload( - const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) - : Float32Workload(descriptor, info), - m_Weight(std::make_unique(*(descriptor.m_Weight))), - m_Bias(descriptor.m_Parameters.m_BiasEnabled - ? std::make_unique(*(descriptor.m_Bias)) : nullptr) {} - -void RefConvolution2dFloat32Workload::Execute() const -{ - ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefConvolution2dFloat32Workload_Execute"); - - const float* inputData = GetInputTensorDataFloat(0, m_Data); - const float* filterData = m_Weight->template GetConstTensor(); - const float* biasData = m_Data.m_Parameters.m_BiasEnabled ? m_Bias->template GetConstTensor() : nullptr; - const TensorInfo& filterInfo = m_Weight->GetTensorInfo(); - - ConvImpl( - m_Data, inputData, 0.0f, 0, filterData, 0.0f, 0, biasData, 0.0f, 0, filterInfo); -} - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefConvolution2dFloat32Workload.hpp b/src/backends/reference/workloads/RefConvolution2dFloat32Workload.hpp deleted file mode 100644 index 5ff743d511..0000000000 --- a/src/backends/reference/workloads/RefConvolution2dFloat32Workload.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -namespace armnn -{ - -class RefConvolution2dFloat32Workload : public Float32Workload -{ -public: - explicit RefConvolution2dFloat32Workload(const Convolution2dQueueDescriptor& descriptor, - const WorkloadInfo& info); - virtual void Execute() const override; - -private: - std::unique_ptr m_Weight; - std::unique_ptr m_Bias; - -}; - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefConvolution2dUint8Workload.cpp b/src/backends/reference/workloads/RefConvolution2dUint8Workload.cpp deleted file mode 100644 index af2c7ad0d6..0000000000 --- a/src/backends/reference/workloads/RefConvolution2dUint8Workload.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "RefConvolution2dUint8Workload.hpp" - -#include "ConvImpl.hpp" -#include "RefWorkloadUtils.hpp" - -#include "Profiling.hpp" - -namespace armnn -{ -RefConvolution2dUint8Workload::RefConvolution2dUint8Workload( - const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) - : Uint8Workload(descriptor, info), - m_Weight(std::make_unique(*(descriptor.m_Weight))), - m_Bias(descriptor.m_Parameters.m_BiasEnabled - ? std::make_unique(*(descriptor.m_Bias)) : nullptr) {} - -void RefConvolution2dUint8Workload::Execute() const -{ - ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefConvolution2dUint8Workload_Execute"); - - const uint8_t* inputData = GetInputTensorDataU8(0, m_Data); - const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); - const uint8_t* weightsData = m_Weight->template GetConstTensor(); - const TensorInfo& weightsInfo = GetTensorInfo(m_Weight.get()); - const int32_t* biasData = m_Data.m_Parameters.m_BiasEnabled ? m_Bias->template GetConstTensor() : nullptr; - const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); - const TensorInfo& filterInfo = m_Weight->GetTensorInfo(); - - ConvImpl( - m_Data, - inputData, inputInfo.GetQuantizationScale(), inputInfo.GetQuantizationOffset(), - weightsData, weightsInfo.GetQuantizationScale(), weightsInfo.GetQuantizationOffset(), - biasData, - outputInfo.GetQuantizationScale(), outputInfo.GetQuantizationOffset(), filterInfo); -} - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefConvolution2dUint8Workload.hpp b/src/backends/reference/workloads/RefConvolution2dUint8Workload.hpp deleted file mode 100644 index a58f23a2a0..0000000000 --- a/src/backends/reference/workloads/RefConvolution2dUint8Workload.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -#include -#include - -namespace armnn -{ - -class RefConvolution2dUint8Workload : public Uint8Workload -{ -public: - explicit RefConvolution2dUint8Workload(const Convolution2dQueueDescriptor& descriptor, - const WorkloadInfo& info); - - virtual void Execute() const override; - -private: - std::unique_ptr m_Weight; - std::unique_ptr m_Bias; - -}; - -} //namespace armnn diff --git a/src/backends/reference/workloads/RefConvolution2dWorkload.cpp b/src/backends/reference/workloads/RefConvolution2dWorkload.cpp new file mode 100644 index 0000000000..0824d5cf1c --- /dev/null +++ b/src/backends/reference/workloads/RefConvolution2dWorkload.cpp @@ -0,0 +1,53 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefConvolution2dWorkload.hpp" + +#include "ConvImpl.hpp" +#include "RefWorkloadUtils.hpp" + +#include "Profiling.hpp" + +namespace armnn +{ +RefConvolution2dWorkload::RefConvolution2dWorkload( + const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) + : BaseWorkload(descriptor, info) +{ + m_Weight = std::make_unique(*(descriptor.m_Weight)); + const TensorInfo& rFilterInfo = GetTensorInfo(m_Weight.get()); + m_FilterShape = rFilterInfo.GetShape(); + m_FilterDecoder = MakeDecoder(rFilterInfo, m_Weight.get()->Map(true)); + + if (descriptor.m_Parameters.m_BiasEnabled) + { + m_Bias = std::make_unique(*(descriptor.m_Bias)); + const TensorInfo& biasInfo = GetTensorInfo(m_Bias.get()); + m_BiasDecoder = MakeDecoder(biasInfo, m_Bias.get()->Map(true)); + } +} + +void RefConvolution2dWorkload::PostAllocationConfigure() +{ + const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + m_InputShape = inputInfo.GetShape(); + m_InputDecoder = MakeDecoder(inputInfo, m_Data.m_Inputs[0]->Map()); + + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + m_OutputShape = outputInfo.GetShape(); + m_OutputEncoder = MakeEncoder(outputInfo, m_Data.m_Outputs[0]->Map()); +} + +void RefConvolution2dWorkload::Execute() const { + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefConvolution2dWorkload_Execute"); + + Convolve(m_InputShape, *m_InputDecoder, m_OutputShape, *m_OutputEncoder, m_FilterShape, + *m_FilterDecoder, m_Data.m_Parameters.m_BiasEnabled, m_BiasDecoder.get(), + m_Data.m_Parameters.m_DataLayout, m_Data.m_Parameters.m_PadTop, m_Data.m_Parameters.m_PadLeft, + m_Data.m_Parameters.m_StrideX, m_Data.m_Parameters.m_StrideY, + m_Data.m_Parameters.m_DilationX, m_Data.m_Parameters.m_DilationY); +} + +} //namespace armnn diff --git a/src/backends/reference/workloads/RefConvolution2dWorkload.hpp b/src/backends/reference/workloads/RefConvolution2dWorkload.hpp new file mode 100644 index 0000000000..b6bdf23ffa --- /dev/null +++ b/src/backends/reference/workloads/RefConvolution2dWorkload.hpp @@ -0,0 +1,41 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include +#include "Decoders.hpp" +#include "Encoders.hpp" + +namespace armnn +{ + +class RefConvolution2dWorkload : public BaseWorkload +{ +public: + explicit RefConvolution2dWorkload(const Convolution2dQueueDescriptor& descriptor, + const WorkloadInfo& info); + + void PostAllocationConfigure() override; + + virtual void Execute() const override; + +private: + std::unique_ptr m_Weight; + std::unique_ptr m_Bias; + + std::unique_ptr> m_InputDecoder; + std::unique_ptr> m_OutputEncoder; + std::unique_ptr> m_FilterDecoder; + std::unique_ptr> m_BiasDecoder; + + TensorShape m_InputShape; + TensorShape m_OutputShape; + TensorShape m_FilterShape; +}; + +} //namespace armnn + diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index 314e65beeb..5a65f60c40 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -9,7 +9,7 @@ #include "RefElementwiseWorkload.hpp" #include "ConvImpl.hpp" #include "RefConstantWorkload.hpp" -#include "RefConvolution2dUint8Workload.hpp" +#include "RefConvolution2dWorkload.hpp" #include "RefSplitterUint8Workload.hpp" #include "RefResizeBilinearUint8Workload.hpp" #include "RefL2NormalizationFloat32Workload.hpp" @@ -46,7 +46,6 @@ #include "RefSpaceToBatchNdWorkload.hpp" #include "RefSplitterFloat32Workload.hpp" #include "RefStridedSliceWorkload.hpp" -#include "RefConvolution2dFloat32Workload.hpp" #include "Pooling2d.hpp" #include "RefFakeQuantizationFloat32Workload.hpp" #include "RefPermuteWorkload.hpp" -- cgit v1.2.1