blob: aad3a0ff6f79350abc4b20683058de04cb66bce2 [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
Tracy Narinee7d27852024-01-26 09:13:19 +0000176TEST_CASE("ElementwiseBinaryAddSupportedOptimizedNetwork")
177{
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;
199 desc.m_Operation = BinaryOperation::Add;
200
201 IConnectableLayer* elementwiseBinaryLayer = network->AddElementwiseBinaryLayer(desc, "elementwiseBinary");
202 IConnectableLayer* output = network->AddOutputLayer(2, "output");
203
204 Connect(input1, elementwiseBinaryLayer, input1TensorInfo, 0, 0);
205 Connect(input2, elementwiseBinaryLayer, input2TensorInfo, 0, 1);
206 Connect(elementwiseBinaryLayer, output, outputTensorInfo, 0, 0);
207
208 std::vector<BackendId> backends = { "GpuFsa" };
209
210 OptimizerOptionsOpaque optimizedOptions;
211 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
212 CHECK(optNet);
213
214 Graph& graph = GetGraphForTesting(optNet.get());
215
216 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
217 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
218 &IsLayerOfType<InputLayer>,
219 &IsLayerOfType<InputLayer>,
220 &IsLayerOfType<PreCompiledLayer>,
221 &IsLayerOfType<OutputLayer>));
222}
223
John Mcloughlin829e13e2024-01-31 11:00:27 +0000224TEST_CASE("ElementwiseBinarySubSupportedOptimizedNetwork")
225{
226 using namespace armnn;
227
228 const float qScale = 1.0f;
229 const int32_t qOffset = 0;
230
231 const TensorShape& input1Shape = { 2, 2, 2 };
232 const TensorShape& input2Shape = { 2, 2, 2 };
233 const TensorShape& outputShape = { 2, 2, 2 };
234
235 TensorInfo input1TensorInfo(input1Shape, DataType::Float32, qScale, qOffset, true);
236 TensorInfo input2TensorInfo(input2Shape, DataType::Float32, qScale, qOffset, true);
237 TensorInfo outputTensorInfo(outputShape, DataType::Float32, qScale, qOffset);
238
239 IRuntime::CreationOptions options;
240 IRuntimePtr runtime(IRuntime::Create(options));
241 INetworkPtr network(INetwork::Create());
242
243 IConnectableLayer* input1 = network->AddInputLayer(0, "input0");
244 IConnectableLayer* input2 = network->AddInputLayer(1, "input1");
245
246 ElementwiseBinaryDescriptor desc;
247 desc.m_Operation = BinaryOperation::Sub;
248
249 IConnectableLayer* elementwiseBinaryLayer = network->AddElementwiseBinaryLayer(desc, "elementwiseBinary");
250 IConnectableLayer* output = network->AddOutputLayer(2, "output");
251
252 Connect(input1, elementwiseBinaryLayer, input1TensorInfo, 0, 0);
253 Connect(input2, elementwiseBinaryLayer, input2TensorInfo, 0, 1);
254 Connect(elementwiseBinaryLayer, output, outputTensorInfo, 0, 0);
255
256 std::vector<BackendId> backends = { "GpuFsa" };
257
258 OptimizerOptionsOpaque optimizedOptions;
259 IOptimizedNetworkPtr optNet = Optimize(*network, backends, runtime->GetDeviceSpec(), optimizedOptions);
260 CHECK(optNet);
261
262 Graph& graph = GetGraphForTesting(optNet.get());
263
264 // Check graph layer sequence to ensure that the network has been replaced with a PreCompiledLayer
265 CHECK(CheckSequence(graph.cbegin(), graph.cend(),
266 &IsLayerOfType<InputLayer>,
267 &IsLayerOfType<InputLayer>,
268 &IsLayerOfType<PreCompiledLayer>,
269 &IsLayerOfType<OutputLayer>));
270}
271
David Monahan8a570462023-11-22 13:24:25 +0000272}