From e662a940d3378cfe669ff7e259a6911713fc0df9 Mon Sep 17 00:00:00 2001 From: Aron Virginas-Tar Date: Mon, 14 Oct 2019 15:12:00 +0100 Subject: IVGCVSW-3975 Add reference workload for LOG_SOFTMAX Signed-off-by: Aron Virginas-Tar Change-Id: I10bb7133e0e2d6d7199abdf39562b1226bbbd3e7 --- src/backends/reference/workloads/CMakeLists.txt | 4 + src/backends/reference/workloads/LogSoftmax.cpp | 91 ++++++++++++++++++++++ src/backends/reference/workloads/LogSoftmax.hpp | 20 +++++ .../reference/workloads/RefLogSoftmaxWorkload.cpp | 36 +++++++++ .../reference/workloads/RefLogSoftmaxWorkload.hpp | 21 +++++ src/backends/reference/workloads/RefWorkloads.hpp | 1 + 6 files changed, 173 insertions(+) create mode 100644 src/backends/reference/workloads/LogSoftmax.cpp create mode 100644 src/backends/reference/workloads/LogSoftmax.hpp create mode 100644 src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp create mode 100644 src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp (limited to 'src/backends/reference/workloads') diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index 9a5f427d37..b8eb95c729 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -37,6 +37,8 @@ list(APPEND armnnRefBackendWorkloads_sources Gather.hpp InstanceNorm.cpp InstanceNorm.hpp + LogSoftmax.cpp + LogSoftmax.hpp LstmUtils.hpp LstmUtils.cpp Maximum.hpp @@ -95,6 +97,8 @@ list(APPEND armnnRefBackendWorkloads_sources RefInstanceNormalizationWorkload.hpp RefL2NormalizationWorkload.cpp RefL2NormalizationWorkload.hpp + RefLogSoftmaxWorkload.cpp + RefLogSoftmaxWorkload.hpp RefLstmWorkload.cpp RefLstmWorkload.hpp RefMeanWorkload.cpp diff --git a/src/backends/reference/workloads/LogSoftmax.cpp b/src/backends/reference/workloads/LogSoftmax.cpp new file mode 100644 index 0000000000..3fa3dc0d8c --- /dev/null +++ b/src/backends/reference/workloads/LogSoftmax.cpp @@ -0,0 +1,91 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "LogSoftmax.hpp" + +#include + +#include + +#include +#include +#include + +namespace +{ + +inline bool ValidateAxis(int axis, unsigned int numDimensions) +{ + const int sNumDimensions = boost::numeric_cast(numDimensions); + return axis < sNumDimensions && axis >= -sNumDimensions; +} + +} // anonymous namespace + +namespace armnn +{ + +void LogSoftmax(Decoder& input, + Encoder& output, + const TensorInfo& inputInfo, + const LogSoftmaxDescriptor& descriptor) +{ + const unsigned int numDimensions = inputInfo.GetNumDimensions(); + + bool axisIsValid = ValidateAxis(descriptor.m_Axis, numDimensions); + BOOST_ASSERT_MSG(axisIsValid, + "Axis index is not in range [-numDimensions, numDimensions)."); + boost::ignore_unused(axisIsValid); + + unsigned int uAxis = descriptor.m_Axis < 0 ? + numDimensions - boost::numeric_cast(std::abs(descriptor.m_Axis)) : + boost::numeric_cast(descriptor.m_Axis); + + const TensorShape& inputShape = inputInfo.GetShape(); + const unsigned int outerSize = armnnUtils::GetNumElementsBetween(inputShape, 0, uAxis); + const unsigned int axisSize = inputShape[uAxis]; + const unsigned int innerSize = armnnUtils::GetNumElementsBetween(inputShape, + uAxis + 1, + inputShape.GetNumDimensions()); + + for (unsigned int outer = 0; outer < outerSize; ++outer) + { + for (unsigned int inner = 0; inner < innerSize; ++inner) + { + // Find max + input[outer * axisSize * innerSize + inner]; + float maxValue = input.Get(); + for (unsigned int i = 1u; i < axisSize; ++i) + { + input[(outer * axisSize + i) * innerSize + inner]; + maxValue = std::max(maxValue, input.Get()); + } + + // Compute sum + float sum = 0.0f; + for (unsigned int i = 0u; i < axisSize; ++i) + { + input[(outer * axisSize + i) * innerSize + inner]; + sum += std::exp((input.Get() - maxValue) * descriptor.m_Beta); + } + + // Compute log sum + const float logSum = std::log(sum); + + // Compute result + for (unsigned int i = 0u; i < axisSize; ++i) + { + const unsigned int index = (outer * axisSize + i) * innerSize + inner; + + input [index]; + output[index]; + + output.Set((input.Get() - maxValue) * descriptor.m_Beta - logSum); + } + } + } +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/LogSoftmax.hpp b/src/backends/reference/workloads/LogSoftmax.hpp new file mode 100644 index 0000000000..2e383992c9 --- /dev/null +++ b/src/backends/reference/workloads/LogSoftmax.hpp @@ -0,0 +1,20 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "BaseIterator.hpp" + +#include + +namespace armnn +{ + +void LogSoftmax(Decoder& input, + Encoder& output, + const TensorInfo& inputInfo, + const LogSoftmaxDescriptor& descriptor); + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp b/src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp new file mode 100644 index 0000000000..a987e79dda --- /dev/null +++ b/src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp @@ -0,0 +1,36 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefLogSoftmaxWorkload.hpp" + +#include "Decoders.hpp" +#include "Encoders.hpp" +#include "LogSoftmax.hpp" +#include "RefWorkloadUtils.hpp" + +#include + +#include + +namespace armnn +{ + +void RefLogSoftmaxWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefLogSoftmaxWorkload_Execute"); + + const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + std::unique_ptr> decoder = MakeDecoder(inputInfo, m_Data.m_Inputs[0]->Map()); + std::unique_ptr> encoder = MakeEncoder(outputInfo, m_Data.m_Outputs[0]->Map()); + + BOOST_ASSERT(decoder != nullptr); + BOOST_ASSERT(encoder != nullptr); + + LogSoftmax(*decoder, *encoder, inputInfo, m_Data.m_Parameters); +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp b/src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp new file mode 100644 index 0000000000..f5048d90b3 --- /dev/null +++ b/src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp @@ -0,0 +1,21 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +namespace armnn +{ + +class RefLogSoftmaxWorkload : public BaseWorkload +{ +public: + using BaseWorkload::BaseWorkload; + virtual void Execute() const override; +}; + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index 39dfa0517b..79d1935823 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -38,6 +38,7 @@ #include "RefGatherWorkload.hpp" #include "RefInstanceNormalizationWorkload.hpp" #include "RefL2NormalizationWorkload.hpp" +#include "RefLogSoftmaxWorkload.hpp" #include "RefLstmWorkload.hpp" #include "RefMeanWorkload.hpp" #include "RefNormalizationWorkload.hpp" -- cgit v1.2.1