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