aboutsummaryrefslogtreecommitdiff
path: root/shim
diff options
context:
space:
mode:
authorSadik Armagan <sadik.armagan@arm.com>2022-08-03 11:27:05 +0100
committerNikhil Raj <nikhil.raj@arm.com>2022-08-29 10:12:21 +0100
commitb016157f1eea1acc6a84308521c0b90543161da4 (patch)
treefe228d1014f4fa9a4f74227d0640719d1d92193c /shim
parentee480d2d6538b0192d40a00ed696b30e2587430c (diff)
downloadarmnn-b016157f1eea1acc6a84308521c0b90543161da4.tar.gz
IVGCVSW-6954 'Arm NN SL Improvements'
* Move the Conv2D and DepthwiseConv2D validation to Optimization level when the weights and tensors are as constant inputs * Take into account offset and scales values when doing INT8 to FP32 dequantization Signed-off-by: Sadik Armagan <sadik.armagan@arm.com> Change-Id: I1f81f15640395ac041923b10dbe9151159715117
Diffstat (limited to 'shim')
-rw-r--r--shim/sl/canonical/ConversionUtils.cpp46
-rw-r--r--shim/sl/canonical/ConversionUtils.hpp4
-rw-r--r--shim/sl/canonical/Converter.cpp77
3 files changed, 92 insertions, 35 deletions
diff --git a/shim/sl/canonical/ConversionUtils.cpp b/shim/sl/canonical/ConversionUtils.cpp
index 96a8ddca6a..f48af32e21 100644
--- a/shim/sl/canonical/ConversionUtils.cpp
+++ b/shim/sl/canonical/ConversionUtils.cpp
@@ -67,6 +67,11 @@ void LayerInputHandle::SanitizeQuantizationScale(LayerInputHandle& weight, Layer
}
}
+armnn::IOutputSlot* LayerInputHandle::GetOutputSlot() const
+{
+ return m_OutputSlot;
+}
+
ConstTensorPin::ConstTensorPin(bool optional)
: m_Optional(optional)
{}
@@ -276,17 +281,6 @@ LayerInputHandle ConvertToLayerInputHandle(const Operation& operation,
case OperandLifeTime::CONSTANT_REFERENCE:
{
auto constantTensorDataType = operandTensorInfo.GetDataType();
- if (inputHandle)
- {
- if ((inputHandle->GetTensorInfo().GetDataType() == armnn::DataType::Float32
- || inputHandle->GetTensorInfo().GetDataType() == armnn::DataType::Float16)
- && (operandTensorInfo.GetDataType() == armnn::DataType::QAsymmU8
- || operandTensorInfo.GetDataType() == armnn::DataType::QAsymmS8))
- {
- constantTensorDataType = inputHandle->GetTensorInfo().GetDataType();
- }
- }
-
// The tensor has an already known constant value, and can be converted into an ArmNN Constant layer.
ConstTensorPin tensorPin = ConvertOperandToConstTensorPin(*operand,
model,
@@ -1029,4 +1023,34 @@ bool SetupAndTrackLayerOutputSlot(const Operation& operation,
return true;
}
+bool IsConnectedToDequantize(armnn::IOutputSlot* ioutputSlot)
+{
+ VLOG(DRIVER) << "ConversionUtils::IsConnectedToDequantize()";
+ if (!ioutputSlot)
+ {
+ return false;
+ }
+ VLOG(DRIVER) << "ConversionUtils::IsConnectedToDequantize() ioutputSlot is valid.";
+ // Find the connections and layers..
+ armnn::IConnectableLayer& owningLayer = ioutputSlot->GetOwningIConnectableLayer();
+ if (owningLayer.GetType() == armnn::LayerType::Dequantize)
+ {
+ VLOG(DRIVER) << "ConversionUtils::IsConnectedToDequantize() connected to Dequantize Layer.";
+ armnn::IInputSlot& inputSlot = owningLayer.GetInputSlot(0);
+ armnn::IOutputSlot* connection = inputSlot.GetConnection();
+ if (connection)
+ {
+ VLOG(DRIVER) << "ConversionUtils::IsConnectedToDequantize() Dequantize Layer has a connection.";
+ armnn::IConnectableLayer& connectedLayer =
+ connection->GetOwningIConnectableLayer();
+ if (connectedLayer.GetType() == armnn::LayerType::Constant)
+ {
+ VLOG(DRIVER) << "ConversionUtils::IsConnectedToDequantize() Dequantize Layer connected to Constant";
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
} // namespace armnn_driver
diff --git a/shim/sl/canonical/ConversionUtils.hpp b/shim/sl/canonical/ConversionUtils.hpp
index 8058bcb379..beee00d11a 100644
--- a/shim/sl/canonical/ConversionUtils.hpp
+++ b/shim/sl/canonical/ConversionUtils.hpp
@@ -79,6 +79,8 @@ public:
void SanitizeQuantizationScale(LayerInputHandle& weight, LayerInputHandle& input);
+ armnn::IOutputSlot* GetOutputSlot() const;
+
private:
armnn::IOutputSlot* m_OutputSlot;
bool m_Valid;
@@ -1012,4 +1014,6 @@ ConstTensorPin DequantizeAndMakeConstTensorPin(const Operation& operation,
size_t operandIndex,
bool optional = false);
+bool IsConnectedToDequantize(armnn::IOutputSlot* ioutputSlot);
+
} // namespace armnn_driver
diff --git a/shim/sl/canonical/Converter.cpp b/shim/sl/canonical/Converter.cpp
index fc983dc081..b50b0a9397 100644
--- a/shim/sl/canonical/Converter.cpp
+++ b/shim/sl/canonical/Converter.cpp
@@ -998,9 +998,20 @@ bool Converter::ConvertConv2d(const Operation& operation, const Model& model, Co
desc.m_BiasEnabled = true;
Optional<TensorInfo> biases(biasInfo);
- bool isSupported = false;
- auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported)
+ bool requiresValidation = true;
+ const Operand* weightsOperand = GetInputOperand(operation, 1, model);
+ const Operand* biasOperand = GetInputOperand(operation, 2, model);
+ if (IsConnectedToDequantize(weightsInput.GetOutputSlot())
+ || IsConnectedToDequantize(biasInput.GetOutputSlot()))
{
+ // Do not require validation for now. There will be an optimization step
+ // [ConvertConstDequantisationLayersToConstLayers] will convert layers to Constant layers
+ // then at the end of the optimization there will be layer supported validation.
+ requiresValidation = false;
+ VLOG(DRIVER) << "Converter::ConvertConv2d(): Weights and Biases are as INPUTS.";
+ }
+
+ auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) {
FORWARD_LAYER_SUPPORT_FUNC(__func__,
IsConvolution2dSupported,
data.m_Backends,
@@ -1012,18 +1023,23 @@ bool Converter::ConvertConv2d(const Operation& operation, const Model& model, Co
biases);
};
- if(!IsDynamicTensor(outputInfo))
+ if (requiresValidation)
{
- validateFunc(outputInfo, isSupported);
- }
- else
- {
- isSupported = AreDynamicTensorsSupported();
- }
+ VLOG(DRIVER) << "Converter::ConvertConv2d(): Requires Validation!";
+ bool isSupported = false;
+ if (!IsDynamicTensor(outputInfo))
+ {
+ validateFunc(outputInfo, isSupported);
+ }
+ else
+ {
+ isSupported = AreDynamicTensorsSupported();
+ }
- if (!isSupported)
- {
- return false;
+ if (!isSupported)
+ {
+ return false;
+ }
}
armnn::IConnectableLayer* startLayer = data.m_Network->AddConvolution2dLayer(desc);
@@ -1231,9 +1247,17 @@ bool Converter::ConvertDepthwiseConv2d(const Operation& operation, const Model&
desc.m_BiasEnabled = true;
Optional<TensorInfo> biases(biasInfo);
- bool isSupported = false;
- auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported)
+ bool requiresValidation = true;
+ if (IsConnectedToDequantize(weightsInput.GetOutputSlot()) || IsConnectedToDequantize(biasInput.GetOutputSlot()))
{
+ // Do not require validation for now. There will be an optimization step
+ // [ConvertConstDequantisationLayersToConstLayers] will convert layers to Constant layers
+ // then at the end of the optimization there will be layer supported validation.
+ requiresValidation = false;
+ VLOG(DRIVER) << "Converter::ConvertDepthwiseConv2d(): Weights and Biases are as INPUTS.";
+ }
+
+ auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) {
FORWARD_LAYER_SUPPORT_FUNC(__func__,
IsDepthwiseConvolutionSupported,
data.m_Backends,
@@ -1245,18 +1269,23 @@ bool Converter::ConvertDepthwiseConv2d(const Operation& operation, const Model&
biases);
};
- if(!IsDynamicTensor(outputInfo))
+ if (requiresValidation)
{
- validateFunc(outputInfo, isSupported);
- }
- else
- {
- isSupported = AreDynamicTensorsSupported();
- }
+ VLOG(DRIVER) << "Converter::ConvertDepthwiseConv2d(): Requires Validation!";
+ bool isSupported = false;
+ if (!IsDynamicTensor(outputInfo))
+ {
+ validateFunc(outputInfo, isSupported);
+ }
+ else
+ {
+ isSupported = AreDynamicTensorsSupported();
+ }
- if (!isSupported)
- {
- return false;
+ if (!isSupported)
+ {
+ return false;
+ }
}
armnn::IConnectableLayer* startLayer = data.m_Network->AddDepthwiseConvolution2dLayer(desc);