blob: ac341c2476a5a3d955dfa3f952b46afdbe8382b1 [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
Teresa Charlinddbda6a2024-02-07 22:58:29 +000018TEST_CASE("ActivationSupportedOptimizedNetwork")
19{
20 const float qScale = 1.0f;
21 const int32_t qOffset = 0;
22
23 const TensorShape& inputShape = { 2, 2, 2 };
24 const TensorShape& outputShape = { 2, 2, 2 };
25
26 TensorInfo inputTensorInfo(inputShape, DataType::Float32, qScale, qOffset, true);
27 TensorInfo outputTensorInfo(outputShape, DataType::Float32, qScale, qOffset);
28
29 IRuntime::CreationOptions options;
30 IRuntimePtr runtime(IRuntime::Create(options));
31 INetworkPtr network(INetwork::Create());
32
33 ActivationDescriptor desc;
34 SUBCASE("TanH")
35 {
36 desc.m_Function = ActivationFunction::TanH;
37 desc.m_A = 1.f;
38 desc.m_B = 1.f;
39 }
40 SUBCASE("Sigmoid")
41 {
42 desc.m_Function = ActivationFunction::Sigmoid;
43 }
44
45 IConnectableLayer* input = network->AddInputLayer(0, "input");
46 IConnectableLayer* activationLayer = network->AddActivationLayer(desc, "activation");
47 IConnectableLayer* output = network->AddOutputLayer(1, "output");
48
49 Connect(input, activationLayer, inputTensorInfo, 0, 0);
50 Connect(activationLayer, output, outputTensorInfo, 0, 0);
51
52 std::vector<BackendId> backends = { "GpuFsa" };
53
54 OptimizerOptionsOpaque optimizedOptions;
55 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
56 CHECK(optNet);
57
58 Graph& graph = GetGraphForTesting(optNet.get());
59
60 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
61 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
62 &IsLayerOfType<InputLayer>,
63 &IsLayerOfType<PreCompiledLayer>,
64 &IsLayerOfType<OutputLayer>));
65}
Teresa Charlin5bda9732024-02-08 18:46:38 +000066TEST_CASE("BatchMatMulSupportedOptimizedNetwork")
67{
Teresa Charlin5bda9732024-02-08 18:46:38 +000068 const float qScale = 1.0f;
69 const int32_t qOffset = 0;
70
71 const TensorShape& input1Shape = { 2, 2 };
72 const TensorShape& input2Shape = { 2, 2 };
73 const TensorShape& outputShape = { 2, 2 };
74
75 TensorInfo input1TensorInfo(input1Shape, DataType::Float32, qScale, qOffset, true);
76 TensorInfo input2TensorInfo(input2Shape, DataType::Float32, qScale, qOffset, true);
77 TensorInfo outputTensorInfo(outputShape, DataType::Float32, qScale, qOffset);
78
79 IRuntime::CreationOptions options;
80 IRuntimePtr runtime(IRuntime::Create(options));
81 INetworkPtr network(INetwork::Create());
82
83 BatchMatMulDescriptor desc{};
84
85 IConnectableLayer* input1 = network->AddInputLayer(0, "input0");
86 IConnectableLayer* input2 = network->AddInputLayer(1, "input1");
87 IConnectableLayer* batchMatMulLayer = network->AddBatchMatMulLayer(desc, "batchMatMul");
88 IConnectableLayer* output = network->AddOutputLayer(2, "output");
89
90 Connect(input1, batchMatMulLayer, input1TensorInfo, 0, 0);
91 Connect(input2, batchMatMulLayer, input2TensorInfo, 0, 1);
92 Connect(batchMatMulLayer, output, outputTensorInfo, 0, 0);
93
94 std::vector<BackendId> backends = { "GpuFsa" };
95
96 OptimizerOptionsOpaque optimizedOptions;
97 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
98 CHECK(optNet);
99
100 Graph& graph = GetGraphForTesting(optNet.get());
101
102 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
103 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
104 &IsLayerOfType<InputLayer>,
105 &IsLayerOfType<InputLayer>,
106 &IsLayerOfType<PreCompiledLayer>,
107 &IsLayerOfType<OutputLayer>));
108}
109
Tracy Narinebc5a5d52024-02-06 15:22:41 +0000110TEST_CASE("CastSupportedOptimizedNetwork")
111{
Tracy Narinebc5a5d52024-02-06 15:22:41 +0000112 const float qScale = 1.0f;
113 const int32_t qOffset = 0;
114
115 const TensorShape& inputShape = { 2, 2, 2 };
116 const TensorShape& outputShape = { 2, 2, 2 };
117
118 TensorInfo inputTensorInfo(inputShape, DataType::Float32, qScale, qOffset, true);
119 TensorInfo outputTensorInfo(outputShape, DataType::Float16, qScale, qOffset);
120
121 IRuntime::CreationOptions options;
122 IRuntimePtr runtime(IRuntime::Create(options));
123 INetworkPtr network(INetwork::Create());
124
125 IConnectableLayer* input = network->AddInputLayer(0, "input");
126 IConnectableLayer* castLayer = network->AddCastLayer("cast");
127 IConnectableLayer* output = network->AddOutputLayer(1, "output");
128
129 Connect(input, castLayer, inputTensorInfo, 0, 0);
130 Connect(castLayer, output, outputTensorInfo, 0, 0);
131
132 std::vector<BackendId> backends = { "GpuFsa" };
133
134 OptimizerOptionsOpaque optimizedOptions;
135 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
136 CHECK(optNet);
137
138 Graph& graph = GetGraphForTesting(optNet.get());
139
140 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
141 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
142 &IsLayerOfType<InputLayer>,
143 &IsLayerOfType<PreCompiledLayer>,
144 &IsLayerOfType<OutputLayer>));
145}
146
David Monahan8a570462023-11-22 13:24:25 +0000147TEST_CASE("SingleConv2dSupportedOptimizedNetwork")
148{
149 IRuntime::CreationOptions options;
150 IRuntimePtr runtime(IRuntime::Create(options));
151 INetworkPtr network(INetwork::Create());
152
153 TensorInfo inputInfo({ 1, 5, 5, 1 }, DataType::Float32);
154 TensorInfo outputInfo({ 1, 3, 3, 1 }, DataType::Float32);
155 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
156 TensorInfo biasesInfo({ 1 }, DataType::Float32, 0.0f, 0, true);
157
158 Convolution2dDescriptor desc;
159 desc.m_BiasEnabled = true;
160 desc.m_DataLayout = DataLayout::NHWC;
161
162 auto inputLayer = network->AddInputLayer(0, "input");
163 auto weightLayer = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
164 auto biasLayer = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
165 auto convLayer = network->AddConvolution2dLayer(desc, "conv2d");
166 auto outputLayer = network->AddOutputLayer(1, "output");
167
168 inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
169 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
170
171 weightLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
172 weightLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
173
174 biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
175 biasLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
176
177 convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
178 convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
179
180 std::vector<BackendId> backends = { "GpuFsa" };
181
182 OptimizerOptionsOpaque optimizedOptions;
183 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
184 CHECK(optNet);
185
186 Graph& graph = GetGraphForTesting(optNet.get());
187
188 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
189 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
190 &IsLayerOfType<InputLayer>,
191 &IsLayerOfType<ConstantLayer>,
192 &IsLayerOfType<ConstantLayer>,
193 &IsLayerOfType<PreCompiledLayer>,
194 &IsLayerOfType<OutputLayer>));
195}
196
197TEST_CASE("TwoConv2dSupportedOptimizedNetwork")
198{
199 IRuntime::CreationOptions options;
200 IRuntimePtr runtime(IRuntime::Create(options));
201 INetworkPtr network(INetwork::Create());
202
203 TensorInfo inputInfo({ 1, 5, 5, 1 }, DataType::Float32);
204 TensorInfo intermediateInfo({ 1, 3, 3, 1 }, DataType::Float32);
205 TensorInfo outputInfo({ 1, 1, 1, 1 }, DataType::Float32);
206 TensorInfo weightsInfo({ 1, 3, 3, 1 }, DataType::Float32, 0.0f, 0, true);
207 TensorInfo biasesInfo({ 1 }, DataType::Float32, 0.0f, 0, true);
208
209 Convolution2dDescriptor desc;
210 desc.m_BiasEnabled = true;
211 desc.m_DataLayout = DataLayout::NHWC;
212
213 auto inputLayer = network->AddInputLayer(0, "input");
214
215 auto weightLayer1 = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
216 auto biasLayer1 = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
217 auto convLayer1 = network->AddConvolution2dLayer(desc, "conv2d");
218
219 auto weightLayer2 = network->AddConstantLayer(ConstTensor(weightsInfo, nullptr), "weights");
220 auto biasLayer2 = network->AddConstantLayer(ConstTensor(biasesInfo, nullptr), "bias");
221 auto convLayer2 = network->AddConvolution2dLayer(desc, "conv2d");
222
223 auto outputLayer = network->AddOutputLayer(0, "output");
224
225 inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
226 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
227
228 weightLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1));
229 weightLayer1->GetOutputSlot(0).SetTensorInfo(weightsInfo);
230
231 biasLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(2));
232 biasLayer1->GetOutputSlot(0).SetTensorInfo(biasesInfo);
233
234 convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
235 convLayer1->GetOutputSlot(0).SetTensorInfo(intermediateInfo);
236
237 weightLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1));
238 weightLayer2->GetOutputSlot(0).SetTensorInfo(weightsInfo);
239
240 biasLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(2));
241 biasLayer2->GetOutputSlot(0).SetTensorInfo(biasesInfo);
242
243 convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
244 convLayer2->GetOutputSlot(0).SetTensorInfo(outputInfo);
245
246 std::vector<BackendId> backends = { "GpuFsa" };
247
248 OptimizerOptionsOpaque optimizedOptions;
249 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
250 CHECK(optNet);
251
252 Graph& graph = GetGraphForTesting(optNet.get());
253
254 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
255 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
256 &IsLayerOfType<InputLayer>,
257 &IsLayerOfType<ConstantLayer>,
258 &IsLayerOfType<ConstantLayer>,
259 &IsLayerOfType<ConstantLayer>,
260 &IsLayerOfType<ConstantLayer>,
261 &IsLayerOfType<PreCompiledLayer>,
262 &IsLayerOfType<PreCompiledLayer>,
263 &IsLayerOfType<OutputLayer>));
264}
265
Teresa Charlin20dda372024-02-08 16:23:25 +0000266TEST_CASE("ElementwiseBinarySupportedOptimizedNetwork")
Tracy Narinee7d27852024-01-26 09:13:19 +0000267{
Tracy Narinee7d27852024-01-26 09:13:19 +0000268 const float qScale = 1.0f;
269 const int32_t qOffset = 0;
270
271 const TensorShape& input1Shape = { 2, 2, 2 };
272 const TensorShape& input2Shape = { 2, 2, 2 };
273 const TensorShape& outputShape = { 2, 2, 2 };
274
275 TensorInfo input1TensorInfo(input1Shape, DataType::Float32, qScale, qOffset, true);
276 TensorInfo input2TensorInfo(input2Shape, DataType::Float32, qScale, qOffset, true);
277 TensorInfo outputTensorInfo(outputShape, DataType::Float32, qScale, qOffset);
278
279 IRuntime::CreationOptions options;
280 IRuntimePtr runtime(IRuntime::Create(options));
281 INetworkPtr network(INetwork::Create());
282
283 IConnectableLayer* input1 = network->AddInputLayer(0, "input0");
284 IConnectableLayer* input2 = network->AddInputLayer(1, "input1");
285
286 ElementwiseBinaryDescriptor desc;
Teresa Charlin20dda372024-02-08 16:23:25 +0000287 SUBCASE("Add")
288 {
289 desc.m_Operation = BinaryOperation::Add;
290 }
291 SUBCASE("Mul")
292 {
293 desc.m_Operation = BinaryOperation::Mul;
294 }
295 SUBCASE("Sub")
296 {
297 desc.m_Operation = BinaryOperation::Sub;
298 }
John Mcloughlin829e13e2024-01-31 11:00:27 +0000299
300 IConnectableLayer* elementwiseBinaryLayer = network->AddElementwiseBinaryLayer(desc, "elementwiseBinary");
301 IConnectableLayer* output = network->AddOutputLayer(2, "output");
302
303 Connect(input1, elementwiseBinaryLayer, input1TensorInfo, 0, 0);
304 Connect(input2, elementwiseBinaryLayer, input2TensorInfo, 0, 1);
305 Connect(elementwiseBinaryLayer, output, outputTensorInfo, 0, 0);
306
307 std::vector<BackendId> backends = { "GpuFsa" };
308
309 OptimizerOptionsOpaque optimizedOptions;
310 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
311 CHECK(optNet);
312
313 Graph& graph = GetGraphForTesting(optNet.get());
314
315 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
316 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
317 &IsLayerOfType<InputLayer>,
318 &IsLayerOfType<InputLayer>,
319 &IsLayerOfType<PreCompiledLayer>,
320 &IsLayerOfType<OutputLayer>));
321}
322
David Monahan8a570462023-11-22 13:24:25 +0000323}