ArmNN
 20.05
TransposeConvolution2d.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 
9 
10 namespace armnn
11 {
12 
13 using namespace armnnUtils;
14 
16  const TensorShape& inputShape,
17  Decoder<float>& inputDecoder,
18  const TensorShape& outputShape,
19  Encoder<float>& outputEncoder,
20  const TensorShape& weightsShape,
21  Decoder<float>& weightsDecoder,
22  Decoder<float>* biasesDecoder)
23 {
24  if (descriptor.m_BiasEnabled && !biasesDecoder)
25  {
26  throw InvalidArgumentException("Biases enabled but no bias data provided");
27  }
28  const DataLayoutIndexed dataLayoutIndexed(descriptor.m_DataLayout);
29  const unsigned int channelsIndex = dataLayoutIndexed.GetChannelsIndex();
30  const unsigned int heightIndex = dataLayoutIndexed.GetHeightIndex();
31  const unsigned int widthIndex = dataLayoutIndexed.GetWidthIndex();
32 
33  unsigned int numBatches = inputShape[0];
34 
35  unsigned int inputWidth = inputShape[widthIndex];
36  unsigned int inputHeight = inputShape[heightIndex];
37  unsigned int inputDepth = inputShape[channelsIndex];
38 
39  unsigned int weightsHeight = weightsShape[heightIndex];
40  unsigned int weightsWidth = weightsShape[widthIndex];
41 
42  unsigned int outputHeight = outputShape[heightIndex];
43  unsigned int outputWidth = outputShape[widthIndex];
44  unsigned int outputDepth = outputShape[channelsIndex];
45 
46  unsigned int paddingLeft = descriptor.m_PadLeft;
47  unsigned int paddingTop = descriptor.m_PadTop;
48 
49  unsigned int strideX = descriptor.m_StrideX;
50  unsigned int strideY = descriptor.m_StrideY;
51 
52  std::vector<float> outputBuffer(outputShape.GetNumElements(), 0);
53 
54  for (unsigned int batch = 0u; batch < numBatches; ++batch)
55  {
56  for (unsigned int yInput = 0u; yInput < inputHeight; ++yInput)
57  {
58  for (unsigned int xInput = 0u; xInput < inputWidth; ++xInput)
59  {
60  unsigned int xOutputOrigin = xInput * strideX - paddingLeft;
61  unsigned int yOutputOrigin = yInput * strideY - paddingTop;
62 
63  for (unsigned int dOutput = 0u; dOutput < outputDepth; ++dOutput)
64  {
65  for (unsigned int yWeights = 0u; yWeights < weightsHeight; ++yWeights)
66  {
67  for (unsigned int xWeights = 0u; xWeights < weightsWidth; ++xWeights)
68  {
69  unsigned int yOutput = yOutputOrigin + yWeights;
70  unsigned int xOutput = xOutputOrigin + xWeights;
71 
72  if (yOutput < outputHeight && xOutput< outputWidth)
73  {
74  for (unsigned int dInput = 0u; dInput < inputDepth; dInput++)
75  {
76  const unsigned int inputIndex =
77  dataLayoutIndexed.GetIndex(inputShape, batch, dInput, yInput, xInput);
78  inputDecoder[inputIndex];
79 
80  const unsigned int weightsIndex =
81  dataLayoutIndexed.GetIndex(weightsShape, dOutput, dInput, yWeights, xWeights);
82  weightsDecoder.SetIndex(weightsIndex, dOutput);
83 
84  const unsigned int outputIndex =
85  dataLayoutIndexed.GetIndex(outputShape, batch, dOutput, yOutput, xOutput);
86  outputEncoder[outputIndex];
87 
88  float output = outputBuffer[outputIndex];
89  output += inputDecoder.Get() * weightsDecoder.Get();
90  outputBuffer[outputIndex] = output;
91  }
92  }
93  }
94  }
95  }
96  }
97  }
98  }
99 
100  // Apply bias (if enabled)
101  if (descriptor.m_BiasEnabled)
102  {
103  outputEncoder[0];
104  Decoder<float>& rBiasesDecoder = *biasesDecoder;
105 
106  for (unsigned int batch = 0u; batch < numBatches; ++batch)
107  {
108  for (unsigned int dOutput = 0u; dOutput < outputDepth; ++dOutput)
109  {
110  rBiasesDecoder.SetIndex(dOutput, dOutput);
111  for (unsigned int yOutput = 0u; yOutput < outputHeight; ++yOutput)
112  {
113  for (unsigned int xOutput = 0u; xOutput < outputWidth; ++xOutput)
114  {
115  const unsigned int outputIndex =
116  dataLayoutIndexed.GetIndex(outputShape, batch, dOutput, yOutput, xOutput);
117  outputBuffer[outputIndex] += rBiasesDecoder.Get();
118  }
119  }
120  }
121  }
122  }
123  outputEncoder[0];
124  for (float output : outputBuffer)
125  {
126  outputEncoder.Set(output);
127  ++outputEncoder;
128  }
129 }
130 
131 } // namespace armnn
unsigned int GetNumElements() const
Definition: Tensor.cpp:107
unsigned int GetWidthIndex() const
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
bool m_BiasEnabled
Enable/disable bias.
void TransposeConvolution2dImpl(const TransposeConvolution2dDescriptor &descriptor, const TensorShape &inputShape, Decoder< float > &inputDecoder, const TensorShape &outputShape, Encoder< float > &outputEncoder, const TensorShape &weightsShape, Decoder< float > &weightsDecoder, Decoder< float > *biasesDecoder)
virtual void Set(IType right)=0
Copyright (c) 2020 ARM Limited.
unsigned int GetHeightIndex() const
virtual IType Get() const =0
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
unsigned int GetIndex(const armnn::TensorShape &shape, unsigned int batchIndex, unsigned int channelIndex, unsigned int heightIndex, unsigned int widthIndex) const
uint32_t m_PadTop
Padding top value in the height dimension.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
virtual BaseIterator & SetIndex(unsigned int index, unsigned int axisIndex=0)=0
uint32_t m_PadLeft
Padding left value in the width dimension.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
unsigned int GetChannelsIndex() const