blob: 6ddb942deaa7865f4609e944f97ff731b44e5e9d [file] [log] [blame]
David Monahan8a570462023-11-22 13:24:25 +00001//
Tracy Narinee7d27852024-01-26 09:13:19 +00002// Copyright © 2022-2024 Arm Ltd and Contributors. All rights reserved.
David Monahan8a570462023-11-22 13:24:25 +00003// SPDX-License-Identifier: MIT
4//
5
6#include <armnn/INetwork.hpp>
7
8#include <GraphUtils.hpp>
9#include <TestUtils.hpp>
10
11#include <doctest/doctest.h>
12
13using namespace armnn;
14
15TEST_SUITE("GpuFsaOptimizedNetwork")
16{
17
Tracy Narinebc5a5d52024-02-06 15:22:41 +000018TEST_CASE("CastSupportedOptimizedNetwork")
19{
20 using namespace armnn;
21
22 const float qScale = 1.0f;
23 const int32_t qOffset = 0;
24
25 const TensorShape& inputShape = { 2, 2, 2 };
26 const TensorShape& outputShape = { 2, 2, 2 };
27
28 TensorInfo inputTensorInfo(inputShape, DataType::Float32, qScale, qOffset, true);
29 TensorInfo outputTensorInfo(outputShape, DataType::Float16, qScale, qOffset);
30
31 IRuntime::CreationOptions options;
32 IRuntimePtr runtime(IRuntime::Create(options));
33 INetworkPtr network(INetwork::Create());
34
35 IConnectableLayer* input = network->AddInputLayer(0, "input");
36 IConnectableLayer* castLayer = network->AddCastLayer("cast");
37 IConnectableLayer* output = network->AddOutputLayer(1, "output");
38
39 Connect(input, castLayer, inputTensorInfo, 0, 0);
40 Connect(castLayer, output, outputTensorInfo, 0, 0);
41
42 std::vector<BackendId> backends = { "GpuFsa" };
43
44 OptimizerOptionsOpaque optimizedOptions;
45 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
46 CHECK(optNet);
47
48 Graph& graph = GetGraphForTesting(optNet.get());
49
50 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
51 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
52 &IsLayerOfType<InputLayer>,
53 &IsLayerOfType<PreCompiledLayer>,
54 &IsLayerOfType<OutputLayer>));
55}
56
David Monahan8a570462023-11-22 13:24:25 +000057TEST_CASE("SingleConv2dSupportedOptimizedNetwork")
58{
59 IRuntime::CreationOptions options;
60 IRuntimePtr runtime(IRuntime::Create(options));
61 INetworkPtr network(INetwork::Create());
62
63 TensorInfo inputInfo({ 1, 5, 5, 1 }, DataType::Float32);
64 TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Float32);
65 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
66 TensorInfo biasesInfo({ 1 }, DataType::Float32, 0.0f, 0, true);
67
68 Convolution2dDescriptor desc;
69 desc.m_BiasEnabled = true;
70 desc.m_DataLayout = DataLayout::NHWC;
71
72 auto inputLayer = network->AddInputLayer(0, "input");
73 auto weightLayer = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
74 auto biasLayer = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
75 auto convLayer = network->AddConvolution2dLayer(desc, "conv2d");
76 auto outputLayer = network->AddOutputLayer(1, "output");
77
78 inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
79 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
80
81 weightLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
82 weightLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
83
84 biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
85 biasLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
86
87 convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
88 convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
89
90 std::vector<BackendId> backends = { "GpuFsa" };
91
92 OptimizerOptionsOpaque optimizedOptions;
93 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
94 CHECK(optNet);
95
96 Graph& graph = GetGraphForTesting(optNet.get());
97
98 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
99 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
100 &IsLayerOfType<InputLayer>,
101 &IsLayerOfType<ConstantLayer>,
102 &IsLayerOfType<ConstantLayer>,
103 &IsLayerOfType<PreCompiledLayer>,
104 &IsLayerOfType<OutputLayer>));
105}
106
107TEST_CASE("TwoConv2dSupportedOptimizedNetwork")
108{
109 IRuntime::CreationOptions options;
110 IRuntimePtr runtime(IRuntime::Create(options));
111 INetworkPtr network(INetwork::Create());
112
113 TensorInfo inputInfo({ 1, 5, 5, 1 }, DataType::Float32);
114 TensorInfo intermediateInfo({ 1, 3, 3, 1 }, DataType::Float32);
115 TensorInfo outputInfo({ 1, 1, 1, 1 }, DataType::Float32);
116 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
117 TensorInfo biasesInfo({ 1 }, DataType::Float32, 0.0f, 0, true);
118
119 Convolution2dDescriptor desc;
120 desc.m_BiasEnabled = true;
121 desc.m_DataLayout = DataLayout::NHWC;
122
123 auto inputLayer = network->AddInputLayer(0, "input");
124
125 auto weightLayer1 = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
126 auto biasLayer1 = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
127 auto convLayer1 = network->AddConvolution2dLayer(desc, "conv2d");
128
129 auto weightLayer2 = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
130 auto biasLayer2 = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
131 auto convLayer2 = network->AddConvolution2dLayer(desc, "conv2d");
132
133 auto outputLayer = network->AddOutputLayer(0, "output");
134
135 inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
136 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
137
138 weightLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1));
139 weightLayer1->GetOutputSlot(0).SetTensorInfo(weightsInfo);
140
141 biasLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(2));
142 biasLayer1->GetOutputSlot(0).SetTensorInfo(biasesInfo);
143
144 convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
145 convLayer1->GetOutputSlot(0).SetTensorInfo(intermediateInfo);
146
147 weightLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1));
148 weightLayer2->GetOutputSlot(0).SetTensorInfo(weightsInfo);
149
150 biasLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(2));
151 biasLayer2->GetOutputSlot(0).SetTensorInfo(biasesInfo);
152
153 convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
154 convLayer2->GetOutputSlot(0).SetTensorInfo(outputInfo);
155
156 std::vector<BackendId> backends = { "GpuFsa" };
157
158 OptimizerOptionsOpaque optimizedOptions;
159 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
160 CHECK(optNet);
161
162 Graph& graph = GetGraphForTesting(optNet.get());
163
164 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
165 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
166 &IsLayerOfType<InputLayer>,
167 &IsLayerOfType<ConstantLayer>,
168 &IsLayerOfType<ConstantLayer>,
169 &IsLayerOfType<ConstantLayer>,
170 &IsLayerOfType<ConstantLayer>,
171 &IsLayerOfType<PreCompiledLayer>,
172 &IsLayerOfType<PreCompiledLayer>,
173 &IsLayerOfType<OutputLayer>));
174}
175
Teresa Charlin20dda372024-02-08 16:23:25 +0000176TEST_CASE("ElementwiseBinarySupportedOptimizedNetwork")
Tracy Narinee7d27852024-01-26 09:13:19 +0000177{
178 using namespace armnn;
179
180 const float qScale = 1.0f;
181 const int32_t qOffset = 0;
182
183 const TensorShape& input1Shape = { 2, 2, 2 };
184 const TensorShape& input2Shape = { 2, 2, 2 };
185 const TensorShape& outputShape = { 2, 2, 2 };
186
187 TensorInfo input1TensorInfo(input1Shape, DataType::Float32, qScale, qOffset, true);
188 TensorInfo input2TensorInfo(input2Shape, DataType::Float32, qScale, qOffset, true);
189 TensorInfo outputTensorInfo(outputShape, DataType::Float32, qScale, qOffset);
190
191 IRuntime::CreationOptions options;
192 IRuntimePtr runtime(IRuntime::Create(options));
193 INetworkPtr network(INetwork::Create());
194
195 IConnectableLayer* input1 = network->AddInputLayer(0, "input0");
196 IConnectableLayer* input2 = network->AddInputLayer(1, "input1");
197
198 ElementwiseBinaryDescriptor desc;
Teresa Charlin20dda372024-02-08 16:23:25 +0000199 SUBCASE("Add")
200 {
201 desc.m_Operation = BinaryOperation::Add;
202 }
203 SUBCASE("Mul")
204 {
205 desc.m_Operation = BinaryOperation::Mul;
206 }
207 SUBCASE("Sub")
208 {
209 desc.m_Operation = BinaryOperation::Sub;
210 }
John Mcloughlin829e13e2024-01-31 11:00:27 +0000211
212 IConnectableLayer* elementwiseBinaryLayer = network->AddElementwiseBinaryLayer(desc, "elementwiseBinary");
213 IConnectableLayer* output = network->AddOutputLayer(2, "output");
214
215 Connect(input1, elementwiseBinaryLayer, input1TensorInfo, 0, 0);
216 Connect(input2, elementwiseBinaryLayer, input2TensorInfo, 0, 1);
217 Connect(elementwiseBinaryLayer, output, outputTensorInfo, 0, 0);
218
219 std::vector<BackendId> backends = { "GpuFsa" };
220
221 OptimizerOptionsOpaque optimizedOptions;
222 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
223 CHECK(optNet);
224
225 Graph& graph = GetGraphForTesting(optNet.get());
226
227 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
228 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
229 &IsLayerOfType<InputLayer>,
230 &IsLayerOfType<InputLayer>,
231 &IsLayerOfType<PreCompiledLayer>,
232 &IsLayerOfType<OutputLayer>));
233}
234
David Monahan8a570462023-11-22 13:24:25 +0000235}