ArmNN
 22.08
FuseConvertF32BF16IntoConstLayerTests.cpp
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 
6 #include <LayersFwd.hpp>
7 #include <Network.hpp>
8 #include <NetworkUtils.hpp>
9 #include <Optimizer.hpp>
10 #include <TestUtils.hpp>
11 
13 
14 #include <doctest/doctest.h>
15 
16 TEST_SUITE("Optimizer")
17 {
18 using namespace armnn;
19 using namespace armnn::optimizations;
20 
21 TEST_CASE("FuseConvertFp32Fp16intoConst")
22 {
23  Graph graph;
24  const unsigned int shape[] = {1, 2, 2, 3};
25 
26  const TensorInfo constTensorInfo(4, shape, DataType::Float32, 1.0, 0, true);
27  const TensorInfo outputConvertInfo(4, shape, DataType::BFloat16, 1.0, 0, true);
28 
29  ConstantLayer* constantLayer = graph.AddLayer<ConstantLayer>("constant");
30  std::vector<float> constantValues(constTensorInfo.GetNumElements(), 3.1416f);
31  ConstTensor constTensor(constTensorInfo, constantValues.data());
32  constantLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(constTensor);
33  constantLayer->GetOutputSlot().SetTensorInfo(constTensorInfo);
34 
35  ConvertFp32ToBf16Layer* convertLayer = graph.AddLayer<ConvertFp32ToBf16Layer>("convert");
36  convertLayer->GetOutputSlot().SetTensorInfo(outputConvertInfo);
37 
38  OutputLayer* output = graph.AddLayer<OutputLayer>(0, "output");
39 
40  // Connect up constant -> convert -> output
41  constantLayer->GetOutputSlot().Connect(convertLayer->GetInputSlot(0));
42  convertLayer->GetOutputSlot().Connect(output->GetInputSlot(0));
43 
44  auto checkConstantFloat32 = [](const armnn::Layer *const layer) -> bool {
45  return IsLayerOfType<ConstantLayer>(layer) &&
46  (layer->GetDataType() == DataType::Float32);
47  };
48  auto checkConstantBFloat16 = [](const armnn::Layer *const layer) -> bool {
49  return IsLayerOfType<ConstantLayer>(layer) &&
50  (layer->GetDataType() == DataType::BFloat16);
51  };
52 
53  CHECK(CheckSequence(graph.cbegin(), graph.cend(),
54  checkConstantFloat32,
55  &IsLayerOfType<ConvertFp32ToBf16Layer>,
56  &IsLayerOfType<OutputLayer>));
57 
59 
60  CHECK(CheckSequence(graph.cbegin(), graph.cend(),
61  checkConstantBFloat16,
62  &IsLayerOfType<OutputLayer>));
63 }
64 
65 TEST_CASE("RevertConstantWeightsToFP32")
66 {
67  Graph graph;
68  const unsigned int shape[] = {1, 2, 2, 3};
69 
70  const TensorInfo constTensorInfo(4, shape, DataType::Float32, 1.0, 0, true);
71  const TensorInfo outputConvertInfo(4, shape, DataType::BFloat16, 1.0, 0, true);
72 
73  TensorInfo inputInfo(4, shape, DataType::Float32);
74  auto* input = graph.AddLayer<InputLayer>(0, "input0");
75  input->GetOutputSlot().SetTensorInfo(inputInfo);
76 
77  auto* constantLayer = graph.AddLayer<ConstantLayer>("constant");
78  std::vector<float> constantValues(constTensorInfo.GetNumElements(), 3.1416f);
79  ConstTensor constTensor(constTensorInfo, constantValues.data());
80  constantLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(constTensor);
81  constantLayer->GetOutputSlot().SetTensorInfo(constTensorInfo);
82 
83  ConvertFp32ToBf16Layer* convertLayerInputs = graph.AddLayer<ConvertFp32ToBf16Layer>("convert");
84  convertLayerInputs->GetOutputSlot().SetTensorInfo(outputConvertInfo);
85  ConvertFp32ToBf16Layer* convertLayerWeights = graph.AddLayer<ConvertFp32ToBf16Layer>("convert2");
86  convertLayerWeights->GetOutputSlot().SetTensorInfo(outputConvertInfo);
87  ConvertFp32ToBf16Layer* convertLayerBiases = graph.AddLayer<ConvertFp32ToBf16Layer>("convert3");
88  convertLayerBiases->GetOutputSlot().SetTensorInfo(outputConvertInfo);
89 
90  auto* biases = graph.AddLayer<armnn::ConstantLayer>("Biases");
91  biases->m_LayerOutput = std::make_unique<armnn::ScopedTensorHandle>(constTensor);
92  biases->GetOutputSlot().SetTensorInfo(constTensorInfo);
93 
95  descriptor.m_BiasEnabled = true;
96  auto* conv = graph.AddLayer<armnn::Convolution2dLayer>(descriptor, "conv2d");
97  const armnn::TensorInfo infoFP32({ 2, 3, 8, 1 }, armnn::DataType::Float32);
98  conv->GetOutputSlot().SetTensorInfo(infoFP32);
99 
100  auto* output = graph.AddLayer<OutputLayer>(0, "output");
101 
102  // Connect up Input -> Convert ->
103  // Constant -> Convert -> Conv2d -> Output
104  // Constant -> Convert ->
105  input->GetOutputSlot().Connect(convertLayerInputs->GetInputSlot(0));
106  constantLayer->GetOutputSlot().Connect(convertLayerWeights->GetInputSlot(0));
107  biases->GetOutputSlot().Connect(convertLayerBiases->GetInputSlot(0));
108 
109  convertLayerInputs->GetOutputSlot().Connect(conv->GetInputSlot(0));
110  convertLayerWeights->GetOutputSlot().Connect(conv->GetInputSlot(1));
111  convertLayerBiases->GetOutputSlot().Connect(conv->GetInputSlot(2));
112 
113  conv->GetOutputSlot().Connect(output->GetInputSlot(0));
114 
115  auto checkConstantFloat32 = [](const armnn::Layer *const layer) -> bool {
116  return IsLayerOfType<ConstantLayer>(layer) &&
117  (layer->GetDataType() == DataType::Float32);
118  };
119  auto checkConstantBFloat16 = [](const armnn::Layer *const layer) -> bool {
120  return IsLayerOfType<ConstantLayer>(layer) &&
121  (layer->GetDataType() == DataType::BFloat16);
122  };
123 
124  CHECK(CheckSequence(graph.cbegin(), graph.cend(),
125  &IsLayerOfType<InputLayer>,
126  checkConstantFloat32,
127  checkConstantFloat32,
128  &IsLayerOfType<ConvertFp32ToBf16Layer>,
129  &IsLayerOfType<ConvertFp32ToBf16Layer>,
130  &IsLayerOfType<ConvertFp32ToBf16Layer>,
131  &IsLayerOfType<Convolution2dLayer>,
132  &IsLayerOfType<OutputLayer>));
133 
135 
136  bool revert = RevertConstantWeightsToFP32(conv);
137 
138  // Erase unconnected layer as occurs during Topological Sort.
139  graph.EraseLayer(convertLayerInputs);
140 
141  CHECK(revert);
142  CHECK(constantLayer->GetDataType() == DataType::Float32);
143 
144  CHECK(CheckSequence(graph.cbegin(), graph.cend(),
145  &IsLayerOfType<InputLayer>,
146  checkConstantBFloat16,
147  checkConstantFloat32,
148  &IsLayerOfType<Convolution2dLayer>,
149  &IsLayerOfType<OutputLayer>));
150 }
151 }
A layer that the constant data can be bound to.
bool m_BiasEnabled
Enable/disable bias.
Optimizer::Optimizations MakeOptimizations(Args &&... args)
Definition: Optimizer.hpp:43
bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
Definition: TestUtils.hpp:21
std::shared_ptr< ConstTensorHandle > m_LayerOutput
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:456
ConstIterator cbegin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops...
Definition: Graph.hpp:179
A Convolution2dDescriptor for the Convolution2dLayer.
int Connect(InputSlot &destination)
Definition: Layer.cpp:112
void EraseLayer(Iterator pos)
Deletes the layer at the specified position.
Definition: Graph.hpp:504
static void Pass(Graph &graph, const Optimizations &optimizations)
Definition: Optimizer.cpp:16
Copyright (c) 2021 ARM Limited and Contributors.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:324
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: OutputLayer.hpp:13
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:327
bool RevertConstantWeightsToFP32(Layer *layer)
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: InputLayer.hpp:13
void SetTensorInfo(const TensorInfo &tensorInfo) override
Definition: Layer.cpp:87
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:326
ConstIterator cend() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops...
Definition: Graph.hpp:181
This layer represents a convolution 2d operation.
This layer converts data type Float32 to BFloat16.
OptimizeForConnection< ConstantLayer, ConvertFp32ToBf16Layer, FuseConvertFp32ToBf16IntoConstLayers > FuseConversionLayersIntoConstLayers
unsigned int GetNumElements() const
Definition: Tensor.hpp:196