diff options
Diffstat (limited to 'src/backends/reference/workloads')
10 files changed, 315 insertions, 0 deletions
diff --git a/src/backends/reference/workloads/BaseIterator.hpp b/src/backends/reference/workloads/BaseIterator.hpp index a10f383e90..73e24691d9 100644 --- a/src/backends/reference/workloads/BaseIterator.hpp +++ b/src/backends/reference/workloads/BaseIterator.hpp @@ -515,6 +515,40 @@ public: } }; +class BooleanDecoderBool : public TypedIterator<const uint8_t, Decoder<bool>> +{ +public: + BooleanDecoderBool(const uint8_t* data) + : TypedIterator(data) {} + + BooleanDecoderBool() + : BooleanDecoderBool(nullptr) {} + + bool Get() const override + { + return *m_Iterator; + } + + std::vector<float> DecodeTensor(const TensorShape& tensorShape, + const unsigned int channelMultiplier, + const bool isDepthwise) override + { + IgnoreUnused(channelMultiplier, isDepthwise); + + const unsigned int size = tensorShape.GetNumElements(); + std::vector<float> decodedTensor; + decodedTensor.reserve(size); + + for (uint32_t i = 0; i < size; ++i) + { + this->operator[](i); + decodedTensor.emplace_back(*m_Iterator); + } + + return decodedTensor; + } +}; + class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>> { public: diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index cd9efc96af..1b20e5bf2d 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -107,6 +107,10 @@ list(APPEND armnnRefBackendWorkloads_sources RefInstanceNormalizationWorkload.hpp RefL2NormalizationWorkload.cpp RefL2NormalizationWorkload.hpp + RefLogicalBinaryWorkload.cpp + RefLogicalBinaryWorkload.hpp + RefLogicalUnaryWorkload.cpp + RefLogicalUnaryWorkload.hpp RefLogSoftmaxWorkload.cpp RefLogSoftmaxWorkload.hpp RefLstmWorkload.cpp diff --git a/src/backends/reference/workloads/Decoders.hpp b/src/backends/reference/workloads/Decoders.hpp index 08e0140fad..0b3f36047d 100644 --- a/src/backends/reference/workloads/Decoders.hpp +++ b/src/backends/reference/workloads/Decoders.hpp @@ -150,6 +150,24 @@ inline std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const } template<> +inline std::unique_ptr<Decoder<bool>> MakeDecoder(const TensorInfo& info, const void* data) +{ + switch(info.GetDataType()) + { + case DataType::Boolean: + { + return std::make_unique<BooleanDecoderBool>(static_cast<const uint8_t*>(data)); + } + default: + { + ARMNN_ASSERT_MSG(false, "Unsupported Data Type!"); + break; + } + } + return nullptr; +} + +template<> inline std::unique_ptr<Decoder<int32_t>> MakeDecoder(const TensorInfo& info, const void* data) { switch(info.GetDataType()) diff --git a/src/backends/reference/workloads/ElementwiseFunction.cpp b/src/backends/reference/workloads/ElementwiseFunction.cpp index afae188bd6..d6f3f42478 100644 --- a/src/backends/reference/workloads/ElementwiseFunction.cpp +++ b/src/backends/reference/workloads/ElementwiseFunction.cpp @@ -37,6 +37,26 @@ ElementwiseUnaryFunction<Functor>::ElementwiseUnaryFunction(const TensorShape& i BroadcastLoop(inShape, outShape).Unroll(Functor(), 0, inData, outData); } +template <typename Functor> +LogicalBinaryFunction<Functor>::LogicalBinaryFunction(const TensorShape& inShape0, + const TensorShape& inShape1, + const TensorShape& outShape, + Decoder<InType>& inData0, + Decoder<InType>& inData1, + Encoder<OutType>& outData) +{ + BroadcastLoop(inShape0, inShape1, outShape).Unroll(Functor(), 0, inData0, inData1, outData); +} + +template <typename Functor> +LogicalUnaryFunction<Functor>::LogicalUnaryFunction(const TensorShape& inShape, + const TensorShape& outShape, + Decoder<InType>& inData, + Encoder<OutType>& outData) +{ + BroadcastLoop(inShape, outShape).Unroll(Functor(), 0, inData, outData); +} + } //namespace armnn template struct armnn::ElementwiseBinaryFunction<std::plus<float>>; @@ -67,3 +87,8 @@ template struct armnn::ElementwiseUnaryFunction<armnn::exp<float>>; template struct armnn::ElementwiseUnaryFunction<std::negate<float>>; template struct armnn::ElementwiseUnaryFunction<armnn::rsqrt<float>>; template struct armnn::ElementwiseUnaryFunction<armnn::sqrt<float>>; + +// Logical Unary +template struct armnn::LogicalUnaryFunction<std::logical_not<bool>>; +template struct armnn::LogicalBinaryFunction<std::logical_and<bool>>; +template struct armnn::LogicalBinaryFunction<std::logical_or<bool>>; diff --git a/src/backends/reference/workloads/ElementwiseFunction.hpp b/src/backends/reference/workloads/ElementwiseFunction.hpp index 8259ba5ac7..ef4a2dc7d5 100644 --- a/src/backends/reference/workloads/ElementwiseFunction.hpp +++ b/src/backends/reference/workloads/ElementwiseFunction.hpp @@ -37,4 +37,30 @@ struct ElementwiseUnaryFunction Encoder<OutType>& outData); }; +template <typename Functor> +struct LogicalBinaryFunction +{ + using OutType = bool; + using InType = bool; + + LogicalBinaryFunction(const TensorShape& inShape0, + const TensorShape& inShape1, + const TensorShape& outShape, + Decoder<InType>& inData0, + Decoder<InType>& inData1, + Encoder<OutType>& outData); +}; + +template <typename Functor> +struct LogicalUnaryFunction +{ + using OutType = bool; + using InType = bool; + + LogicalUnaryFunction(const TensorShape& inShape, + const TensorShape& outShape, + Decoder<InType>& inData, + Encoder<OutType>& outData); +}; + } //namespace armnn diff --git a/src/backends/reference/workloads/RefLogicalBinaryWorkload.cpp b/src/backends/reference/workloads/RefLogicalBinaryWorkload.cpp new file mode 100644 index 0000000000..1b4e8f9aa0 --- /dev/null +++ b/src/backends/reference/workloads/RefLogicalBinaryWorkload.cpp @@ -0,0 +1,75 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefLogicalBinaryWorkload.hpp" + +#include "Decoders.hpp" +#include "ElementwiseFunction.hpp" +#include "Encoders.hpp" +#include "RefWorkloadUtils.hpp" + +#include <Profiling.hpp> + +#include <armnn/TypesUtils.hpp> + +namespace armnn +{ + +RefLogicalBinaryWorkload::RefLogicalBinaryWorkload(const LogicalBinaryQueueDescriptor& desc, + const WorkloadInfo& info) + : BaseWorkload<LogicalBinaryQueueDescriptor>(desc, info) +{} + +void RefLogicalBinaryWorkload::PostAllocationConfigure() +{ + const TensorInfo& inputInfo0 = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& inputInfo1 = GetTensorInfo(m_Data.m_Inputs[1]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + m_Input0 = MakeDecoder<InType>(inputInfo0); + m_Input1 = MakeDecoder<InType>(inputInfo1); + m_Output = MakeEncoder<OutType>(outputInfo); +} + +void RefLogicalBinaryWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefLogicalBinaryWorkload_Execute"); + + const TensorInfo& inputInfo0 = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& inputInfo1 = GetTensorInfo(m_Data.m_Inputs[1]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + const TensorShape& inShape0 = inputInfo0.GetShape(); + const TensorShape& inShape1 = inputInfo1.GetShape(); + const TensorShape& outShape = outputInfo.GetShape(); + + m_Input0->Reset(m_Data.m_Inputs[0]->Map()); + m_Input1->Reset(m_Data.m_Inputs[1]->Map()); + m_Output->Reset(m_Data.m_Outputs[0]->Map()); + + using AndFunction = LogicalBinaryFunction<std::logical_and<bool>>; + using OrFunction = LogicalBinaryFunction<std::logical_or<bool>>; + + switch (m_Data.m_Parameters.m_Operation) + { + case LogicalBinaryOperation::LogicalAnd: + { + AndFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output); + break; + } + case LogicalBinaryOperation::LogicalOr: + { + OrFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output); + break; + } + default: + { + throw InvalidArgumentException(std::string("Unsupported Logical Binary operation") + + GetLogicalBinaryOperationAsCString(m_Data.m_Parameters.m_Operation), CHECK_LOCATION()); + } + } +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefLogicalBinaryWorkload.hpp b/src/backends/reference/workloads/RefLogicalBinaryWorkload.hpp new file mode 100644 index 0000000000..4d6baf5fa4 --- /dev/null +++ b/src/backends/reference/workloads/RefLogicalBinaryWorkload.hpp @@ -0,0 +1,34 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "BaseIterator.hpp" + +#include <backendsCommon/Workload.hpp> +#include <backendsCommon/WorkloadData.hpp> + +namespace armnn +{ + +class RefLogicalBinaryWorkload : public BaseWorkload<LogicalBinaryQueueDescriptor> +{ +public: + using BaseWorkload<LogicalBinaryQueueDescriptor>::m_Data; + + RefLogicalBinaryWorkload(const LogicalBinaryQueueDescriptor& descriptor, const WorkloadInfo& info); + void PostAllocationConfigure() override; + virtual void Execute() const override; + +private: + using InType = bool; + using OutType = bool; + + std::unique_ptr<Decoder<InType>> m_Input0; + std::unique_ptr<Decoder<InType>> m_Input1; + std::unique_ptr<Encoder<OutType>> m_Output; +}; + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefLogicalUnaryWorkload.cpp b/src/backends/reference/workloads/RefLogicalUnaryWorkload.cpp new file mode 100644 index 0000000000..76eb5ac39f --- /dev/null +++ b/src/backends/reference/workloads/RefLogicalUnaryWorkload.cpp @@ -0,0 +1,64 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefLogicalUnaryWorkload.hpp" + +#include "Decoders.hpp" +#include "ElementwiseFunction.hpp" +#include "Encoders.hpp" +#include "RefWorkloadUtils.hpp" + +#include <Profiling.hpp> + +#include <armnn/TypesUtils.hpp> + +namespace armnn +{ + +RefLogicalUnaryWorkload::RefLogicalUnaryWorkload(const ElementwiseUnaryQueueDescriptor& desc, + const WorkloadInfo& info) + : BaseWorkload<ElementwiseUnaryQueueDescriptor>(desc, info) +{} + +void RefLogicalUnaryWorkload::PostAllocationConfigure() +{ + const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + m_Input = MakeDecoder<InType>(inputInfo); + m_Output = MakeEncoder<OutType>(outputInfo); +} + +void RefLogicalUnaryWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefLogicalUnaryWorkload_Execute"); + + const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + const TensorShape& inShape = inputInfo.GetShape(); + const TensorShape& outShape = outputInfo.GetShape(); + + m_Input->Reset(m_Data.m_Inputs[0]->Map()); + m_Output->Reset(m_Data.m_Outputs[0]->Map()); + + using NotFunction = LogicalUnaryFunction<std::logical_not<bool>>; + + switch (m_Data.m_Parameters.m_Operation) + { + case UnaryOperation::LogicalNot: + { + NotFunction(inShape, outShape, *m_Input, *m_Output); + break; + } + default: + { + throw InvalidArgumentException(std::string("Unsupported Logical Unary operation") + + GetUnaryOperationAsCString(m_Data.m_Parameters.m_Operation), CHECK_LOCATION()); + } + } +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefLogicalUnaryWorkload.hpp b/src/backends/reference/workloads/RefLogicalUnaryWorkload.hpp new file mode 100644 index 0000000000..0d8b35495c --- /dev/null +++ b/src/backends/reference/workloads/RefLogicalUnaryWorkload.hpp @@ -0,0 +1,33 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "BaseIterator.hpp" + +#include <backendsCommon/Workload.hpp> +#include <backendsCommon/WorkloadData.hpp> + +namespace armnn +{ + +class RefLogicalUnaryWorkload : public BaseWorkload<ElementwiseUnaryQueueDescriptor> +{ +public: + using BaseWorkload<ElementwiseUnaryQueueDescriptor>::m_Data; + + RefLogicalUnaryWorkload(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info); + void PostAllocationConfigure() override; + virtual void Execute() const override; + +private: + using InType = bool; + using OutType = bool; + + std::unique_ptr<Decoder<InType>> m_Input; + std::unique_ptr<Encoder<OutType>> m_Output; +}; + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index fc47cff84f..390b2a8d55 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -41,6 +41,8 @@ #include "RefGatherWorkload.hpp" #include "RefInstanceNormalizationWorkload.hpp" #include "RefL2NormalizationWorkload.hpp" +#include "RefLogicalBinaryWorkload.hpp" +#include "RefLogicalUnaryWorkload.hpp" #include "RefLogSoftmaxWorkload.hpp" #include "RefLstmWorkload.hpp" #include "RefMeanWorkload.hpp" |