From a4983cec09a3e24bf4e99abd31aa11842e8b365f Mon Sep 17 00:00:00 2001 From: Finn Williams Date: Thu, 23 Jul 2020 12:55:12 +0100 Subject: IVGCVSW-4931 Update NN Driver to support dynamic tensors * Change NN Driver m_Network to now have ShapeInferenceMethod::InferAndValidate * Implement dynamic tensor support for: - ArgMinMax layer - Pooling2d layer - Activation layer * Skip dynamic tensor tests for any HAL other than 1.3 Change-Id: Icf66c968e49cdd4822b8c79c5f18b3f9e97dc53f Signed-off-by: Finn Williams Signed-off-by: Teresa Charlin --- ConversionUtils.hpp | 151 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 45 deletions(-) (limited to 'ConversionUtils.hpp') diff --git a/ConversionUtils.hpp b/ConversionUtils.hpp index 5dc9993d..474d1a58 100644 --- a/ConversionUtils.hpp +++ b/ConversionUtils.hpp @@ -62,6 +62,8 @@ public: void Connect(armnn::IInputSlot& inputSlot); + void Disconnect(armnn::IInputSlot& inputSlot); + const armnn::TensorInfo& GetTensorInfo() const; private: @@ -1380,7 +1382,8 @@ bool SetupAndTrackLayerOutputSlot(const HalOperation& operation, uint32_t layerOutputIndex, const HalModel& model, ConversionData& data, - const armnn::TensorInfo* overrideOutputInfo = nullptr) + const armnn::TensorInfo* overrideOutputInfo = nullptr, + const std::function & validateFunc = nullptr) { using HalOperand = typename HalPolicy::Operand; @@ -1392,18 +1395,39 @@ bool SetupAndTrackLayerOutputSlot(const HalOperation& operation, armnn::IOutputSlot& outputSlot = layer.GetOutputSlot(layerOutputIndex); - const uint32_t operandIndex = operation.outputs[operationOutputIndex]; - data.m_OutputSlotForOperand[operandIndex] = &outputSlot; - - if (overrideOutputInfo == nullptr) + bool isSupported = false; + if (validateFunc && + layer.GetInputSlot(0).GetConnection() && + IsDynamicTensor(outputSlot.GetTensorInfo())) { - outputSlot.SetTensorInfo(GetTensorInfoForOperand(*outputOperand)); + outputSlot.IsTensorInfoSet(); + validateFunc(outputSlot.GetTensorInfo(), isSupported); + + if(!isSupported) + { + for (unsigned int inputSlotIndex = 0; inputSlotIndex < layer.GetNumInputSlots(); ++inputSlotIndex) + { + layer.GetInputSlot(inputSlotIndex).GetConnection()->Disconnect(layer.GetInputSlot(inputSlotIndex)); + } + + return false; + } } else { - outputSlot.SetTensorInfo(*overrideOutputInfo); + if (overrideOutputInfo == nullptr) + { + outputSlot.SetTensorInfo(GetTensorInfoForOperand(*outputOperand)); + } + else + { + outputSlot.SetTensorInfo(*overrideOutputInfo); + } } + const uint32_t operandIndex = operation.outputs[operationOutputIndex]; + data.m_OutputSlotForOperand[operandIndex] = &outputSlot; + return true; } @@ -1452,7 +1476,8 @@ bool SetupAndTrackLayerOutputSlot(const HalOperation& operation, armnn::IConnectableLayer& layer, const HalModel& model, ConversionData& data, - const armnn::TensorInfo* overrideOutputInfo = nullptr) + const armnn::TensorInfo* overrideOutputInfo = nullptr, + const std::function & validateFunc = nullptr) { return SetupAndTrackLayerOutputSlot(operation, outputIndex, @@ -1460,7 +1485,8 @@ bool SetupAndTrackLayerOutputSlot(const HalOperation& operation, outputIndex, model, data, - overrideOutputInfo); + overrideOutputInfo, + validateFunc); } templateGetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateGetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data); + if (!isSupported) + { + return false; + } + + return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data, nullptr, validateFunc); } templateGetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template