blob: 8ad6f5a4d148e727d87019a068cb9f13f120feda [file] [log] [blame]
Aron Virginas-Tar70104002018-10-24 15:33:28 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00006#include <backendsCommon/test/EndToEndTestImpl.hpp>
narpra01b9546cf2018-11-20 15:21:28 +00007#include <backendsCommon/test/MergerTestImpl.hpp>
Aron Virginas-Tar70104002018-10-24 15:33:28 +01008
9#include <boost/test/unit_test.hpp>
Éanna Ó Catháin20e58802018-12-04 10:29:06 +000010#include <boost/test/execution_monitor.hpp>
Aron Virginas-Tar70104002018-10-24 15:33:28 +010011
12BOOST_AUTO_TEST_SUITE(RefEndToEnd)
13
narpra01b9546cf2018-11-20 15:21:28 +000014std::vector<armnn::BackendId> defaultBackends = {armnn::Compute::CpuRef};
15
Aron Virginas-Tar70104002018-10-24 15:33:28 +010016BOOST_AUTO_TEST_CASE(ConstantUsage_Ref_Float32)
17{
narpra01b9546cf2018-11-20 15:21:28 +000018 BOOST_TEST(ConstantUsageFloat32Test(defaultBackends));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010019}
20
21BOOST_AUTO_TEST_CASE(ConstantUsage_Ref_Uint8)
22{
narpra01b9546cf2018-11-20 15:21:28 +000023 BOOST_TEST(ConstantUsageUint8Test(defaultBackends));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010024}
25
26BOOST_AUTO_TEST_CASE(Unsigned8)
27{
28 using namespace armnn;
29
30 // Create runtime in which test will run
31 armnn::IRuntime::CreationOptions options;
32 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
33
34 // Builds up the structure of the network.
35 armnn::INetworkPtr net(INetwork::Create());
36
37 IConnectableLayer* input = net->AddInputLayer(0, "input");
38 IConnectableLayer* softmax = net->AddSoftmaxLayer(SoftmaxDescriptor(), "softmax");
39 IConnectableLayer* output = net->AddOutputLayer(0, "output");
40
41 input->GetOutputSlot(0).Connect(softmax->GetInputSlot(0));
42 softmax->GetOutputSlot(0).Connect(output->GetInputSlot(0));
43
44 // Sets the tensors in the network.
45 TensorInfo inputTensorInfo(TensorShape({1, 5}), DataType::QuantisedAsymm8);
46 inputTensorInfo.SetQuantizationOffset(100);
47 inputTensorInfo.SetQuantizationScale(10000.0f);
48 input->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
49
50 TensorInfo outputTensorInfo(TensorShape({1, 5}), DataType::QuantisedAsymm8);
51 outputTensorInfo.SetQuantizationOffset(0);
52 outputTensorInfo.SetQuantizationScale(1.0f/255.0f);
53 softmax->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
54
55 // optimize the network
narpra01b9546cf2018-11-20 15:21:28 +000056 IOptimizedNetworkPtr optNet = Optimize(*net, defaultBackends, runtime->GetDeviceSpec());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010057
58 // Loads it into the runtime.
59 NetworkId netId;
60 auto error = runtime->LoadNetwork(netId, std::move(optNet));
61 BOOST_TEST(error == Status::Success);
62
63 // Creates structures for input & output.
64 std::vector<uint8_t> inputData
65 {
66 1, 10, 3, 200, 5 // Some inputs - one of which is sufficiently larger than the others to saturate softmax.
67 };
68 std::vector<uint8_t> outputData(5);
69
70 armnn::InputTensors inputTensors
71 {
72 {0, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData.data())}
73 };
74 armnn::OutputTensors outputTensors
75 {
76 {0, armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
77 };
78
79 // Does the inference.
80 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
81
82 // Checks the results.
83 BOOST_TEST(outputData[0] == 0);
84 BOOST_TEST(outputData[1] == 0);
85 BOOST_TEST(outputData[2] == 0);
86 BOOST_TEST(outputData[3] == 255); // softmax has been saturated.
87 BOOST_TEST(outputData[4] == 0);
88}
89
90BOOST_AUTO_TEST_CASE(TrivialAdd)
91{
92 // This test was designed to match "AddTwo" in android nn/runtime/test/TestTrivialModel.cpp.
93
94 using namespace armnn;
95
96 // Create runtime in which test will run
97 armnn::IRuntime::CreationOptions options;
98 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
99
100 // Builds up the structure of the network.
101 armnn::INetworkPtr net(INetwork::Create());
102
103 IConnectableLayer* input1 = net->AddInputLayer(0);
104 IConnectableLayer* input2 = net->AddInputLayer(1);
105 IConnectableLayer* add = net->AddAdditionLayer();
106 IConnectableLayer* output = net->AddOutputLayer(0);
107
108 input1->GetOutputSlot(0).Connect(add->GetInputSlot(0));
109 input2->GetOutputSlot(0).Connect(add->GetInputSlot(1));
110 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
111
112 // Sets the tensors in the network.
113 TensorInfo tensorInfo(TensorShape({3, 4}), DataType::Float32);
114 input1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
115 input2->GetOutputSlot(0).SetTensorInfo(tensorInfo);
116 add->GetOutputSlot(0).SetTensorInfo(tensorInfo);
117
118 // optimize the network
narpra01b9546cf2018-11-20 15:21:28 +0000119 IOptimizedNetworkPtr optNet = Optimize(*net, defaultBackends, runtime->GetDeviceSpec());
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100120
121 // Loads it into the runtime.
122 NetworkId netId;
123 runtime->LoadNetwork(netId, std::move(optNet));
124
125 // Creates structures for input & output - matching android nn test.
126 std::vector<float> input1Data
127 {
128 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f
129 };
130 std::vector<float> input2Data
131 {
132 100.f, 200.f, 300.f, 400.f, 500.f, 600.f, 700.f, 800.f, 900.f, 1000.f, 1100.f, 1200.f
133 };
134 std::vector<float> outputData(12);
135
136 InputTensors inputTensors
137 {
138 {0,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input1Data.data())},
139 {1,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input2Data.data())}
140 };
141 OutputTensors outputTensors
142 {
143 {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
144 };
145
146 // Does the inference.
147 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
148
149 // Checks the results
150 BOOST_TEST(outputData[0] == 101);
151 BOOST_TEST(outputData[1] == 202);
152 BOOST_TEST(outputData[2] == 303);
153 BOOST_TEST(outputData[3] == 404);
154 BOOST_TEST(outputData[4] == 505);
155 BOOST_TEST(outputData[5] == 606);
156 BOOST_TEST(outputData[6] == 707);
157 BOOST_TEST(outputData[7] == 808);
158 BOOST_TEST(outputData[8] == 909);
159 BOOST_TEST(outputData[9] == 1010);
160 BOOST_TEST(outputData[10] == 1111);
161 BOOST_TEST(outputData[11] == 1212);
162}
163
164BOOST_AUTO_TEST_CASE(MultipleOutputs)
165{
166 using namespace armnn;
167
168 // Create runtime in which test will run
169 armnn::IRuntime::CreationOptions options;
170 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
171
172 // Builds up the structure of the network.
173 INetworkPtr net(INetwork::Create());
174
175 IConnectableLayer* input = net->AddInputLayer(0);
176
177 // ReLu1
178 ActivationDescriptor activation1Descriptor;
179 activation1Descriptor.m_Function = ActivationFunction::BoundedReLu;
180 activation1Descriptor.m_A = 1.f;
181 activation1Descriptor.m_B = -1.f;
182 IConnectableLayer* activation1 = net->AddActivationLayer(activation1Descriptor);
183
184 // ReLu6
185 ActivationDescriptor activation2Descriptor;
186 activation2Descriptor.m_Function = ActivationFunction::BoundedReLu;
187 activation2Descriptor.m_A = 6.0f;
188 IConnectableLayer* activation2 = net->AddActivationLayer(activation2Descriptor);
189
190 // BoundedReLu(min=2, max=5)
191 ActivationDescriptor activation3Descriptor;
192 activation3Descriptor.m_Function = ActivationFunction::BoundedReLu;
193 activation3Descriptor.m_A = 5.0f;
194 activation3Descriptor.m_B = 2.0f;
195 IConnectableLayer* activation3 = net->AddActivationLayer(activation3Descriptor);
196
197 IConnectableLayer* output1 = net->AddOutputLayer(0);
198 IConnectableLayer* output2 = net->AddOutputLayer(1);
199 IConnectableLayer* output3 = net->AddOutputLayer(2);
200
201 input->GetOutputSlot(0).Connect(activation1->GetInputSlot(0));
202 input->GetOutputSlot(0).Connect(activation2->GetInputSlot(0));
203 input->GetOutputSlot(0).Connect(activation3->GetInputSlot(0));
204
205 activation1->GetOutputSlot(0).Connect(output1->GetInputSlot(0));
206 activation2->GetOutputSlot(0).Connect(output2->GetInputSlot(0));
207 activation3->GetOutputSlot(0).Connect(output3->GetInputSlot(0));
208
209 // Sets the tensors in the network.
210 TensorInfo tensorInfo(TensorShape({ 10 }), DataType::Float32);
211 input->GetOutputSlot(0).SetTensorInfo(tensorInfo);
212 activation1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
213 activation2->GetOutputSlot(0).SetTensorInfo(tensorInfo);
214 activation3->GetOutputSlot(0).SetTensorInfo(tensorInfo);
215
216 // optimize the network
narpra01b9546cf2018-11-20 15:21:28 +0000217 IOptimizedNetworkPtr optNet = Optimize(*net, defaultBackends, runtime->GetDeviceSpec());
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100218
219 // Loads it into the runtime.
220 NetworkId netId;
221 runtime->LoadNetwork(netId, std::move(optNet));
222
223 // Creates structures for input & output.
224 const std::vector<float> inputData{ 3.f, 5.f, 2.f, 3.f, 7.f, 0.f, -2.f, -1.f, 3.f, 3.f };
225
226 std::vector<float> output1Data(inputData.size());
227 std::vector<float> output2Data(inputData.size());
228 std::vector<float> output3Data(inputData.size());
229
230 InputTensors inputTensors
231 {
232 {0,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData.data())}
233 };
234 OutputTensors outputTensors
235 {
236 {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), output1Data.data())},
237 {1,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 1), output2Data.data())},
238 {2,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 2), output3Data.data())}
239 };
240
241 // Does the inference.
242 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
243
244 // Checks the results.
245 BOOST_TEST(output1Data == std::vector<float>({ 1.f, 1.f, 1.f, 1.f, 1.f, 0.f, -1.f, -1.f, 1.f, 1.f })); // ReLu1
246 BOOST_TEST(output2Data == std::vector<float>({ 3.f, 5.f, 2.f, 3.f, 6.f, 0.f, 0.f, 0.f, 3.f, 3.f })); // ReLu6
247 BOOST_TEST(output3Data == std::vector<float>({ 3.f, 5.f, 2.f, 3.f, 5.f, 2.f, 2.f, 2.f, 3.f, 3.f })); // [2, 5]
248}
249
Éanna Ó Catháin20e58802018-12-04 10:29:06 +0000250BOOST_AUTO_TEST_CASE(TrivialMin)
251{
252 using namespace armnn;
253
254 // Create runtime in which test will run
255 armnn::IRuntime::CreationOptions options;
256 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
257
258 // Builds up the structure of the network.
259 armnn::INetworkPtr net(INetwork::Create());
260
261 IConnectableLayer* input1 = net->AddInputLayer(0);
262 IConnectableLayer* input2 = net->AddInputLayer(1);
263 IConnectableLayer* min = net->AddMinimumLayer();
264 IConnectableLayer* output = net->AddOutputLayer(0);
265
266 input1->GetOutputSlot(0).Connect(min->GetInputSlot(0));
267 input2->GetOutputSlot(0).Connect(min->GetInputSlot(1));
268 min->GetOutputSlot(0).Connect(output->GetInputSlot(0));
269
270 // Sets the tensors in the network.
271 TensorInfo tensorInfo(TensorShape({1, 1, 1, 4}), DataType::Float32);
272 input1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
273 input2->GetOutputSlot(0).SetTensorInfo(tensorInfo);
274 min->GetOutputSlot(0).SetTensorInfo(tensorInfo);
275
276 // optimize the network
277 IOptimizedNetworkPtr optNet = Optimize(*net, defaultBackends, runtime->GetDeviceSpec());
278
279 // Loads it into the runtime.
280 NetworkId netId;
281 runtime->LoadNetwork(netId, std::move(optNet));
282
283 // Creates structures for input & output - matching android nn test.
284 std::vector<float> input1Data
285 {
286 1.0f, 2.0f, 3.0f, 4.0f
287 };
288 std::vector<float> input2Data
289 {
290 2.0f, 1.0f, 5.0f, 2.0f
291 };
292 std::vector<float> outputData(4);
293
294 InputTensors inputTensors
295 {
296 {0,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input1Data.data())},
297 {1,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input2Data.data())}
298 };
299 OutputTensors outputTensors
300 {
301 {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
302 };
303
304 // Does the inference.
305 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
306
307 // Checks the results
308 BOOST_TEST(outputData[0] == 1);
309 BOOST_TEST(outputData[1] == 1);
310 BOOST_TEST(outputData[2] == 3);
311 BOOST_TEST(outputData[3] == 2);
312}
313
314
narpra01b9546cf2018-11-20 15:21:28 +0000315BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim0Test)
316{
317 MergerDim0EndToEnd<float>(defaultBackends);
318}
319
320BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim0Uint8Test)
321{
322 MergerDim0EndToEnd<uint8_t>(defaultBackends);
323}
324
325BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim1Test)
326{
327 MergerDim1EndToEnd<float>(defaultBackends);
328}
329
330BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim1Uint8Test)
331{
332 MergerDim1EndToEnd<uint8_t>(defaultBackends);
333}
334
335BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim2Test)
336{
337 MergerDim2EndToEnd<float>(defaultBackends);
338}
339
340BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim2Uint8Test)
341{
342 MergerDim2EndToEnd<uint8_t>(defaultBackends);
343}
344
345BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim3Test)
346{
347 MergerDim3EndToEnd<float>(defaultBackends);
348}
349
350BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim3Uint8Test)
351{
352 MergerDim3EndToEnd<uint8_t>(defaultBackends);
353}
354
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100355BOOST_AUTO_TEST_SUITE_END()