diff options
author | Finn Williams <Finn.Williams@arm.com> | 2019-12-04 14:27:27 +0000 |
---|---|---|
committer | Jim Flynn Arm <jim.flynn@arm.com> | 2019-12-09 15:39:16 +0000 |
commit | fd2710651ada27fc82f28c07fb1e09effc3bda2d (patch) | |
tree | 7c2200489c7a3f845b91362c2c8d66ab9c6101e8 /src/backends | |
parent | 6a5e5e8b7e56f927d70ced3203d6e16df3fdd189 (diff) | |
download | armnn-fd2710651ada27fc82f28c07fb1e09effc3bda2d.tar.gz |
IVGCVSW-4211 Add Signed 8 bit Quantisation support into the Reference backend
!android-nn-driver:2435
Signed-off-by: Finn Williams <Finn.Williams@arm.com>
Change-Id: I10ecd4a8937725953396805f33a3562a5384c4d4
Diffstat (limited to 'src/backends')
12 files changed, 105 insertions, 4 deletions
diff --git a/src/backends/aclCommon/ArmComputeTensorUtils.cpp b/src/backends/aclCommon/ArmComputeTensorUtils.cpp index 328a083ae9..9250b61ec9 100644 --- a/src/backends/aclCommon/ArmComputeTensorUtils.cpp +++ b/src/backends/aclCommon/ArmComputeTensorUtils.cpp @@ -27,7 +27,7 @@ arm_compute::DataType GetArmComputeDataType(armnn::DataType dataType) return arm_compute::DataType::QASYMM8; case armnn::DataType::QuantisedSymm16: return arm_compute::DataType::QSYMM16; - case armnn::DataType::QuantisedSymm8: + case armnn::DataType::QSymmS8: return arm_compute::DataType::QSYMM8; case armnn::DataType::QuantizedSymm8PerAxis: return arm_compute::DataType::QSYMM8_PER_CHANNEL; diff --git a/src/backends/backendsCommon/WorkloadData.cpp b/src/backends/backendsCommon/WorkloadData.cpp index 56dff9be41..d9a1f46c9f 100644 --- a/src/backends/backendsCommon/WorkloadData.cpp +++ b/src/backends/backendsCommon/WorkloadData.cpp @@ -2179,6 +2179,7 @@ void QuantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName); if (outputTensorInfo.GetDataType() != DataType::QuantisedAsymm8 && + outputTensorInfo.GetDataType() != DataType::QSymmS8 && outputTensorInfo.GetDataType() != DataType::QuantisedSymm16) { throw InvalidArgumentException(descriptorName + ": Output of quantized layer must be quantized type."); diff --git a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp index 6a3e852ed2..844b1090ce 100644 --- a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp +++ b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp @@ -143,6 +143,13 @@ LayerTestResult<float, 4> DequantizeOffsetUint8Test( return DequantizeOffsetTest<armnn::DataType::QuantisedAsymm8>(workloadFactory, memoryManager); } +LayerTestResult<float, 4> DequantizeSimpleInt8Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) +{ + return DequantizeSimpleTest<armnn::DataType::QSymmS8>(workloadFactory, memoryManager); +} + LayerTestResult<float, 4> DequantizeSimpleInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) @@ -158,6 +165,13 @@ LayerTestResult<armnn::Half, 4> DequantizeSimpleUint8ToFp16Test( memoryManager); } +LayerTestResult<armnn::Half, 4> DequantizeSimpleInt8ToFp16Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) +{ + return DequantizeSimpleTest<armnn::DataType::QSymmS8, armnn::DataType::Float16>(workloadFactory, memoryManager); +} + LayerTestResult<armnn::Half, 4> DequantizeSimpleInt16ToFp16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) diff --git a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp index 008fea8833..c70f03e8f3 100644 --- a/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp +++ b/src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp @@ -20,6 +20,10 @@ LayerTestResult<float, 4> DequantizeOffsetUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); +LayerTestResult<float, 4> DequantizeSimpleInt8Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); + LayerTestResult<float, 4> DequantizeSimpleInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); @@ -28,6 +32,10 @@ LayerTestResult<armnn::Half, 4> DequantizeSimpleUint8ToFp16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); +LayerTestResult<armnn::Half, 4> DequantizeSimpleInt8ToFp16Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); + LayerTestResult<armnn::Half, 4> DequantizeSimpleInt16ToFp16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); diff --git a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp index 94d7224629..481f6813b6 100644 --- a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp +++ b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp @@ -139,6 +139,13 @@ LayerTestResult<uint8_t, 4> QuantizeClampUint8Test( return QuantizeClampTest<armnn::DataType::QuantisedAsymm8>(workloadFactory, memoryManager); } +LayerTestResult<int8_t, 4> QuantizeClampInt8Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) +{ + return QuantizeClampTest<armnn::DataType::QSymmS8>(workloadFactory, memoryManager); +} + LayerTestResult<int16_t, 4> QuantizeClampInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager) diff --git a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp index a2e1a49763..ece75fd43b 100644 --- a/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp +++ b/src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp @@ -18,6 +18,10 @@ LayerTestResult<uint8_t, 4> QuantizeClampUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); +LayerTestResult<int8_t, 4> QuantizeClampInt8Test( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); + LayerTestResult<int16_t, 4> QuantizeClampInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp index 299503ddc6..19b76152f3 100644 --- a/src/backends/reference/RefLayerSupport.cpp +++ b/src/backends/reference/RefLayerSupport.cpp @@ -615,8 +615,9 @@ bool RefLayerSupport::IsDequantizeSupported(const TensorInfo& input, { bool supported = true; - std::array<DataType,2> supportedInputTypes = { + std::array<DataType,3> supportedInputTypes = { DataType::QuantisedAsymm8, + DataType::QSymmS8, DataType::QuantisedSymm16 }; @@ -1398,7 +1399,7 @@ bool RefLayerSupport::IsQuantizeSupported(const TensorInfo& input, { bool supported = true; - // Define supported output types. + // Define supported input types. std::array<DataType,1> supportedInputTypes = { DataType::Float32, }; @@ -1407,8 +1408,9 @@ bool RefLayerSupport::IsQuantizeSupported(const TensorInfo& input, "Reference quantize: input type not supported."); // Define supported output types. - std::array<DataType,2> supportedOutputTypes = { + std::array<DataType,3> supportedOutputTypes = { DataType::QuantisedAsymm8, + DataType::QSymmS8, DataType::QuantisedSymm16 }; supported &= CheckSupportRule(TypeAnyOf(output, supportedOutputTypes), reasonIfUnsupported, diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index a397e935c1..b88f432acf 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -1419,13 +1419,16 @@ BOOST_AUTO_TEST_CASE(DetectionPostProcessFastNmsInt16) // Dequantize ARMNN_AUTO_TEST_CASE(DequantizeSimpleUint8, DequantizeSimpleUint8Test) ARMNN_AUTO_TEST_CASE(DequantizeOffsetUint8, DequantizeOffsetUint8Test) +ARMNN_AUTO_TEST_CASE(DequantizeSimpleInt8, DequantizeSimpleInt8Test) ARMNN_AUTO_TEST_CASE(DequantizeSimpleInt16, DequantizeSimpleInt16Test) ARMNN_AUTO_TEST_CASE(DequantizeSimpleUint8ToFp16, DequantizeSimpleUint8ToFp16Test) +ARMNN_AUTO_TEST_CASE(DequantizeSimpleInt8ToFp16, DequantizeSimpleInt8ToFp16Test) ARMNN_AUTO_TEST_CASE(DequantizeSimpleInt16ToFp16, DequantizeSimpleInt16ToFp16Test) // Quantize ARMNN_AUTO_TEST_CASE(QuantizeSimpleUint8, QuantizeSimpleUint8Test) ARMNN_AUTO_TEST_CASE(QuantizeClampUint8, QuantizeClampUint8Test) +ARMNN_AUTO_TEST_CASE(QuantizeClampInt8, QuantizeClampInt8Test) ARMNN_AUTO_TEST_CASE(QuantizeClampInt16, QuantizeClampInt16Test) // PReLU diff --git a/src/backends/reference/workloads/BaseIterator.hpp b/src/backends/reference/workloads/BaseIterator.hpp index ca5110c2fd..ca6d3cbc60 100644 --- a/src/backends/reference/workloads/BaseIterator.hpp +++ b/src/backends/reference/workloads/BaseIterator.hpp @@ -137,6 +137,25 @@ private: const int32_t m_Offset; }; +class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>> +{ +public: + QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset) + : TypedIterator(data), m_Scale(scale), m_Offset(offset) {} + + QSymmS8Decoder(const float scale, const int32_t offset) + : QSymmS8Decoder(nullptr, scale, offset) {} + + float Get() const override + { + return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset); + } + +private: + const float m_Scale; + const int32_t m_Offset; +}; + class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>> { public: @@ -245,6 +264,30 @@ private: const int32_t m_Offset; }; +class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>> +{ +public: + QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset) + : TypedIterator(data), m_Scale(scale), m_Offset(offset) {} + + QSymmS8Encoder(const float scale, const int32_t offset) + : QSymmS8Encoder(nullptr, scale, offset) {} + + void Set(float right) override + { + *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset); + } + + float Get() const override + { + return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset); + } + +private: + const float m_Scale; + const int32_t m_Offset; +}; + class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>> { public: diff --git a/src/backends/reference/workloads/Decoders.hpp b/src/backends/reference/workloads/Decoders.hpp index b9cd7f9573..9d41c9e9e7 100644 --- a/src/backends/reference/workloads/Decoders.hpp +++ b/src/backends/reference/workloads/Decoders.hpp @@ -105,6 +105,13 @@ inline std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const { return MakeSigned32Decoder(info, data); } + case DataType::QSymmS8: + { + return std::make_unique<QSymmS8Decoder>( + static_cast<const int8_t*>(data), + info.GetQuantizationScale(), + info.GetQuantizationOffset()); + } default: { BOOST_ASSERT_MSG(false, "Unsupported Data Type!"); diff --git a/src/backends/reference/workloads/Encoders.hpp b/src/backends/reference/workloads/Encoders.hpp index 0d578d68de..92493ed641 100644 --- a/src/backends/reference/workloads/Encoders.hpp +++ b/src/backends/reference/workloads/Encoders.hpp @@ -37,6 +37,13 @@ inline std::unique_ptr<Encoder<float>> MakeEncoder(const TensorInfo& info, void* info.GetQuantizationScale(), info.GetQuantizationOffset()); } + case DataType::QSymmS8: + { + return std::make_unique<QSymmS8Encoder>( + static_cast<int8_t*>(data), + info.GetQuantizationScale(), + info.GetQuantizationOffset()); + } case armnn::DataType::QuantisedSymm16: { return std::make_unique<QSymm16Encoder>( diff --git a/src/backends/reference/workloads/RefQuantizeWorkload.cpp b/src/backends/reference/workloads/RefQuantizeWorkload.cpp index b7ace32e14..a78804b709 100644 --- a/src/backends/reference/workloads/RefQuantizeWorkload.cpp +++ b/src/backends/reference/workloads/RefQuantizeWorkload.cpp @@ -48,6 +48,11 @@ void RefQuantizeWorkload::Execute() const QuantizeImpl<uint8_t>(input, output, m_NumElements, m_Scale, m_Offset); break; } + case DataType::QSymmS8: + { + QuantizeImpl<int8_t>(input, output, m_NumElements, m_Scale, m_Offset); + break; + } case DataType::QuantisedSymm16: { QuantizeImpl<int16_t>(input, output, m_NumElements, m_Scale, 0); |