aboutsummaryrefslogtreecommitdiff
path: root/src/backends/reference/workloads
diff options
context:
space:
mode:
authorAron Virginas-Tar <Aron.Virginas-Tar@arm.com>2019-10-14 15:12:00 +0100
committerÁron Virginás-Tar <aron.virginas-tar@arm.com>2019-10-15 11:46:03 +0000
commite662a940d3378cfe669ff7e259a6911713fc0df9 (patch)
tree40c6b83f2d4b936da053bcb74784a8a849c4c9bc /src/backends/reference/workloads
parentf4d59a678d8ef8420f52d341bb60f1a583269e24 (diff)
downloadarmnn-e662a940d3378cfe669ff7e259a6911713fc0df9.tar.gz
IVGCVSW-3975 Add reference workload for LOG_SOFTMAX
Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com> Change-Id: I10bb7133e0e2d6d7199abdf39562b1226bbbd3e7
Diffstat (limited to 'src/backends/reference/workloads')
-rw-r--r--src/backends/reference/workloads/CMakeLists.txt4
-rw-r--r--src/backends/reference/workloads/LogSoftmax.cpp91
-rw-r--r--src/backends/reference/workloads/LogSoftmax.hpp20
-rw-r--r--src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp36
-rw-r--r--src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp21
-rw-r--r--src/backends/reference/workloads/RefWorkloads.hpp1
6 files changed, 173 insertions, 0 deletions
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 <TensorUtils.hpp>
+
+#include <cmath>
+
+#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace
+{
+
+inline bool ValidateAxis(int axis, unsigned int numDimensions)
+{
+ const int sNumDimensions = boost::numeric_cast<int>(numDimensions);
+ return axis < sNumDimensions && axis >= -sNumDimensions;
+}
+
+} // anonymous namespace
+
+namespace armnn
+{
+
+void LogSoftmax(Decoder<float>& input,
+ Encoder<float>& 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<unsigned int>(std::abs(descriptor.m_Axis)) :
+ boost::numeric_cast<unsigned int>(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 <armnn/Tensor.hpp>
+
+namespace armnn
+{
+
+void LogSoftmax(Decoder<float>& input,
+ Encoder<float>& 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 <Profiling.hpp>
+
+#include <boost/assert.hpp>
+
+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<float>> decoder = MakeDecoder<float>(inputInfo, m_Data.m_Inputs[0]->Map());
+ std::unique_ptr<Encoder<float>> encoder = MakeEncoder<float>(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 <backendsCommon/Workload.hpp>
+#include <backendsCommon/WorkloadData.hpp>
+
+namespace armnn
+{
+
+class RefLogSoftmaxWorkload : public BaseWorkload<LogSoftmaxQueueDescriptor>
+{
+public:
+ using BaseWorkload<LogSoftmaxQueueDescriptor>::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"