IVGCVSW-4390 Refactor QUANTIZE to make use of Decoder/Encoder types
authorKeith Davis <keith.davis@arm.com>
Wed, 29 Jan 2020 16:52:59 +0000 (16:52 +0000)
committerKeith Davis <keith.davis@arm.com>
Fri, 31 Jan 2020 16:43:52 +0000 (16:43 +0000)
 * Add no-ops for CL/NEON Uint8
 * Refactor Quantize workload to Decoder/Encoder types

Signed-off-by: Keith Davis <keith.davis@arm.com>
Change-Id: I80b09de528299b925e2ac38acd9a5019b8d3e4ac

src/backends/backendsCommon/WorkloadData.cpp
src/backends/cl/ClWorkloadFactory.cpp
src/backends/neon/NeonWorkloadFactory.cpp
src/backends/reference/RefLayerSupport.cpp
src/backends/reference/workloads/RefQuantizeWorkload.cpp
src/backends/reference/workloads/RefQuantizeWorkload.hpp

index 5057c8c4dfd67c41869ac99acc564d523f99f511..8bf2b0f988a1f7bd55a402fab0e557c6f224bf82 100644 (file)
@@ -2199,7 +2199,10 @@ void QuantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
     std::vector<DataType> supportedTypes =
     {
         DataType::Float32,
-        DataType::Float16
+        DataType::Float16,
+        DataType::QSymmS8,
+        DataType::QAsymmU8,
+        DataType::QSymmS16
     };
 
     ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
index 4bb2e2a8ce0ca7e5c1c4680d5ad108ac005107cd..0440aac0221087808dc1832eae3f37defc3093fa 100644 (file)
@@ -438,7 +438,7 @@ std::unique_ptr<IWorkload> ClWorkloadFactory::CreatePrelu(const PreluQueueDescri
 std::unique_ptr<IWorkload> ClWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
                                                              const WorkloadInfo& info) const
 {
-    return MakeWorkload<ClQuantizeWorkload>(descriptor, info);
+    return MakeWorkload<ClQuantizeWorkload, NullWorkload>(descriptor, info);
 }
 
 std::unique_ptr<IWorkload> ClWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& descriptor,
index 38e471f1d3c14e6cb98451053e7980d3ebeb4ce7..2639850a06f353ef2c3b50781d99fd7bfe43ff21 100644 (file)
@@ -407,7 +407,7 @@ std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreatePrelu(const armnn::
 std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateQuantize(const QuantizeQueueDescriptor& descriptor,
                                                                       const WorkloadInfo& info) const
 {
-    return std::make_unique<NeonQuantizeWorkload>(descriptor, info);
+    return MakeWorkloadHelper<NeonQuantizeWorkload, NullWorkload>(descriptor, info);
 }
 
 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateQuantizedLstm(const QuantizedLstmQueueDescriptor& descriptor,
index 8410c303ae83ec071bb51a70cedcc94b9d300ce3..c6a3af46bf7ebf4a58a09a571440ae3794193ded 100644 (file)
@@ -1439,9 +1439,12 @@ bool RefLayerSupport::IsQuantizeSupported(const TensorInfo& input,
    bool supported = true;
 
     // Define supported input types.
-    std::array<DataType,2> supportedInputTypes = {
+    std::array<DataType,5> supportedInputTypes = {
         DataType::QSymmS8,
-        DataType::Float32
+        DataType::Float32,
+        DataType::QAsymmU8,
+        DataType::QSymmS8,
+        DataType::QSymmS16
     };
 
     supported &= CheckSupportRule(TypeAnyOf(input, supportedInputTypes), reasonIfUnsupported,
index ab2ee7fc4e90f1a91ffbc046d8af2a781dc460b7..2eef5f33db050ea59aa36c5edc7879d1147adb64 100644 (file)
@@ -5,6 +5,8 @@
 
 #include "RefQuantizeWorkload.hpp"
 
+#include "RefWorkloadUtils.hpp"
+
 #include <armnn/TypesUtils.hpp>
 
 
@@ -14,14 +16,13 @@ namespace armnn
 namespace
 {
 
-template<typename T>
-void QuantizeImpl(const void *input, void *output, size_t numValues, float scale, int offset)
+void QuantizeImpl(Decoder<float>& in, Encoder<float>& out, size_t numValues)
 {
-    auto in = static_cast<const float *>(input);
-    auto out = static_cast<T *>(output);
-    for (size_t i = 0; i < numValues; i++, in++, out++)
+    for (unsigned int i = 0; i < numValues; i++)
     {
-        *out = armnn::Quantize<T>(*in, scale, offset);
+        in[i];
+        out[i];
+        out.Set(in.Get());
     }
 }
 
@@ -30,42 +31,24 @@ void QuantizeImpl(const void *input, void *output, size_t numValues, float scale
 RefQuantizeWorkload::RefQuantizeWorkload(const QuantizeQueueDescriptor& descriptor, const WorkloadInfo &info)
     : BaseWorkload(descriptor, info)
     , m_NumElements(info.m_InputTensorInfos[0].GetNumElements())
-    , m_TargetType(info.m_OutputTensorInfos[0].GetDataType())
-    , m_Scale(info.m_OutputTensorInfos[0].GetQuantizationScale())
-    , m_Offset(info.m_OutputTensorInfos[0].GetQuantizationOffset())
 {
 }
 
-void RefQuantizeWorkload::Execute() const
+void RefQuantizeWorkload::PostAllocationConfigure()
 {
-    const void* input = m_Data.m_Inputs[0]->Map(true);
-    void* output =  m_Data.m_Outputs[0]->Map(true);
+    const TensorInfo& inputInfo = armnn::GetTensorInfo(m_Data.m_Inputs[0]);
+    m_InputDecoder = MakeDecoder<float>(inputInfo);
 
-    switch(m_TargetType)
-    {
-        case DataType::QAsymmU8:
-        {
-            QuantizeImpl<uint8_t>(input, output, m_NumElements, m_Scale, m_Offset);
-            break;
-        }
-        case DataType::QSymmS8:
-        {
-            QuantizeImpl<int8_t>(input, output, m_NumElements, m_Scale, 0);
-            break;
-        }
-        case DataType::QSymmS16:
-        {
-            QuantizeImpl<int16_t>(input, output, m_NumElements, m_Scale, 0);
-            break;
-        }
-        default:
-        {
-            BOOST_ASSERT_MSG(false, "RefQuantizeWorkload: Non quantized output type encountered");
-        }
-    }
+    const TensorInfo& outputInfo = armnn::GetTensorInfo(m_Data.m_Outputs[0]);
+    m_OutputEncoder = MakeEncoder<float>(outputInfo);
+}
+
+void RefQuantizeWorkload::Execute() const
+{
+    m_InputDecoder->Reset(m_Data.m_Inputs[0]->Map());
+    m_OutputEncoder->Reset(m_Data.m_Outputs[0]->Map());
 
-    m_Data.m_Inputs[0]->Unmap();
-    m_Data.m_Outputs[0]->Unmap();
+    QuantizeImpl(*m_InputDecoder, *m_OutputEncoder, m_NumElements);
 }
 
 } //namespace armnn
\ No newline at end of file
index 6a43b8471ddc795d47a9ccf400c7949039ee2eee..9ae107607bfb9b463f29eed21cefe91c33899269 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <backendsCommon/Workload.hpp>
 #include <backendsCommon/WorkloadData.hpp>
+#include "Decoders.hpp"
+#include "Encoders.hpp"
 
 namespace armnn {
 
@@ -14,13 +16,15 @@ class RefQuantizeWorkload : public BaseWorkload<QuantizeQueueDescriptor>
 {
 public:
     RefQuantizeWorkload(const QuantizeQueueDescriptor& descriptor, const WorkloadInfo &info);
+    void PostAllocationConfigure() override;
     void Execute() const override;
 
 private:
+
+    std::unique_ptr<Decoder<float>> m_InputDecoder;
+    std::unique_ptr<Encoder<float>> m_OutputEncoder;
+
     size_t m_NumElements;
-    armnn::DataType m_TargetType;
-    float m_Scale;
-    int m_Offset;
 };
 
 } //namespace armnn
\ No newline at end of file