aboutsummaryrefslogtreecommitdiff
path: root/ConversionUtils.hpp
diff options
context:
space:
mode:
authorAron Virginas-Tar <Aron.Virginas-Tar@arm.com>2019-11-06 14:32:30 +0000
committerAron Virginas-Tar <Aron.Virginas-Tar@arm.com>2019-11-06 15:28:34 +0000
commit9f0693b41a33d4d17ef016d8a5490cc65a8cfb8a (patch)
treee19c9f330b90d3161e089b281be26aac0e44e7be /ConversionUtils.hpp
parent3b959603ab1e3dc7b7b70798f357b3fe6c0e47c8 (diff)
downloadandroid-nn-driver-9f0693b41a33d4d17ef016d8a5490cc65a8cfb8a.tar.gz
IVGCVSW-3841 Add support for per-axis quantization
Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com> Change-Id: Ife7fa63b8839465e8f9f8626f34ca8c0f4d12788
Diffstat (limited to 'ConversionUtils.hpp')
-rw-r--r--ConversionUtils.hpp46
1 files changed, 34 insertions, 12 deletions
diff --git a/ConversionUtils.hpp b/ConversionUtils.hpp
index e4ac4a5a..1975434a 100644
--- a/ConversionUtils.hpp
+++ b/ConversionUtils.hpp
@@ -183,11 +183,12 @@ inline bool IsOperandTypeSupportedForTensors(V1_0::OperandType type)
inline bool IsOperandTypeSupportedForTensors(V1_2::OperandType type)
{
- return type == V1_2::OperandType::BOOL ||
- type == V1_2::OperandType::TENSOR_FLOAT16 ||
- type == V1_2::OperandType::TENSOR_FLOAT32 ||
- type == V1_2::OperandType::TENSOR_QUANT8_ASYMM ||
- type == V1_2::OperandType::TENSOR_QUANT16_SYMM ||
+ return type == V1_2::OperandType::BOOL ||
+ type == V1_2::OperandType::TENSOR_FLOAT16 ||
+ type == V1_2::OperandType::TENSOR_FLOAT32 ||
+ type == V1_2::OperandType::TENSOR_QUANT8_ASYMM ||
+ type == V1_2::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL ||
+ type == V1_2::OperandType::TENSOR_QUANT16_SYMM ||
type == V1_2::OperandType::TENSOR_INT32;
}
@@ -384,16 +385,37 @@ Shape GetOperandShape(const V1_2::Operand& operand)
// we accept some tolerance. We don't want ArmNN itself to accept these inconsistencies as it is up to the
// user (us, in this case) to ensure they match.
void SanitizeBiasQuantizationScale(armnn::TensorInfo& biasInfo,
- const armnn::TensorInfo& weightInfo, const armnn::TensorInfo& inputInfo)
+ const armnn::TensorInfo& weightInfo,
+ const armnn::TensorInfo& inputInfo)
{
- const float expectedBiasScale = weightInfo.GetQuantizationScale() * inputInfo.GetQuantizationScale();
- if (biasInfo.GetQuantizationScale() != expectedBiasScale)
+ if (weightInfo.HasPerAxisQuantization())
{
- boost::math::fpc::close_at_tolerance<float> comparer(boost::math::fpc::percent_tolerance(1.0f));
- if (comparer(biasInfo.GetQuantizationScale(), expectedBiasScale))
+ // NOTE: Bias scale is always set to 0 for per-axis quantization and
+ // it needs to be calculated: scale[i] = input_scale * weight_scale[i]
+ auto UpdateBiasScaleValue = [&inputInfo](float biasScale) -> float
{
- ALOGW("Bias quantization scale has been modified to match input*weights");
- biasInfo.SetQuantizationScale(expectedBiasScale);
+ return biasScale * inputInfo.GetQuantizationScale();
+ };
+
+ std::vector<float> biasScales(weightInfo.GetQuantizationScales());
+ std::transform(biasScales.begin(), biasScales.end(), biasScales.begin(), UpdateBiasScaleValue);
+
+ biasInfo.SetQuantizationScales(biasScales);
+ biasInfo.SetQuantizationDim(weightInfo.GetQuantizationDim());
+
+ ALOGV("Bias quantization params have been updated for per-axis quantization");
+ }
+ else
+ {
+ const float expectedBiasScale = weightInfo.GetQuantizationScale() * inputInfo.GetQuantizationScale();
+ if (biasInfo.GetQuantizationScale() != expectedBiasScale)
+ {
+ boost::math::fpc::close_at_tolerance<float> comparer(boost::math::fpc::percent_tolerance(1.0f));
+ if (comparer(biasInfo.GetQuantizationScale(), expectedBiasScale))
+ {
+ ALOGW("Bias quantization scale has been modified to match input * weights");
+ biasInfo.SetQuantizationScale(expectedBiasScale);
+ }
}
}
}