From b0717b5241a15e3e4d37a1b51b6e5fd9a92a664f Mon Sep 17 00:00:00 2001 From: arovir01 Date: Wed, 5 Sep 2018 17:03:25 +0100 Subject: IVGCVSW-1806: Refactor Android-NN-Driver ModelToINetworkConverter * Moved conversion logic into new V1_0 and V1_1 HalPolicy classes * Extracted common helper functions into ConversionUtils class Change-Id: I1ab50edc266dd528c0cb22a5cd1aa65e103674d9 --- ConversionUtils.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 ConversionUtils.cpp (limited to 'ConversionUtils.cpp') diff --git a/ConversionUtils.cpp b/ConversionUtils.cpp new file mode 100644 index 00000000..60d1a1f4 --- /dev/null +++ b/ConversionUtils.cpp @@ -0,0 +1,172 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ConversionUtils.hpp" + +/// +/// Helper classes +/// + +namespace armnn_driver +{ + +LayerInputHandle::LayerInputHandle() + : m_OutputSlot(nullptr) + , m_Valid(false) +{} + +LayerInputHandle::LayerInputHandle(bool valid, armnn::IOutputSlot* outputSlot, armnn::TensorInfo tensorInfo) + : m_OutputSlot(outputSlot) + , m_Valid(valid) + , m_TensorInfo(tensorInfo) +{} + +bool LayerInputHandle::IsValid() const +{ + return m_Valid; +} + +void LayerInputHandle::Connect(armnn::IInputSlot& inputSlot) +{ + BOOST_ASSERT(IsValid()); + if (m_OutputSlot) + { + m_OutputSlot->Connect(inputSlot); + } +} + +const armnn::TensorInfo& LayerInputHandle::GetTensorInfo() const +{ + return m_TensorInfo; +} + +ConstTensorPin::ConstTensorPin(bool optional) + : m_Optional(optional) +{} + +ConstTensorPin::ConstTensorPin(const armnn::TensorInfo& tensorInfo, + const void* valueStart, + uint32_t numBytes, + const armnn::PermutationVector& mappings) +{ + boost::ignore_unused(numBytes); + assert(tensorInfo.GetNumBytes() == numBytes); + + const bool needsSwizzling = (mappings.GetSize() > 0); + if (needsSwizzling) + { + m_SwizzledTensorData.resize(tensorInfo.GetNumBytes()); + SwizzleAndroidNn4dTensorToArmNn(tensorInfo, valueStart, m_SwizzledTensorData.data(), mappings); + + m_ConstTensor = armnn::ConstTensor(armnnUtils::Permuted(tensorInfo, mappings), m_SwizzledTensorData.data()); + } + else + { + m_ConstTensor = armnn::ConstTensor(tensorInfo, valueStart); + } +} + +bool ConstTensorPin::IsValid() const +{ + return m_ConstTensor.GetMemoryArea() != nullptr; +} + +bool ConstTensorPin::IsOptional() const +{ + return m_Optional; +} + +const armnn::ConstTensor& ConstTensorPin::GetConstTensor() const +{ + return m_ConstTensor; +} + +const armnn::ConstTensor* ConstTensorPin::GetConstTensorPtr() const +{ + if (IsValid() && m_ConstTensor.GetNumElements() > 0) + { + return &m_ConstTensor; + } + // tensor is either invalid, or has no elements (indicating an optional tensor that was not provided) + return nullptr; +} + +/// +/// Utility functions +/// + +armnn::IConnectableLayer* ProcessActivation(const armnn::TensorInfo& tensorInfo, + ActivationFn activation, + armnn::IConnectableLayer* prevLayer, + ConversionData& data) +{ + BOOST_ASSERT(prevLayer->GetNumOutputSlots() == 1); + + prevLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo); + + armnn::IConnectableLayer* activationLayer = prevLayer; + + if (activation != ActivationFn::kActivationNone) + { + armnn::ActivationDescriptor activationDesc; + switch (activation) + { + case ActivationFn::kActivationRelu: + { + activationDesc.m_Function = armnn::ActivationFunction::ReLu; + break; + } + case ActivationFn::kActivationRelu1: + { + activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; + activationDesc.m_A = 1.0f; + activationDesc.m_B = -1.0f; + break; + } + case ActivationFn::kActivationRelu6: + { + activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; + activationDesc.m_A = 6.0f; + break; + } + case ActivationFn::kActivationSigmoid: + { + activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; + break; + } + case ActivationFn::kActivationTanh: + { + activationDesc.m_Function = armnn::ActivationFunction::TanH; + activationDesc.m_A = 1.0f; + activationDesc.m_B = 1.0f; + break; + } + default: + { + Fail("%s: Invalid activation enum value %i", __func__, activation); + return nullptr; + } + } + + if (!IsLayerSupported(__func__, + armnn::IsActivationSupported, + data.m_Compute, + prevLayer->GetOutputSlot(0).GetTensorInfo(), + tensorInfo, + activationDesc)) + { + return nullptr; + } + + activationLayer = data.m_Network->AddActivationLayer(activationDesc); + + prevLayer->GetOutputSlot(0).Connect(activationLayer->GetInputSlot(0)); + activationLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo); + } + + return activationLayer; +} + +} // namespace armnn_driver \ No newline at end of file -- cgit v1.2.1