From 4bd9a745df49bdf11e03f932af6eca6b61ddb0a1 Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Wed, 12 Aug 2020 12:58:50 +0100 Subject: IVGCVSW-5182 Update Convert functions to use ShapeInferenceMethod. 1/2. * ConvertToActivation * ConvertAdd * ConvertArgMinMax * ConvertConv2d * ConvertDepthToSpace * ConvertDepthwiseConv2d * ConvertDiv * ConvertFloor * ConvertFullyConnected * ConvertL2Normalization * ConvertLocalResponseNormalization * ConvertMean * ConvertMul * ConvertPad * ConvertReshape * ConvertSub * ConvertStridedSlice * ConvertTranspose * ConvertBatchToSpaceNd * ConvertSpaceToBatchNd * ConvertComparison_1_2 * ConvertConv2d_1_2 * ConvertDepthwiseConv2d_1_2 * ConvertElementwiseUnary * ConvertExpandDims * ConvertGather * ConvertGroupedConv2d * ConvertInstanceNormalization * ConvertLogSoftmax * ConvertMaximum * ConvertMinimum * ConvertPadV2 * ConvertPrelu * ConvertQuantize * ConvertResize * ConvertSpaceToDepth * ConvertSoftmax * ConvertTransposeConv2d Signed-off-by: Finn Williams Signed-off-by: Teresa Charlin Signed-off-by: Kevin May Change-Id: Idacf16e5eab56d83fce293570bbc89381ae056dc --- ConversionUtils_1_2.hpp | 611 ++++++++++++++++++++++++++++++------------------ 1 file changed, 380 insertions(+), 231 deletions(-) (limited to 'ConversionUtils_1_2.hpp') diff --git a/ConversionUtils_1_2.hpp b/ConversionUtils_1_2.hpp index 824a8f4a..0f47ad31 100644 --- a/ConversionUtils_1_2.hpp +++ b/ConversionUtils_1_2.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2020 Arm Ltd. All rights reserved. +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -138,22 +138,30 @@ bool ConvertComparison_1_2(const HalOperation& operation, const TensorInfo& inputInfo1 = input1.GetTensorInfo(); const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); - if (IsDynamicTensor(outputInfo)) - { - return Fail("%s: Dynamic output tensors are not supported", __func__); - } - ComparisonDescriptor descriptor(comparisonOperation); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsComparisonSupported, - data.m_Backends, - isSupported, - inputInfo0, - inputInfo1, - outputInfo, - descriptor); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsComparisonSupported, + data.m_Backends, + isSupported, + inputInfo0, + inputInfo1, + outputInfo, + descriptor); + + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } if (!isSupported) { @@ -169,7 +177,10 @@ bool ConvertComparison_1_2(const HalOperation& operation, return false; } - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + input0.Connect(layer->GetInputSlot(0)); + input1.Connect(layer->GetInputSlot(1)); + + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template biases(bias.GetInfo()); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsConvolution2dSupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - desc, - weights.GetInfo(), - biases); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsConvolution2dSupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + desc, + weights.GetInfo(), + biases); + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } if (!isSupported) { @@ -329,7 +347,7 @@ bool ConvertConv2d_1_2(const HalOperation& operation, const HalModel& model, Con input.Connect(startLayer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data, nullptr, validateFunc); } template(operation, 1, model); @@ -476,15 +489,27 @@ bool ConvertDepthwiseConv2d_1_2(const HalOperation& operation, const HalModel& m Optional biases(bias.GetInfo()); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsDepthwiseConvolutionSupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - desc, - weights.GetInfo(), - biases); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsDepthwiseConvolutionSupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + desc, + weights.GetInfo(), + biases); + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } if (!isSupported) { @@ -556,21 +581,29 @@ bool ConvertElementwiseUnary(const HalOperation& operation, const TensorInfo& inputInfo = input.GetTensorInfo(); const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); - if (IsDynamicTensor(outputInfo)) - { - return Fail("%s: Dynamic output tensors are not supported", __func__); - } - ElementwiseUnaryDescriptor descriptor(unaryOperation); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsElementwiseUnarySupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - descriptor); + + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsElementwiseUnarySupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + descriptor); + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } if (!isSupported) { @@ -579,10 +612,9 @@ bool ConvertElementwiseUnary(const HalOperation& operation, IConnectableLayer* layer = data.m_Network->AddElementwiseUnaryLayer(descriptor); assert(layer != nullptr); - input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 1, HalOperandType::INT32, axis, model, data)) @@ -640,13 +668,25 @@ bool ConvertExpandDims(const HalOperation& operation, const HalModel& model, Con reshapeDescriptor.m_TargetShape = targetShape; bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsReshapeSupported, - data.m_Backends, - isSupported, - input.GetTensorInfo(), - outputInfo, - reshapeDescriptor); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsReshapeSupported, + data.m_Backends, + isSupported, + input.GetTensorInfo(), + outputInfo, + reshapeDescriptor); + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } if (!isSupported) { @@ -657,7 +697,7 @@ bool ConvertExpandDims(const HalOperation& operation, const HalModel& model, Con assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateGetInputSlot(0)); indices.Connect(layer->GetInputSlot(1)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(numGroups * channelMultiplier, &groupOutputInfo), - outputInfo, - concatDescriptor); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsConcatSupported, + data.m_Backends, + isSupported, + std::vector(numGroups * channelMultiplier, &groupOutputInfo), + outputInfo, + concatDescriptor); + }; + + if(!IsDynamicTensor(outputInfo)) + { + validateFunc(outputInfo, isSupported); + } + else + { + isSupported = AreDynamicTensorsSupported(); + } + if (!isSupported) { return false; @@ -1072,7 +1130,7 @@ bool ConvertGroupedConv2d(const HalOperation& operation, const HalModel& model, return Fail("%s: ProcessActivation failed", __func__); } - return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data, nullptr, validateFunc); } template(operation, 4, model, data); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsInstanceNormalizationSupported, - data.m_Backends, - isSupported, - input.GetTensorInfo(), - outputInfo, - desc); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsInstanceNormalizationSupported, + data.m_Backends, + isSupported, + input.GetTensorInfo(), + outputInfo, + desc); + }; + + if(IsDynamicTensor(outputInfo)) + { + isSupported = AreDynamicTensorsSupported(); + } + else + { + validateFunc(outputInfo, isSupported); + } + if (!isSupported) { return false; @@ -1162,7 +1229,7 @@ bool ConvertInstanceNormalization(const HalOperation& operation, const HalModel& IConnectableLayer* layer = data.m_Network->AddInstanceNormalizationLayer(desc); input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateGetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateAddPadLayer(descriptor); assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); - layer->GetOutputSlot(0).SetTensorInfo(outputInfo); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateGetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 3, model, data); @@ -1906,13 +2018,25 @@ bool ConvertResize(const HalOperation& operation, descriptor.m_HalfPixelCenters = GetOptionalBool(operation, 5, model, data); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsResizeSupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - descriptor); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsResizeSupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + descriptor); + }; + + if(IsDynamicTensor(outputInfo)) + { + isSupported = AreDynamicTensorsSupported(); + } + else + { + validateFunc(outputInfo, isSupported); + } if (!isSupported) { @@ -1920,12 +2044,10 @@ bool ConvertResize(const HalOperation& operation, } IConnectableLayer* layer = data.m_Network->AddResizeLayer(descriptor); - assert(layer != nullptr); - input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } template(operation, 2, model, data); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsSpaceToDepthSupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - desc); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsSpaceToDepthSupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + desc); + }; + + if(IsDynamicTensor(outputInfo)) + { + isSupported = AreDynamicTensorsSupported(); + } + else + { + validateFunc(outputInfo, isSupported); + } + if (!isSupported) { return false; @@ -1991,7 +2122,7 @@ bool ConvertSpaceToDepth(const HalOperation& operation, const HalModel& model, C assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templatetype; @@ -2056,13 +2183,26 @@ bool ConvertSoftmax(const HalOperation& operation, const HalModel& model, Conver } bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsSoftmaxSupported, - data.m_Backends, - isSupported, - input.GetTensorInfo(), - outputInfo, - desc); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsSoftmaxSupported, + data.m_Backends, + isSupported, + input.GetTensorInfo(), + outputInfo, + desc); + }; + + if(IsDynamicTensor(outputInfo)) + { + isSupported = AreDynamicTensorsSupported(); + } + else + { + validateFunc(outputInfo, isSupported); + } + if (!isSupported) { return false; @@ -2072,7 +2212,7 @@ bool ConvertSoftmax(const HalOperation& operation, const HalModel& model, Conver assert(layer != nullptr); input.Connect(layer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data, nullptr, validateFunc); } templateGetInputSlot(1)); cellStateIn.Connect(layer->GetInputSlot(2)); - return ( (IsDynamicTensor(scratchBufferInfo)? SetupAndTrackLayerOutputSlotAndOverrideTensorInfo( @@ -2521,10 +2662,6 @@ bool ConvertTransposeConv2d(const HalOperation& operation, const HalModel& model const TensorInfo& inputInfo = input.GetTensorInfo(); const TensorInfo& outputInfo = GetTensorInfoForOperand(*output); - if (IsDynamicTensor(outputInfo)) - { - return Fail("%s: Dynamic output tensors are not supported", __func__); - } // ArmNN does not currently support non-fixed weights or bias // Find the shape of the weights tensor. In AndroidNN this will be [ 1, H, W, I * M ] @@ -2658,15 +2795,27 @@ bool ConvertTransposeConv2d(const HalOperation& operation, const HalModel& model Optional biases(bias.GetInfo()); bool isSupported = false; - FORWARD_LAYER_SUPPORT_FUNC(__func__, - IsTransposeConvolution2dSupported, - data.m_Backends, - isSupported, - inputInfo, - outputInfo, - desc, - weights.GetInfo(), - biases); + auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC(__func__, + IsTransposeConvolution2dSupported, + data.m_Backends, + isSupported, + inputInfo, + outputInfo, + desc, + weights.GetInfo(), + biases); + }; + + if(IsDynamicTensor(outputInfo)) + { + isSupported = AreDynamicTensorsSupported(); + } + else + { + validateFunc(outputInfo, isSupported); + } if (!isSupported) { return false; @@ -2687,7 +2836,7 @@ bool ConvertTransposeConv2d(const HalOperation& operation, const HalModel& model input.Connect(startLayer->GetInputSlot(0)); - return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data); + return SetupAndTrackLayerOutputSlot(operation, 0, *endLayer, model, data, nullptr, validateFunc); } } // armnn_driver namespace \ No newline at end of file -- cgit v1.2.1