ArmNN
 25.02
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NetworkUtils.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2022,2024 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "NetworkUtils.hpp"
7 
9 
10 #include <armnn/Exceptions.hpp>
12 
13 namespace armnn
14 {
15 
16 namespace
17 {
18 
19 void UpdateOutputSlotToFp32(OutputSlot& outputSlot)
20 {
21  const TensorInfo& origTensorInfo = outputSlot.GetTensorInfo();
22  TensorInfo newTensorInfo(origTensorInfo);
23  newTensorInfo.SetDataType(DataType::Float32);
24  outputSlot.SetTensorInfo(newTensorInfo);
25 }
26 
27 void ChangeOutputFp16ToFp32(Layer& layer)
28 {
29  for (auto&& outputSlot = layer.BeginOutputSlots(); outputSlot != layer.EndOutputSlots(); ++outputSlot)
30  {
31  if (outputSlot->GetTensorInfo().GetDataType() == DataType::Float16)
32  {
33  UpdateOutputSlotToFp32(*outputSlot);
34  }
35  }
36 }
37 
38 } // anonymous namespace
39 
40 std::vector<ConvertFp16ToFp32Layer*> InsertConvertFp16ToFp32LayersBefore(Graph& graph,
41  Layer& layer,
42  bool expectCorrectInputType)
43 {
44  std::vector<ConvertFp16ToFp32Layer*> convertLayers;
45  convertLayers.reserve(layer.GetNumInputSlots());
46 
47  // Insert a ConvertFp16ToFp32Layer before each input slot
48  for (auto&& inputSlot = layer.BeginInputSlots(); inputSlot != layer.EndInputSlots(); ++inputSlot)
49  {
50  bool allowInsert = true;
51  if (expectCorrectInputType)
52  {
53  // Only insert ConvertFp16ToFp32Layer before FP16 input slots
54  OutputSlot* connectedOutputSlot = inputSlot->GetConnectedOutputSlot();
55  allowInsert =
56  connectedOutputSlot && connectedOutputSlot->GetTensorInfo().GetDataType() == DataType::Float16;
57  }
58 
59  if (allowInsert)
60  {
61  const std::string name =
62  std::string("convert_fp16_to_fp32-" + std::to_string(inputSlot->GetSlotIndex()) + "-") +
63  layer.GetName();
64  ConvertFp16ToFp32Layer* convertLayer =
65  graph.InsertNewLayer<ConvertFp16ToFp32Layer>(*inputSlot, name.c_str());
66 
67  TensorInfo convertInfo = convertLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
68  convertInfo.SetDataType(DataType::Float32);
69 
70  convertLayer->GetOutputSlot().SetTensorInfo(convertInfo);
71 
72  convertLayers.emplace_back(convertLayer);
73  }
74  }
75 
76  return convertLayers;
77 }
78 
79 std::vector<ConvertFp32ToFp16Layer*> InsertConvertFp32ToFp16LayersAfter(Graph& graph, Layer& layer)
80 {
81  const unsigned int numOutputSlots = layer.GetNumOutputSlots();
82 
83  std::vector<ConvertFp32ToFp16Layer*> convertLayers;
84  convertLayers.reserve(numOutputSlots);
85 
86  // Update FP16 output slots to FP32 on current layer
87  ChangeOutputFp16ToFp32(layer);
88 
89  // Insert a ConvertFp32ToFp16Layer after each FP32 output slot
90  for (unsigned int slotIndex = 0u; slotIndex < numOutputSlots; ++slotIndex)
91  {
92  OutputSlot& outputSlot = layer.GetOutputSlot(slotIndex);
93  if(outputSlot.GetTensorInfo().GetDataType() == DataType::Float32)
94  {
95  const std::string name =
96  std::string("convert_fp32_to_fp16-" + std::to_string(slotIndex) + "-") + layer.GetName();
97  ConvertFp32ToFp16Layer* convertLayer =
98  graph.InsertNewLayer<ConvertFp32ToFp16Layer>(outputSlot, name.c_str());
99 
100  TensorInfo convertInfo = convertLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
101  convertInfo.SetDataType(DataType::Float16);
102 
103  convertLayer->GetOutputSlot().SetTensorInfo(convertInfo);
104 
105  convertLayers.emplace_back(convertLayer);
106  }
107  }
108 
109  return convertLayers;
110 }
111 
112 std::vector<DebugLayer*> InsertDebugLayerAfter(Graph& graph, Layer& layer, bool toFile)
113 {
114  std::vector<DebugLayer*> debugLayers;
115  debugLayers.reserve(layer.GetNumOutputSlots());
116 
117  // Connect a DebugLayer to each output slot of the layer
118  uint32_t outputSlotIdx = 0;
119  for (auto outputSlot = layer.BeginOutputSlots(); outputSlot != layer.EndOutputSlots(); ++outputSlot)
120  {
121  const std::string debugName = std::string("DebugLayerAfter") + layer.GetNameStr() + "_" +
122  std::to_string(outputSlotIdx);
123 
124  DebugLayer* debugLayer =
125  graph.InsertNewLayer<DebugLayer>(*outputSlot, debugName.c_str(), toFile);
126 
127  // Sets output tensor info for the debug layer.
128  if (debugLayer->GetInputSlot(0).GetConnectedOutputSlot() != &(*outputSlot))
129  {
130  throw armnn::Exception("unable to set output tensor info for the debug layer.");
131  }
132 
133  TensorInfo debugInfo = debugLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
134 
135  debugLayer->GetOutputSlot().SetTensorInfo(debugInfo);
136 
137  // NOTE: It is OK to do this because DebugLayer is only supported on CpuRef
138  debugLayer->SetBackendId(Compute::CpuRef);
139 
140  debugLayers.emplace_back(debugLayer);
141 
142  ++outputSlotIdx;
143  }
144 
145  return debugLayers;
146 }
147 
148 } // namespace armnn
This layer converts data type Float 16 to Float 32.
This layer converts data type Float 32 to Float 16.
This layer visualizes the data flowing through the network.
Definition: DebugLayer.hpp:14
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:47
LayerT * InsertNewLayer(InputSlot &insertBefore, Args &&... args)
Inserts a new layer between the output slot currently connected to insertBefore and insertBefore itse...
Definition: Graph.hpp:481
const OutputSlot * GetConnectedOutputSlot() const
Definition: Layer.hpp:56
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:339
unsigned int GetNumOutputSlots() const override
Returns the number of connectable output slots.
Definition: Layer.hpp:335
void SetBackendId(const BackendId &id) override
Set the backend of the IConnectableLayer.
Definition: Layer.hpp:291
std::vector< OutputSlot >::iterator EndOutputSlots()
Definition: Layer.hpp:267
const char * GetName() const override
Returns the name of the layer.
Definition: Layer.hpp:332
std::vector< OutputSlot >::iterator BeginOutputSlots()
Definition: Layer.hpp:266
std::vector< InputSlot >::iterator EndInputSlots()
Definition: Layer.hpp:263
const std::string & GetNameStr() const
Definition: Layer.hpp:240
unsigned int GetNumInputSlots() const override
Returns the number of connectable input slots.
Definition: Layer.hpp:334
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:337
std::vector< InputSlot >::iterator BeginInputSlots()
Definition: Layer.hpp:262
void SetTensorInfo(const TensorInfo &tensorInfo) override
Definition: Layer.cpp:95
const TensorInfo & GetTensorInfo() const override
Definition: Layer.cpp:100
void SetDataType(DataType type)
Definition: Tensor.hpp:201
DataType GetDataType() const
Definition: Tensor.hpp:200
Copyright (c) 2021 ARM Limited and Contributors.
std::vector< DebugLayer * > InsertDebugLayerAfter(Graph &graph, Layer &layer, bool toFile)
std::vector< ConvertFp32ToFp16Layer * > InsertConvertFp32ToFp16LayersAfter(Graph &graph, Layer &layer)
std::vector< ConvertFp16ToFp32Layer * > InsertConvertFp16ToFp32LayersBefore(Graph &graph, Layer &layer, bool expectCorrectInputType)
@ CpuRef
CPU Execution: Reference C++ kernels.