diff options
author | Mike Kelly <mike.kelly@arm.com> | 2020-02-28 18:11:58 +0000 |
---|---|---|
committer | mike.kelly <mike.kelly@arm.com> | 2020-03-02 16:44:09 +0000 |
commit | c9ea45adefdde2890e9aa191a5b31563a3dd35ea (patch) | |
tree | 2ea65c972d24cc2d823ea39eb105d4062db54934 /src/armnnUtils | |
parent | 510f6183d289b176702a18f020449c68be6f1075 (diff) | |
download | armnn-c9ea45adefdde2890e9aa191a5b31563a3dd35ea.tar.gz |
IVGCVSW-4375 Add support for Transpose
* Added TransposeLayer
* Added CL, Neon and Ref Workloads
* Added Transpose utilities
* Added Serializer and Deserializer support
* Added Quantizer support
Signed-off-by: Mike Kelly <mike.kelly@arm.com>
Change-Id: I04c755ba7cb5b1edf72b3c9f3c0314878032e3c7
Diffstat (limited to 'src/armnnUtils')
-rw-r--r-- | src/armnnUtils/Transpose.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/armnnUtils/Transpose.cpp b/src/armnnUtils/Transpose.cpp new file mode 100644 index 0000000000..3f3837c725 --- /dev/null +++ b/src/armnnUtils/Transpose.cpp @@ -0,0 +1,126 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include <armnn/Tensor.hpp> + +#include <armnnUtils/Transpose.hpp> + +#include "Half.hpp" + +#include <cassert> +#include <cstring> + +namespace +{ + +class TransposeLoop +{ +public: + using size_type = unsigned int; + + TransposeLoop(const armnn::TensorShape& srcShape, const armnn::PermutationVector& mappings) + : m_SrcShape(srcShape) + { + assert(srcShape.GetNumDimensions() == mappings.GetSize()); + + const size_type numDims = srcShape.GetNumDimensions(); + + size_type srcStride = 1U; + size_type dstStride = 1U; + + for (size_type i = numDims - 1U, k = 0U; k < numDims; ++k, --i) + { + m_SrcStrides[i] = srcStride; + m_DstStrides[mappings[i]] = dstStride; + + srcStride *= srcShape[i]; + dstStride *= srcShape[mappings[i]]; + } + } + + void Unroll(const void* srcData, void* dstData, size_t dataTypeSize) + { + assert(srcData); + assert(dstData); + assert(dataTypeSize > 0); + + const unsigned char* srcDataPtr = reinterpret_cast<const unsigned char*>(srcData); + unsigned char* dstDataPtr = reinterpret_cast<unsigned char*>(dstData); + + const unsigned char* const srcEndPtr = srcDataPtr + m_SrcShape.GetNumElements() * dataTypeSize; + unsigned char* const dstEndPtr = dstDataPtr + m_SrcShape.GetNumElements() * dataTypeSize; + + Unroll(0, srcDataPtr, dstDataPtr, srcEndPtr, dstEndPtr, dataTypeSize); + } + +private: + void Unroll(size_type dimension, + const unsigned char* srcData, unsigned char* dstData, + const unsigned char* srcEnd, unsigned char* dstEnd, + size_t dataTypeSize) + { + assert(srcData); + assert(dstData); + assert(srcEnd); + assert(dstEnd); + assert(srcData < srcEnd); + assert(dstData < dstEnd); + assert(dataTypeSize > 0); + + if (dimension >= m_SrcShape.GetNumDimensions()) + { + ::memcpy(dstData, srcData, dataTypeSize); + } + else + { + for (size_type i = 0; i < m_SrcShape[dimension]; i++) + { + Unroll(dimension + 1, srcData, dstData, srcEnd, dstEnd, dataTypeSize); + + srcData += m_SrcStrides[dimension] * dataTypeSize; + dstData += m_DstStrides[dimension] * dataTypeSize; + } + } + } + + armnn::TensorShape m_SrcShape; + std::array<size_type, armnn::MaxNumOfTensorDimensions> m_SrcStrides; + std::array<size_type, armnn::MaxNumOfTensorDimensions> m_DstStrides; +}; + +} // namespace + +namespace armnnUtils +{ + +armnn::TensorShape TransposeTensorShape(const armnn::TensorShape& srcShape, const armnn::PermutationVector& mappings) +{ + assert(srcShape.GetNumDimensions() == mappings.GetSize()); + + const unsigned int numDims = mappings.GetSize(); + unsigned int outDims[armnn::MaxNumOfTensorDimensions]; + + for (unsigned int i = 0U; i < numDims; ++i) + { + outDims[i] = srcShape[mappings[i]]; + } + armnn::TensorShape permutedShape(numDims, outDims); + return permutedShape; +} + +armnn::TensorInfo TransposeTensorShape(const armnn::TensorInfo& info, const armnn::PermutationVector& mappings) +{ + armnn::TensorInfo outInfo(info); + outInfo.SetShape(TransposeTensorShape(info.GetShape(), mappings)); + return outInfo; +} + +void Transpose(const armnn::TensorShape& srcShape, const armnn::PermutationVector& mappings, + const void* src, void* dst, size_t dataTypeSize) +{ + TransposeLoop(srcShape, mappings).Unroll(src, dst, dataTypeSize); +} + +} // namespace armnnUtils |