ArmNN
 25.11
Loading...
Searching...
No Matches
DepthToSpace.cpp
Go to the documentation of this file.
1//
2// Copyright © 2019, 2024 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "DepthToSpace.hpp"
7
10
11using namespace armnnUtils;
12
13namespace armnn
14{
15
16void DepthToSpace(const TensorInfo& inputInfo,
17 const DepthToSpaceDescriptor& descriptor,
18 const void* inputData,
19 void* outputData,
20 unsigned int dataTypeSize)
21{
22 const unsigned int blockSize = descriptor.m_BlockSize;
23
24 const TensorShape& inputShape = inputInfo.GetShape();
25 const unsigned int batches = inputShape[0];
26
27 armnnUtils::DataLayoutIndexed dataLayoutIndexed(descriptor.m_DataLayout);
28 const unsigned int inDepth = inputShape[dataLayoutIndexed.GetChannelsIndex()];
29 const unsigned int inHeight = inputShape[dataLayoutIndexed.GetHeightIndex()];
30 const unsigned int inWidth = inputShape[dataLayoutIndexed.GetWidthIndex()];
31
32 const unsigned int outDepth = inDepth / (blockSize * blockSize);
33
34 // The 4D input data can be interpreted as 6D (implicitly reshaped) as follows:
35 //
36 // [batch, block size, block size, inDepth, inHeight, inWidth] for NCHW and
37 // [batch, inHeight, inWidth, blockSize, blockSize, outDepth] for NHWC.
38 //
39 // DepthToSpace can then be implemented as a permutation in 6D resulting in
40 // the following shapes:
41 //
42 // [batch, outDepth, inHeight, blockSize, inWidth, blockSize] for NCHW and
43 // [batch, inHeight, blockSize, inWidth, blockSize, outDepth] for NHWC.
44 //
45 // NOTE:
46 // Since 6D tensors are not currently supported, in practice we need to handle each
47 // batch separately and execute 5D permutations
48
49 TensorShape permDestShape;
50 PermutationVector permVector{};
51 if (descriptor.m_DataLayout == DataLayout::NCHW)
52 {
53 permDestShape = TensorShape({ outDepth, inHeight, blockSize, inWidth, blockSize });
54 permVector = { 2, 4, 0, 1, 3 };
55 }
56 else
57 {
58 permDestShape = TensorShape({ inHeight, blockSize, inWidth, blockSize, outDepth });
59 permVector = { 0, 2, 1, 3, 4 };
60 }
61
62 const unsigned int numElementsPerBatch = inputShape.GetNumElements() / batches;
63
64 for (unsigned int batchIndex = 0u; batchIndex < batches; ++batchIndex)
65 {
66 const uintptr_t batchDataOffset = batchIndex * (numElementsPerBatch * dataTypeSize);
67
68 armnnUtils::Permute(permDestShape,
69 permVector,
70 static_cast<const void*>(reinterpret_cast<const uint8_t*>(inputData) + batchDataOffset),
71 static_cast<void*>(reinterpret_cast<uint8_t*>(outputData) + batchDataOffset),
72 dataTypeSize);
73 }
74}
75
76} // namespace armnn
const TensorShape & GetShape() const
Definition Tensor.hpp:193
unsigned int GetNumElements() const
Function that calculates the tensor elements by multiplying all dimension size which are Specified.
Definition Tensor.cpp:181
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout.
unsigned int GetHeightIndex() const
unsigned int GetChannelsIndex() const
Copyright (c) 2021 ARM Limited and Contributors.
SpaceToDepthDescriptor DepthToSpaceDescriptor
A DepthToSpaceDescriptor for the DepthToSpaceLayer.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
unsigned int m_BlockSize
Scalar specifying the input block size. It must be >= 1.