aboutsummaryrefslogtreecommitdiff
path: root/src/armnnUtils
diff options
context:
space:
mode:
authorMike Kelly <mike.kelly@arm.com>2020-02-28 18:11:58 +0000
committermike.kelly <mike.kelly@arm.com>2020-03-02 16:44:09 +0000
commitc9ea45adefdde2890e9aa191a5b31563a3dd35ea (patch)
tree2ea65c972d24cc2d823ea39eb105d4062db54934 /src/armnnUtils
parent510f6183d289b176702a18f020449c68be6f1075 (diff)
downloadarmnn-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.cpp126
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