ArmNN
 24.02
PermuteDepthwiseConv2dWeights.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include "Optimization.hpp"
8 #include "NetworkUtils.hpp"
9 
10 #include <armnnUtils/Permute.hpp>
11 
12 #include <fmt/format.h>
13 
14 namespace armnn
15 {
16 namespace optimizations
17 {
18 
20 {
21 public:
22 
23  void Run(Graph& graph, Layer& layer) const
24  {
26  {
27  AddPermuteLayer(graph, PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&layer));
28  }
29  }
30 
31 protected:
34 
35 private:
36  /// ArmNN format for weights for depthwise is [1, H, W, C] independently of the input/output layout
37  ///
38  /// ACL format for weights for depthwise is:
39  /// - [1, H, W, C] for [N, H, W, C] input/output layout (matches with ArmNN)
40  /// - [1, C, H, W] for [N, C, H, W] input/output layout
41  ///
42  /// Therefore ArmNN weights have to be permuted when input/output layout is [N, C, H, W] to pass them to ACL.
43  static void AddPermuteLayer(Graph& graph, DepthwiseConvolution2dLayer* layer)
44  {
46  TensorInfo weightInfo = layer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo();
48  {
49  // No permutation required. Input and weights data layouts are the same.
50  return;
51  }
53  {
54  // Weights permutation required. Weights [N,H,W,C] and input [N,C,H,W] data layouts are different.
55  // [ 1, H, W, I*M] --> [ 1, I * M, H, W ]
56  PermutationVector permutationVector = { 0, 2, 3, 1 };
57  TensorInfo weightsPermuted = armnnUtils::Permuted(weightInfo, permutationVector);
58 
59  // Inserts NewLayer so layers don't need to be re-sorted.
60  PermuteLayer* permuteLayer =
61  graph.InsertNewLayer<PermuteLayer>(layer->GetInputSlot(1),
62  PermuteDescriptor(permutationVector),
63  "permute_layer");
64  permuteLayer->GetOutputSlot().SetTensorInfo(weightsPermuted);
65 
66  // Assign Permute BackendId to be the same as the Depthwise Conv2d BackendId.
67  // Needed as backends have already been assigned at this stage.
68  permuteLayer->SetBackendId(layer->GetBackendId());
69  }
70  else
71  {
72  throw InvalidArgumentException(fmt::format("Unknown data layout for tensor info conversion: {}",
74  }
75  }
76 };
77 
79 
80 } // namespace optimizations
81 } // namespace armnn
armnn::OutputSlot::GetTensorInfo
const TensorInfo & GetTensorInfo() const override
Definition: Layer.cpp:92
armnn::DataLayout::NHWC
@ NHWC
armnn::DepthwiseConvolution2dLayer
This layer represents a depthwise convolution 2d operation.
Definition: DepthwiseConvolution2dLayer.hpp:15
armnn::DepthwiseConvolution2dDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:710
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::optimizations::PermuteDepthwiseConv2dWeightsImpl::~PermuteDepthwiseConv2dWeightsImpl
~PermuteDepthwiseConv2dWeightsImpl()=default
armnn::GetDataLayoutName
constexpr const char * GetDataLayoutName(DataLayout dataLayout)
Definition: TypesUtils.hpp:253
armnn::optimizations::PermuteDepthwiseConv2dWeightsImpl::PermuteDepthwiseConv2dWeightsImpl
PermuteDepthwiseConv2dWeightsImpl()=default
NetworkUtils.hpp
armnnUtils::Permuted
armnn::TensorShape Permuted(const armnn::TensorShape &srcShape, const armnn::PermutationVector &mappings)
Definition: Permute.cpp:125
Optimization.hpp
armnn::Layer::GetInputSlot
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:337
armnn::LayerWithParameters::GetParameters
const Parameters & GetParameters() const override
If the layer has a descriptor return it.
Definition: LayerWithParameters.hpp:19
armnn::Layer
Definition: Layer.hpp:230
armnn::optimizations::PermuteDepthwiseConv2dWeightsImpl
Definition: PermuteDepthwiseConv2dWeights.hpp:19
armnn::PermutationVector
Definition: Types.hpp:314
Permute.hpp
armnn::OptimizeForType
Definition: Optimization.hpp:67
armnn::LayerType::DepthwiseConvolution2d
@ DepthwiseConvolution2d
armnn::Layer::GetType
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
Definition: Layer.hpp:286
armnn::Layer::GetBackendId
const BackendId & GetBackendId() const
Definition: Layer.hpp:290
armnn::InputSlot::GetConnectedOutputSlot
const OutputSlot * GetConnectedOutputSlot() const
Definition: Layer.hpp:56
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::optimizations::PermuteDepthwiseConv2dWeightsImpl::Run
void Run(Graph &graph, Layer &layer) const
Definition: PermuteDepthwiseConv2dWeights.hpp:23
armnn::Graph
Definition: Graph.hpp:30
armnn::Graph::InsertNewLayer
LayerT * InsertNewLayer(InputSlot &insertBefore, Args &&... args)
Inserts a new layer between the output slot currently connected to insertBefore and insertBefore itse...
Definition: Graph.hpp:471
armnn::DataLayout::NCHW
@ NCHW