aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNattapat Chaimanowong <nattapat.chaimanowong@arm.com>2019-04-24 16:19:57 +0100
committerMatteo Martincigh <matteo.martincigh@arm.com>2019-04-29 11:04:20 +0000
commitae2c5f0350a7033f58578f9c509345445a639865 (patch)
tree4fd6266fc7d917130a0087938eafcadd1b7f31be
parentbb73e576e75fde75acb28362fb7be194dfcbcada (diff)
downloadarmnn-ae2c5f0350a7033f58578f9c509345445a639865.tar.gz
IVGCVSW-2982 Refactor reference Activation workload
Change-Id: Ia3b9a56787cc68822a3c1635de82e03ecc0aae27 Signed-off-by: Nattapat Chaimanowong <nattapat.chaimanowong@arm.com>
-rw-r--r--src/backends/backendsCommon/WorkloadData.cpp14
-rw-r--r--src/backends/reference/RefWorkloadFactory.cpp6
-rw-r--r--src/backends/reference/backend.mk3
-rw-r--r--src/backends/reference/test/RefCreateWorkloadTests.cpp8
-rw-r--r--src/backends/reference/workloads/Activation.cpp150
-rw-r--r--src/backends/reference/workloads/Activation.hpp16
-rw-r--r--src/backends/reference/workloads/CMakeLists.txt6
-rw-r--r--src/backends/reference/workloads/Decoders.hpp6
-rw-r--r--src/backends/reference/workloads/Encoders.hpp8
-rw-r--r--src/backends/reference/workloads/RefActivationFloat32Workload.cpp28
-rw-r--r--src/backends/reference/workloads/RefActivationFloat32Workload.hpp20
-rw-r--r--src/backends/reference/workloads/RefActivationUint8Workload.cpp38
-rw-r--r--src/backends/reference/workloads/RefActivationWorkload.cpp33
-rw-r--r--src/backends/reference/workloads/RefActivationWorkload.hpp (renamed from src/backends/reference/workloads/RefActivationUint8Workload.hpp)4
-rw-r--r--src/backends/reference/workloads/RefWorkloads.hpp5
15 files changed, 170 insertions, 175 deletions
diff --git a/src/backends/backendsCommon/WorkloadData.cpp b/src/backends/backendsCommon/WorkloadData.cpp
index df66b4e4c1..66e30f0592 100644
--- a/src/backends/backendsCommon/WorkloadData.cpp
+++ b/src/backends/backendsCommon/WorkloadData.cpp
@@ -297,6 +297,20 @@ void ActivationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
"ActivationQueueDescriptor",
"input",
"output");
+
+ std::vector<DataType> supportedTypes = {
+ DataType::Float32,
+ DataType::Float16,
+ DataType::QuantisedAsymm8
+ };
+
+ ValidateDataTypes(workloadInfo.m_InputTensorInfos[0],
+ supportedTypes,
+ "ActivationQueueDescriptor");
+
+ ValidateDataTypes(workloadInfo.m_OutputTensorInfos[0],
+ {workloadInfo.m_InputTensorInfos[0].GetDataType()},
+ "ActivationQueueDescriptor");
}
//---------------------------------------------------------------
diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp
index b1c3ad79ac..8887bb719a 100644
--- a/src/backends/reference/RefWorkloadFactory.cpp
+++ b/src/backends/reference/RefWorkloadFactory.cpp
@@ -113,7 +113,11 @@ std::unique_ptr<IWorkload> RefWorkloadFactory::CreateOutput(const OutputQueueDes
std::unique_ptr<IWorkload> RefWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor,
const WorkloadInfo& info) const
{
- return MakeWorkload<RefActivationFloat32Workload, RefActivationUint8Workload>(descriptor, info);
+ if (IsFloat16(info))
+ {
+ return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
+ }
+ return std::make_unique<RefActivationWorkload>(descriptor, info);
}
std::unique_ptr<IWorkload> RefWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor,
diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk
index e74e85378f..06459ed31b 100644
--- a/src/backends/reference/backend.mk
+++ b/src/backends/reference/backend.mk
@@ -24,8 +24,7 @@ BACKEND_SOURCES := \
workloads/Merger.cpp \
workloads/Pad.cpp \
workloads/Pooling2d.cpp \
- workloads/RefActivationFloat32Workload.cpp \
- workloads/RefActivationUint8Workload.cpp \
+ workloads/RefActivationWorkload.cpp \
workloads/RefBatchNormalizationFloat32Workload.cpp \
workloads/RefBatchNormalizationUint8Workload.cpp \
workloads/RefBatchToSpaceNdFloat32Workload.cpp \
diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp
index 4b4e5449b4..5da1f94f6e 100644
--- a/src/backends/reference/test/RefCreateWorkloadTests.cpp
+++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp
@@ -55,12 +55,12 @@ static void RefCreateActivationWorkloadTest()
BOOST_AUTO_TEST_CASE(CreateActivationFloat32Workload)
{
- RefCreateActivationWorkloadTest<RefActivationFloat32Workload, armnn::DataType::Float32>();
+ RefCreateActivationWorkloadTest<RefActivationWorkload, armnn::DataType::Float32>();
}
BOOST_AUTO_TEST_CASE(CreateActivationUint8Workload)
{
- RefCreateActivationWorkloadTest<RefActivationUint8Workload, armnn::DataType::QuantisedAsymm8>();
+ RefCreateActivationWorkloadTest<RefActivationWorkload, armnn::DataType::QuantisedAsymm8>();
}
template <typename WorkloadType,
@@ -527,13 +527,13 @@ static void RefCreateSingleOutputMultipleInputsTest()
BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputsFloat32)
{
- RefCreateSingleOutputMultipleInputsTest<RefSplitterFloat32Workload, RefActivationFloat32Workload,
+ RefCreateSingleOutputMultipleInputsTest<RefSplitterFloat32Workload, RefActivationWorkload,
armnn::DataType::Float32>();
}
BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputsUint8)
{
- RefCreateSingleOutputMultipleInputsTest<RefSplitterUint8Workload, RefActivationUint8Workload,
+ RefCreateSingleOutputMultipleInputsTest<RefSplitterUint8Workload, RefActivationWorkload,
armnn::DataType::QuantisedAsymm8>();
}
diff --git a/src/backends/reference/workloads/Activation.cpp b/src/backends/reference/workloads/Activation.cpp
index ef4903074b..760c9a0ccd 100644
--- a/src/backends/reference/workloads/Activation.cpp
+++ b/src/backends/reference/workloads/Activation.cpp
@@ -11,6 +11,91 @@
namespace armnn
{
+float Activation(float in,
+ ActivationFunction function,
+ float a,
+ float b)
+{
+ float output;
+
+ // Compute the result of the activation function.
+ switch (function)
+ {
+ case ActivationFunction::Linear:
+ {
+ output = a * in + b;
+ break;
+ }
+ case ActivationFunction::Sigmoid:
+ {
+ output = 1.f / (1.f + expf(-in));
+ break;
+ }
+ case ActivationFunction::ReLu:
+ {
+ output = std::max(0.f, in);
+ break;
+ }
+ case ActivationFunction::BoundedReLu:
+ {
+ output = std::min(a, std::max(b, in));
+ break;
+ }
+ case ActivationFunction::SoftReLu:
+ {
+ output = logf(1.0f + expf(in));
+ break;
+ }
+ case ActivationFunction::LeakyReLu:
+ {
+ output = in > 0.0f ? in : (in * a);
+ break;
+ }
+ case ActivationFunction::Abs:
+ {
+ output = in < 0 ? -in : in;
+ break;
+ }
+ case ActivationFunction::Sqrt:
+ {
+ output = sqrtf(in);
+ break;
+ }
+ case ActivationFunction::Square:
+ {
+ output = in * in;
+ break;
+ }
+ case ActivationFunction::TanH:
+ {
+ output = a * tanhf(b * in);
+ break;
+ }
+ default:
+ {
+ throw InvalidArgumentException("Unsupported activation function");
+ }
+ }
+
+ return output;
+}
+
+
+void Activation(Decoder<float>& in,
+ Encoder<float>& out,
+ const TensorInfo& tensorInfo,
+ ActivationFunction function,
+ float a,
+ float b)
+{
+ for (size_t i = 0; i<tensorInfo.GetNumElements(); i++)
+ {
+ out.Set(Activation(in.Get(), function, a, b));
+
+ ++in;
+ ++out;
+ }
+}
void Activation(const float* in,
float* out,
@@ -21,70 +106,7 @@ void Activation(const float* in,
{
for (size_t i = 0; i<tensorInfo.GetNumElements(); i++)
{
- float input = in[i];
- float output;
-
- // Compute the result of the activation function.
- switch (function)
- {
- case ActivationFunction::Linear:
- {
- output = a * input + b;
- break;
- }
- case ActivationFunction::Sigmoid:
- {
- output = 1.f / (1.f + expf(-input));
- break;
- }
- case ActivationFunction::ReLu:
- {
- output = std::max(0.f, input);
- break;
- }
- case ActivationFunction::BoundedReLu:
- {
- output = std::min(a, std::max(b, input));
- break;
- }
- case ActivationFunction::SoftReLu:
- {
- output = logf(1.0f + expf(input));
- break;
- }
- case ActivationFunction::LeakyReLu:
- {
- output = input > 0.0f ? input : (input * a);
- break;
- }
- case ActivationFunction::Abs:
- {
- output = input < 0 ? -input : input;
- break;
- }
- case ActivationFunction::Sqrt:
- {
- output = sqrtf(input);
- break;
- }
- case ActivationFunction::Square:
- {
- output = input * input;
- break;
- }
- case ActivationFunction::TanH:
- {
- output = a * tanhf(b * input);
- break;
- }
- default:
- {
- BOOST_LOG_TRIVIAL(error) << "Unsupported activation function";
- return;
- }
- }
-
- out[i] = output;
+ out[i] = Activation(in[i], function, a, b);
}
}
diff --git a/src/backends/reference/workloads/Activation.hpp b/src/backends/reference/workloads/Activation.hpp
index c8a23114f0..ffe3c5fc5d 100644
--- a/src/backends/reference/workloads/Activation.hpp
+++ b/src/backends/reference/workloads/Activation.hpp
@@ -3,18 +3,30 @@
// SPDX-License-Identifier: MIT
//
+#include "BaseIterator.hpp"
+
#include <armnn/Tensor.hpp>
#include <armnn/Types.hpp>
namespace armnn
{
+float Activation(float in,
+ ActivationFunction function,
+ float a,
+ float b);
-/// Performs the ActivationFunction elementwise on the inputs to give the outputs.
+void Activation(Decoder<float>& in,
+ Encoder<float>& out,
+ const TensorInfo& tensorInfo,
+ ActivationFunction function,
+ float a,
+ float b);
+
+// This is still used by Reference LSTM implementation
void Activation(const float* in,
float* out,
const TensorInfo& tensorInfo,
ActivationFunction function,
float a,
float b);
-
} //namespace armnn
diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt
index e94b031060..596c0993e0 100644
--- a/src/backends/reference/workloads/CMakeLists.txt
+++ b/src/backends/reference/workloads/CMakeLists.txt
@@ -34,10 +34,8 @@ list(APPEND armnnRefBackendWorkloads_sources
Pad.hpp
Pooling2d.cpp
Pooling2d.hpp
- RefActivationFloat32Workload.cpp
- RefActivationFloat32Workload.hpp
- RefActivationUint8Workload.cpp
- RefActivationUint8Workload.hpp
+ RefActivationWorkload.cpp
+ RefActivationWorkload.hpp
RefBatchNormalizationFloat32Workload.cpp
RefBatchNormalizationFloat32Workload.hpp
RefBatchNormalizationUint8Workload.cpp
diff --git a/src/backends/reference/workloads/Decoders.hpp b/src/backends/reference/workloads/Decoders.hpp
index 4112e7d454..acf20c4b69 100644
--- a/src/backends/reference/workloads/Decoders.hpp
+++ b/src/backends/reference/workloads/Decoders.hpp
@@ -11,10 +11,10 @@ namespace armnn
{
template<typename T>
-std::unique_ptr<Decoder<T>> MakeDecoder(const TensorInfo& info, const void* data);
+inline std::unique_ptr<Decoder<T>> MakeDecoder(const TensorInfo& info, const void* data);
template<>
-std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const void* data)
+inline std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const void* data)
{
switch(info.GetDataType())
{
@@ -45,4 +45,4 @@ std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const void*
return nullptr;
}
-} //namespace armnn \ No newline at end of file
+} //namespace armnn
diff --git a/src/backends/reference/workloads/Encoders.hpp b/src/backends/reference/workloads/Encoders.hpp
index 90300aa0f7..547bead98a 100644
--- a/src/backends/reference/workloads/Encoders.hpp
+++ b/src/backends/reference/workloads/Encoders.hpp
@@ -11,10 +11,10 @@ namespace armnn
{
template<typename T>
-std::unique_ptr<Encoder<T>> MakeEncoder(const TensorInfo& info, void* data);
+inline std::unique_ptr<Encoder<T>> MakeEncoder(const TensorInfo& info, void* data);
template<>
-std::unique_ptr<Encoder<float>> MakeEncoder(const TensorInfo& info, void* data)
+inline std::unique_ptr<Encoder<float>> MakeEncoder(const TensorInfo& info, void* data)
{
switch(info.GetDataType())
{
@@ -46,7 +46,7 @@ std::unique_ptr<Encoder<float>> MakeEncoder(const TensorInfo& info, void* data)
}
template<>
-std::unique_ptr<Encoder<bool>> MakeEncoder(const TensorInfo& info, void* data)
+inline std::unique_ptr<Encoder<bool>> MakeEncoder(const TensorInfo& info, void* data)
{
switch(info.GetDataType())
{
@@ -63,4 +63,4 @@ std::unique_ptr<Encoder<bool>> MakeEncoder(const TensorInfo& info, void* data)
return nullptr;
}
-} //namespace armnn \ No newline at end of file
+} //namespace armnn
diff --git a/src/backends/reference/workloads/RefActivationFloat32Workload.cpp b/src/backends/reference/workloads/RefActivationFloat32Workload.cpp
deleted file mode 100644
index 3cc59be7a4..0000000000
--- a/src/backends/reference/workloads/RefActivationFloat32Workload.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-
-#include "RefActivationFloat32Workload.hpp"
-
-#include "Activation.hpp"
-#include "RefWorkloadUtils.hpp"
-
-#include "Profiling.hpp"
-
-namespace armnn
-{
-
-void RefActivationFloat32Workload::Execute() const
-{
- ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefActivationFloat32Workload_Execute");
-
- Activation(GetInputTensorDataFloat(0, m_Data),
- GetOutputTensorDataFloat(0, m_Data),
- GetTensorInfo(m_Data.m_Inputs[0]),
- m_Data.m_Parameters.m_Function,
- m_Data.m_Parameters.m_A,
- m_Data.m_Parameters.m_B);
-}
-
-} //namespace armnn
diff --git a/src/backends/reference/workloads/RefActivationFloat32Workload.hpp b/src/backends/reference/workloads/RefActivationFloat32Workload.hpp
deleted file mode 100644
index dd65697e57..0000000000
--- a/src/backends/reference/workloads/RefActivationFloat32Workload.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-
-#pragma once
-
-#include <backendsCommon/Workload.hpp>
-
-namespace armnn
-{
-
-class RefActivationFloat32Workload : public Float32Workload<ActivationQueueDescriptor>
-{
-public:
- using Float32Workload<ActivationQueueDescriptor>::Float32Workload;
- virtual void Execute() const override;
-};
-
-} //namespace armnn
diff --git a/src/backends/reference/workloads/RefActivationUint8Workload.cpp b/src/backends/reference/workloads/RefActivationUint8Workload.cpp
deleted file mode 100644
index b95c2e22a8..0000000000
--- a/src/backends/reference/workloads/RefActivationUint8Workload.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright © 2017 Arm Ltd. All rights reserved.
-// SPDX-License-Identifier: MIT
-//
-
-#include "RefActivationUint8Workload.hpp"
-
-#include "Activation.hpp"
-#include "RefWorkloadUtils.hpp"
-
-#include "Profiling.hpp"
-
-#include <vector>
-
-namespace armnn
-{
-
-void RefActivationUint8Workload::Execute() const
-{
- ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefActivationUint8Workload_Execute");
-
- const TensorInfo& tensorInfo = GetTensorInfo(m_Data.m_Inputs[0]);
-
- auto dequant = Dequantize(GetInputTensorDataU8(0, m_Data), tensorInfo);
-
- std::vector<float> results(tensorInfo.GetNumElements());
-
- Activation(dequant.data(),
- results.data(),
- tensorInfo,
- m_Data.m_Parameters.m_Function,
- m_Data.m_Parameters.m_A,
- m_Data.m_Parameters.m_B);
-
- Quantize(GetOutputTensorDataU8(0, m_Data), results.data(), GetTensorInfo(m_Data.m_Outputs[0]));
-}
-
-} //namespace armnn
diff --git a/src/backends/reference/workloads/RefActivationWorkload.cpp b/src/backends/reference/workloads/RefActivationWorkload.cpp
new file mode 100644
index 0000000000..78c971e183
--- /dev/null
+++ b/src/backends/reference/workloads/RefActivationWorkload.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "RefActivationWorkload.hpp"
+
+#include "Activation.hpp"
+#include "Decoders.hpp"
+#include "Encoders.hpp"
+#include "RefWorkloadUtils.hpp"
+
+#include "Profiling.hpp"
+
+namespace armnn
+{
+
+void RefActivationWorkload::Execute() const
+{
+ ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefActivationWorkload_Execute");
+
+ const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]);
+ const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]);
+
+ Activation(*MakeDecoder<float>(inputInfo, m_Data.m_Inputs[0]->Map()),
+ *MakeEncoder<float>(outputInfo, m_Data.m_Outputs[0]->Map()),
+ inputInfo,
+ m_Data.m_Parameters.m_Function,
+ m_Data.m_Parameters.m_A,
+ m_Data.m_Parameters.m_B);
+}
+
+} //namespace armnn
diff --git a/src/backends/reference/workloads/RefActivationUint8Workload.hpp b/src/backends/reference/workloads/RefActivationWorkload.hpp
index 66f5e327f1..a3b001e61f 100644
--- a/src/backends/reference/workloads/RefActivationUint8Workload.hpp
+++ b/src/backends/reference/workloads/RefActivationWorkload.hpp
@@ -11,10 +11,10 @@
namespace armnn
{
-class RefActivationUint8Workload : public Uint8Workload<ActivationQueueDescriptor>
+class RefActivationWorkload : public BaseWorkload<ActivationQueueDescriptor>
{
public:
- using Uint8Workload<ActivationQueueDescriptor>::Uint8Workload;
+ using BaseWorkload<ActivationQueueDescriptor>::BaseWorkload;
virtual void Execute() const override;
};
diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp
index a1b584759b..7871a1b806 100644
--- a/src/backends/reference/workloads/RefWorkloads.hpp
+++ b/src/backends/reference/workloads/RefWorkloads.hpp
@@ -13,7 +13,7 @@
#include "RefSplitterUint8Workload.hpp"
#include "RefResizeBilinearUint8Workload.hpp"
#include "RefL2NormalizationFloat32Workload.hpp"
-#include "RefActivationUint8Workload.hpp"
+#include "RefActivationWorkload.hpp"
#include "RefPooling2dFloat32Workload.hpp"
#include "RefWorkloadUtils.hpp"
#include "RefMergerUint8Workload.hpp"
@@ -47,7 +47,6 @@
#include "RefSpaceToBatchNdWorkload.hpp"
#include "RefSplitterFloat32Workload.hpp"
#include "RefStridedSliceWorkload.hpp"
-#include "RefActivationFloat32Workload.hpp"
#include "RefConvolution2dFloat32Workload.hpp"
#include "Pooling2d.hpp"
#include "RefFakeQuantizationFloat32Workload.hpp"
@@ -64,4 +63,4 @@
#include "RefRsqrtFloat32Workload.hpp"
#include "RefDequantizeWorkload.hpp"
-#include "RefQuantizeWorkload.hpp" \ No newline at end of file
+#include "RefQuantizeWorkload.hpp"