From b454c5c65efb238c130b042ace390b2bc7f0bf75 Mon Sep 17 00:00:00 2001 From: Finn Williams Date: Tue, 9 Feb 2021 15:56:23 +0000 Subject: IVGCVSW-4893 Refactor ILayerVisitor using unified interface strategy. Signed-off-by: Jan Eilers Signed-off-by: Finn Williams Signed-off-by: Francis Murtagh Change-Id: Id7bc8255a8e3f9e5aac65d510bec8a559bf37246 --- src/armnn/StaticRangeStrategy.cpp | 193 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/armnn/StaticRangeStrategy.cpp (limited to 'src/armnn/StaticRangeStrategy.cpp') diff --git a/src/armnn/StaticRangeStrategy.cpp b/src/armnn/StaticRangeStrategy.cpp new file mode 100644 index 0000000000..84b8d24068 --- /dev/null +++ b/src/armnn/StaticRangeStrategy.cpp @@ -0,0 +1,193 @@ +// +// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "StaticRangeStrategy.hpp" + +#include +#include +#include + +#include + +namespace armnn +{ + +StaticRangeStrategy::StaticRangeStrategy(RangeTracker& rangeTracker) + : m_RangeTracker(rangeTracker) +{} + +void StaticRangeStrategy::SetRange(const IConnectableLayer* layer, unsigned int outputIdx, float min, float max) +{ + m_RangeTracker.SetRange(layer, outputIdx, min, max); +} + +void StaticRangeStrategy::ForwardParentParameters(const IConnectableLayer* layer) +{ + const auto parentRange = m_RangeTracker.GetRange(layer->GetInputSlot(0).GetConnection()->GetOwningLayerGuid(), 0); + SetRange(layer, 0, parentRange.first, parentRange.second); +} + + +void StaticRangeStrategy::ExecuteStrategy(const armnn::IConnectableLayer *layer, + const BaseDescriptor &descriptor, + const std::vector &constants, + const char *name, + const armnn::LayerBindingId id) +{ +IgnoreUnused(id, name); + +switch (layer->GetType()) +{ + case armnn::LayerType::Activation : + { + const ActivationDescriptor& activationDescriptor = static_cast(descriptor); + + switch (activationDescriptor.m_Function) + { + // Range is 0, 15 for Abs, Linear, ReLu and Soft ReLu + case ActivationFunction::Abs: + case ActivationFunction::Linear: + case ActivationFunction::ReLu: + case ActivationFunction::SoftReLu: + SetRange(layer, 0, 0.f, 15.f); + break; + case ActivationFunction::BoundedReLu: + SetRange(layer, 0, 0.f, activationDescriptor.m_A); + break; + case ActivationFunction::TanH: + SetRange(layer, 0, -1.f, 1.f); + break; + case ActivationFunction::LeakyReLu: + SetRange(layer, 0, -5.f, 15.f); + break; + default: + SetRange(layer, 0, -15.f, 15.f); + break; + } + break; + } + case armnn::LayerType::Addition : + { + SetRange(layer, 0, -20.f, 20.f); + break; + } + case armnn::LayerType::ArgMinMax : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::BatchToSpaceNd : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::BatchNormalization : + { + SetRange(layer, 0, -15.0f, 15.0f); + break; + } + case armnn::LayerType::Concat : + { + float min = std::numeric_limits::max(); + float max = std::numeric_limits::lowest(); + for (unsigned int i = 0; i < layer->GetNumInputSlots(); ++i) + { + const IOutputSlot* outputSlot = layer->GetInputSlot(i).GetConnection(); + LayerGuid layerId = outputSlot->GetOwningLayerGuid(); + unsigned int slotIndex = outputSlot->CalculateIndexOnOwner(); + RangeTracker::MinMaxRange range = m_RangeTracker.GetRange(layerId, slotIndex); + min = std::min(min, range.first); + max = std::max(max, range.second); + } + SetRange(layer, 0, min, max); + break; + } + case armnn::LayerType::Constant : + { + + if (constants[0].GetDataType() != DataType::Float32) + { + throw InvalidArgumentException("Quantization is supported only for FP32 tensors"); + } + + // Work out the range based on the input constants + unsigned int inputNumElements = constants[0].GetNumElements(); + const float* inputData = reinterpret_cast(constants[0].GetMemoryArea()); + + float min = std::numeric_limits::max(); + float max = std::numeric_limits::lowest(); + + for (unsigned int i = 0; i < inputNumElements; i++) + { + const float inputValue = inputData[i]; + + min = std::min(min, inputValue); + max = std::max(max, inputValue); + } + SetRange(layer, 0, min, max); + break; + } + case armnn::LayerType::Convolution2d : + { + SetRange(layer, 0, -15.0f, 15.0f); + break; + } + case armnn::LayerType::DepthwiseConvolution2d : + { + SetRange(layer, 0, -15.0f, 15.0f); + break; + } + case armnn::LayerType::FullyConnected : + { + SetRange(layer, 0, -15.0f, 15.0f); + break; + } + case armnn::LayerType::Permute : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::Pooling2d : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::Reshape : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::Resize : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::Splitter : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::SpaceToBatchNd : + { + ForwardParentParameters(layer); + break; + } + case armnn::LayerType::Softmax : + { + SetRange(layer, 0, 0.f, 1.f); + break; + } + case armnn::LayerType::StridedSlice : + { + ForwardParentParameters(layer); + break; + } + default: + { + } +} +} + +} //namespace armnn -- cgit v1.2.1