diff options
author | David Beck <david.beck@arm.com> | 2018-09-24 10:46:38 +0100 |
---|---|---|
committer | Matthew Bentham <matthew.bentham@arm.com> | 2018-10-10 16:16:57 +0100 |
commit | 711fa31d5d43b904d28bcd407cd7e921529a37ca (patch) | |
tree | 729e74dc8681a8a8ac108bf349637ebbce00ba76 /src/backends/aclCommon/ArmComputeUtils.hpp | |
parent | 5662c206864df4121eea29c541c24c0f62113809 (diff) | |
download | armnn-711fa31d5d43b904d28bcd407cd7e921529a37ca.tar.gz |
IVGCVSW-1921: move common Acl code to a separate folder
Change-Id: I400be8e7c0cc5a31eb9d2a7396da145d50d51b6e
Diffstat (limited to 'src/backends/aclCommon/ArmComputeUtils.hpp')
-rw-r--r-- | src/backends/aclCommon/ArmComputeUtils.hpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/backends/aclCommon/ArmComputeUtils.hpp b/src/backends/aclCommon/ArmComputeUtils.hpp new file mode 100644 index 0000000000..db472964ea --- /dev/null +++ b/src/backends/aclCommon/ArmComputeUtils.hpp @@ -0,0 +1,125 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#if ARMCOMPUTENEON_ENABLED || ARMCOMPUTECL_ENABLED + +#include <armnn/Tensor.hpp> +#include <armnn/Descriptors.hpp> + +#include <arm_compute/core/Types.h> + +namespace armnn +{ + +inline arm_compute::NormalizationLayerInfo +CreateAclNormalizationLayerInfoForL2Normalization(const armnn::TensorInfo& tensorInfo) +{ + const unsigned int depth = tensorInfo.GetShape()[1]; + + // At the time of writing, {CL|Neon}L2Normalization performs the reduction only along dimension 0. This version of + // L2 Normalization always performs the reduction along the depth axis, though. Thus, we repurpose + // {CL|Neon}NormalizationLayers to act as depthwise L2 normalizations by carefully chosing the normalization + // parameters. + // + // Please refer to both the reference implementation of the normalization layer and the implementation of + // {CL|Neon}NormalizationLayer when checking the derivations for the parameter values below. + + // Make sure normalization covers the entire depth range. ACL requires the normalization size to be odd. + // CL: This does not result in extra kernel threads not doing any work: See usage of the RADIUS parameter in + // ACL's normalization_layer_cross_map() CL function. + const uint32_t normSize = depth * 2u + 1u; + + // See ACL's NormalizationLayerInfo::scale_coeff() definition. + // For the reference implementation, to make alpha_ become 1, we'd have to use alpha = normSize instead. + const float alpha = 1.0f; + + // Don't offset the reduction. + const float kappa = 0.0f; + + // pow(reduction, -0.5) = 1 / sqrt(reduction) + const float beta = 0.5f; + + return arm_compute::NormalizationLayerInfo(arm_compute::NormType::CROSS_MAP, normSize, alpha, beta, kappa, false); +} + +inline arm_compute::ActivationLayerInfo::ActivationFunction +ConvertActivationFunctionToAclActivationFunction(ActivationFunction armnnFunction) +{ + using AclActivationFunction = arm_compute::ActivationLayerInfo::ActivationFunction; + + switch (armnnFunction) + { + case ActivationFunction::Linear: return AclActivationFunction::LINEAR; + // Arm compute's 'logistic' function is non-parameterized, so it is exactly a sigmoid function. + case ActivationFunction::Sigmoid: return AclActivationFunction::LOGISTIC; + case ActivationFunction::ReLu: return AclActivationFunction::RELU; + case ActivationFunction::BoundedReLu: return AclActivationFunction::LU_BOUNDED_RELU; + case ActivationFunction::SoftReLu: return AclActivationFunction::SOFT_RELU; + case ActivationFunction::LeakyReLu: return AclActivationFunction::LEAKY_RELU; + case ActivationFunction::Abs: return AclActivationFunction::ABS; + case ActivationFunction::Sqrt: return AclActivationFunction::SQRT; + case ActivationFunction::Square: return AclActivationFunction::SQUARE; + case ActivationFunction::TanH: return AclActivationFunction::TANH; + default: throw InvalidArgumentException("Unsupported activation function"); + } +} + +inline arm_compute::ActivationLayerInfo +ConvertActivationDescriptorToAclActivationLayerInfo(const ActivationDescriptor& actDesc) +{ + return arm_compute::ActivationLayerInfo(ConvertActivationFunctionToAclActivationFunction(actDesc.m_Function), + actDesc.m_A, actDesc.m_B); +} + +inline arm_compute::PoolingType ConvertPoolingAlgorithmToAclPoolingType(PoolingAlgorithm poolingAlgorithm) +{ + using arm_compute::PoolingType; + + switch (poolingAlgorithm) + { + case PoolingAlgorithm::Max: return PoolingType::MAX; + case PoolingAlgorithm::Average: return PoolingType::AVG; + case PoolingAlgorithm::L2: return PoolingType::L2; + default: throw InvalidArgumentException("Unsupported pooling algorithm"); + } +} + +inline arm_compute::DimensionRoundingType ConvertOutputShapeRoundingToAclDimensionRoundingType(OutputShapeRounding + rounding) +{ + using arm_compute::DimensionRoundingType; + + switch (rounding) + { + case OutputShapeRounding::Ceiling: return DimensionRoundingType::CEIL; + case OutputShapeRounding::Floor: return DimensionRoundingType::FLOOR; + default: throw InvalidArgumentException("Unsupported Output Shape Rounding type"); + } +} + +inline arm_compute::NormType +ConvertNormalizationAlgorithmChannelToAclNormType(NormalizationAlgorithmChannel channelType) +{ + using arm_compute::NormType; + switch (channelType) + { + case NormalizationAlgorithmChannel::Across: return NormType::CROSS_MAP; + case NormalizationAlgorithmChannel::Within: return NormType::IN_MAP_2D; + default: throw InvalidArgumentException("Unsupported normalization algorithm channel type"); + } +} + +inline arm_compute::FullyConnectedLayerInfo +ConvertFullyConnectedDescriptorToAclFullyConnectedLayerInfo(const FullyConnectedDescriptor& fullyConnectedDesc) +{ + arm_compute::FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = fullyConnectedDesc.m_TransposeWeightMatrix; + return fc_info; +} + +} + +#endif // ARMCOMPUTENEON_ENABLED || ARMCOMPUTECL_ENABLED |