From 758eee8e72b8e0f81b98fce04a6a83ccbd1d7127 Mon Sep 17 00:00:00 2001 From: Sadik Armagan Date: Thu, 15 Nov 2018 15:34:49 +0000 Subject: IVGCVSW-2088 Add a converter method for STRIDED_SLICE to the V1.1 section of the ModelToINetworkConverter * Added Converter function for StridedSlice operator to 1.1:HalPolicy !armnn:121 Change-Id: Ida911c2ebeae9b7af708a5e4f492e97ac0d336cb --- 1.1/HalPolicy.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1.1/HalPolicy.hpp | 1 + 2 files changed, 93 insertions(+) (limited to '1.1') diff --git a/1.1/HalPolicy.cpp b/1.1/HalPolicy.cpp index 6e162860..86f11188 100644 --- a/1.1/HalPolicy.cpp +++ b/1.1/HalPolicy.cpp @@ -37,6 +37,8 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model, return ConvertSpaceToBatchNd(operation, model, data); case V1_1::OperationType::SQUEEZE: return ConvertSqueeze(operation, model, data); + case V1_1::OperationType::STRIDED_SLICE: + return ConvertStridedSlice(operation, model, data); case V1_1::OperationType::TRANSPOSE: return ConvertTranspose(operation, model, data); case V1_1::OperationType::BATCH_TO_SPACE_ND: @@ -443,6 +445,96 @@ bool HalPolicy::ConvertSqueeze(const Operation& operation, const Model& model, C return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); } +bool HalPolicy::ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data) +{ + LayerInputHandle input = ConvertToLayerInputHandle(operation, 0, model, data); + if (!input.IsValid()) + { + return Fail("%s: Operation has invalid inputs", __func__); + } + const armnn::TensorInfo& inputInfo = input.GetTensorInfo(); + + unsigned int rank = inputInfo.GetNumDimensions(); + if (rank > 4) + { + Fail("%s: Inputs with rank greater than 4 are not supported", __func__); + } + + const Operand* beginOperand = GetInputOperand(operation, 1, model); + const Operand* endOperand = GetInputOperand(operation, 2, model); + const Operand* stridesOperand = GetInputOperand(operation, 3, model); + + std::vector beginValues; + std::vector endValues; + std::vector stridesValues; + + // The length of the beginOperand, endOperand and stridesOperand must be of a rank(input) + auto ValidateInputOperands = [&] (const Operand& operand, std::vector& operandValues) + { + if (!GetTensorInt32Values(operand, operandValues, model, data)) + { + return false; + } + + if (operandValues.size() != rank) + { + return false; + } + + return true; + }; + + if (!ValidateInputOperands(*beginOperand, beginValues) + || !ValidateInputOperands(*endOperand, endValues) + || !ValidateInputOperands(*stridesOperand, stridesValues)) + { + return Fail("%s: Operation has invalid input operand", __func__); + } + + // Stride cannot have value '0' + if (std::any_of(stridesValues.cbegin(), stridesValues.cend(), [](int32_t i){ return i == 0; })) + { + return Fail("%s: Stride must be non-zero value.", __func__); + } + + armnn::StridedSliceDescriptor descriptor; + descriptor.m_Begin.assign(beginValues.cbegin(), beginValues.cend()); + descriptor.m_End.assign(endValues.cbegin(), endValues.cend()); + descriptor.m_Stride.assign(stridesValues.cbegin(), stridesValues.cend()); + descriptor.m_DataLayout = armnn::DataLayout::NHWC; + + // Get the "begin_mask", "end_mask", and "shrink_axis_mask" flags + if (!GetInputInt32(operation, 4, descriptor.m_BeginMask, model, data) + || !GetInputInt32(operation, 5, descriptor.m_EndMask, model, data) + || !GetInputInt32(operation, 6, descriptor.m_ShrinkAxisMask, model, data)) + { + return Fail("%s: Operation has invalid inputs", __func__); + } + + const Operand* output = GetOutputOperand(operation, 0, model); + if (!output) + { + return Fail("%s: Could not read output 0", __func__); + } + const armnn::TensorInfo& outputInfo = GetTensorInfoForOperand(*output); + + if (!IsLayerSupported(__func__, + armnn::IsStridedSliceSupported, + data.m_Compute, + inputInfo, + outputInfo, + descriptor)) + { + return false; + } + + armnn::IConnectableLayer* const layer = data.m_Network->AddStridedSliceLayer(descriptor); + assert(layer != nullptr); + input.Connect(layer->GetInputSlot(0)); + + return SetupAndTrackLayerOutputSlot(operation, 0, *layer, model, data); +} + bool HalPolicy::ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data) { LayerInputHandle input = ConvertToLayerInputHandle(operation, 0, model, data); diff --git a/1.1/HalPolicy.hpp b/1.1/HalPolicy.hpp index 16452fcb..bcaf5637 100644 --- a/1.1/HalPolicy.hpp +++ b/1.1/HalPolicy.hpp @@ -31,6 +31,7 @@ private: static bool ConvertPad(const Operation& operation, const Model& model, ConversionData& data); static bool ConvertSpaceToBatchNd(const Operation& operation, const Model& model, ConversionData& data); static bool ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data); + static bool ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data); static bool ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data); static bool ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data); }; -- cgit v1.2.1