blob: cf4d91b1191b7b113cd39bde2cb4c9d71c5001a5 [file] [log] [blame]
Narumol Prangnawaratb8d771a2020-08-14 11:51:12 +01001//
2// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include <backendsCommon/test/CommonTestUtils.hpp>
7#include <backendsCommon/test/mockBackend/MockImportBackend.hpp>
8
9#include <test/GraphUtils.hpp>
10
11#include <boost/test/unit_test.hpp>
12
13BOOST_AUTO_TEST_SUITE(NeonFallback)
14
15std::vector<armnn::BackendId> defaultBackends = { armnn::Compute::CpuAcc };
16
17BOOST_AUTO_TEST_CASE(FallbackImportToCpuAcc)
18{
19 using namespace armnn;
20
21 // Create a mock backend object
22 MockImportBackendInitialiser initialiser; // Register the Mock Backend
23 auto backendObjPtr = CreateBackendObject(MockImportBackendId());
24 BOOST_TEST((backendObjPtr != nullptr));
25
26 BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
27 if (backendIds.find("MockRef") == backendIds.end())
28 {
29 std::string message = "Cannot load MockRef";
30 BOOST_FAIL(message);
31 }
32
33 // Create runtime in which test will run and allow fallback to CpuRef.
34 IRuntime::CreationOptions options;
35 IRuntimePtr runtime(IRuntime::Create(options));
36
37 // Builds up the structure of the network.
38 INetworkPtr net(INetwork::Create());
39
40 IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
41 IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
42 IConnectableLayer* input2 = net->AddInputLayer(2, "input2");
43 IConnectableLayer* add = net->AddAdditionLayer("add");
44 IConnectableLayer* sub = net->AddSubtractionLayer("sub");
45 IConnectableLayer* output = net->AddOutputLayer(0, "output");
46
47 input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
48 input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
49 input2->GetOutputSlot(0).Connect(sub->GetInputSlot(0));
50 add->GetOutputSlot(0).Connect(sub->GetInputSlot(1));
51 sub->GetOutputSlot(0).Connect(output->GetInputSlot(0));
52
53 TensorInfo info = TensorInfo({ 1, 2, 3, 2 }, DataType::Float32);
54
55 input0->GetOutputSlot(0).SetTensorInfo(info);
56 input1->GetOutputSlot(0).SetTensorInfo(info);
57 input2->GetOutputSlot(0).SetTensorInfo(info);
58 add->GetOutputSlot(0).SetTensorInfo(info);
59 sub->GetOutputSlot(0).SetTensorInfo(info);
60
61 // optimize the network
62 std::vector<BackendId> backends = { "MockRef", Compute::CpuAcc };
63 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
64
65 OptimizedNetwork* optNetObjPtr = PolymorphicDowncast<OptimizedNetwork*>(optNet.get());
66 Graph& graph = optNetObjPtr->GetGraph();
67
68 armnn::Layer* const layer0 = GetFirstLayerWithName(graph, "input0");
69 armnn::Layer* const layer1 = GetFirstLayerWithName(graph, "input1");
70 armnn::Layer* const layer2 = GetFirstLayerWithName(graph, "input2");
71 armnn::Layer* const layer3 = GetFirstLayerWithName(graph, "add");
72 armnn::Layer* const layer4 = GetFirstLayerWithName(graph, "[ add (0) -> sub (1) ]");
73 armnn::Layer* const layer5 = GetFirstLayerWithName(graph, "sub");
74 armnn::Layer* const layer6 = GetFirstLayerWithName(graph, "output");
75
76 // Checks order is valid.
77 BOOST_TEST(CheckOrder(graph, layer0, layer1));
78 BOOST_TEST(CheckOrder(graph, layer1, layer2));
79 BOOST_TEST(CheckOrder(graph, layer2, layer3));
80 BOOST_TEST(CheckOrder(graph, layer3, layer4));
81 BOOST_TEST(CheckOrder(graph, layer4, layer5));
82 BOOST_TEST(CheckOrder(graph, layer5, layer6));
83
84 // Load it into the runtime. It should pass.
85 NetworkId netId;
86 std::string ignoredErrorMessage;
87 INetworkProperties networkProperties(true, true);
88
89 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
90
91 // Creates structures for input & output
92 std::vector<float> inputData0
93 {
94 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f
95 };
96 std::vector<float> inputData1
97 {
98 0.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f
99 };
100 std::vector<float> inputData2
101 {
102 12.0f, 11.0f, 10.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f
103 };
104
105 std::vector<float> outputData(12);
106
107 std::vector<float> expectedOutput
108 {
109 11.0f, 9.0f, 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, -7.0f, -9.0f, -11.0f
110 };
111
112 InputTensors inputTensors
113 {
114 { 0, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData0.data()) },
115 { 1, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 1), inputData1.data()) },
116 { 2, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 2), inputData2.data()) }
117 };
118 OutputTensors outputTensors
119 {
120 { 0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data()) }
121 };
122
123 runtime->GetProfiler(netId)->EnableProfiling(true);
124
125 // Do the inference
126 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
127
128 // Retrieve the Profiler.Print() output to get the workload execution
129 ProfilerManager& profilerManager = armnn::ProfilerManager::GetInstance();
130 std::stringstream ss;
131 profilerManager.GetProfiler()->Print(ss);;
132 std::string dump = ss.str();
133
134 // Contains ImportMemGeneric
135 std::size_t found = dump.find("ImportMemGeneric");
136 BOOST_TEST(found != std::string::npos);
137
138 // Contains SyncMemGeneric
139 found = dump.find("SyncMemGeneric");
140 BOOST_TEST(found != std::string::npos);
141
142 // Does not contain CopyMemGeneric
143 found = dump.find("CopyMemGeneric");
144 BOOST_TEST(found == std::string::npos);
145
146 // Use memory import between backends
147 BOOST_TEST((layer4->GetType() == LayerType::MemImport));
148
149 // Check output is as expected
150 BOOST_TEST(outputData == expectedOutput);
151}
152
153BOOST_AUTO_TEST_CASE(FallbackPaddingCopyToCpuAcc)
154{
155 using namespace armnn;
156
157 // Create a mock backend object
158 MockImportBackendInitialiser initialiser; // Register the Mock Backend
159 auto backendObjPtr = CreateBackendObject(MockImportBackendId());
160 BOOST_TEST((backendObjPtr != nullptr));
161
162 BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
163 if (backendIds.find("MockRef") == backendIds.end())
164 {
165 std::string message = "Cannot load MockRef";
166 BOOST_FAIL(message);
167 }
168
169 // Create runtime in which test will run and allow fallback to CpuRef.
170 IRuntime::CreationOptions options;
171 IRuntimePtr runtime(IRuntime::Create(options));
172
173 // Builds up the structure of the network.
174 INetworkPtr net(INetwork::Create());
175
176 Pooling2dDescriptor desc;
177
178 IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
179 IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
180 IConnectableLayer* add = net->AddAdditionLayer("add");
181 IConnectableLayer* pooling = net->AddPooling2dLayer(desc, "pooling");
182 IConnectableLayer* output = net->AddOutputLayer(0, "output");
183
184 input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
185 input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
186 add->GetOutputSlot(0).Connect(pooling->GetInputSlot(0));
187 pooling->GetOutputSlot(0).Connect(output->GetInputSlot(0));
188
189 TensorInfo info = TensorInfo({ 1, 2, 3, 2 }, DataType::Float32);
190 TensorInfo poolingInfo = TensorInfo({ 1, 2, 1, 1 }, DataType::Float32);
191
192 input0->GetOutputSlot(0).SetTensorInfo(info);
193 input1->GetOutputSlot(0).SetTensorInfo(info);
194 add->GetOutputSlot(0).SetTensorInfo(info);
195 pooling->GetOutputSlot(0).SetTensorInfo(poolingInfo);
196
197 // optimize the network
198 std::vector<BackendId> backends = { "MockRef", Compute::CpuAcc };
199 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
200
201 OptimizedNetwork* optNetObjPtr = PolymorphicDowncast<OptimizedNetwork*>(optNet.get());
202 Graph& graph = optNetObjPtr->GetGraph();
203
204 armnn::Layer* const layer0 = GetFirstLayerWithName(graph, "input0");
205 armnn::Layer* const layer1 = GetFirstLayerWithName(graph, "input1");
206 armnn::Layer* const layer2 = GetFirstLayerWithName(graph, "add");
207 armnn::Layer* const layer3 = GetFirstLayerWithName(graph, "[ add (0) -> pooling (0) ]");
208 armnn::Layer* const layer4 = GetFirstLayerWithName(graph, "pooling");
209 armnn::Layer* const layer5 = GetFirstLayerWithName(graph, "output");
210
211 // Checks order is valid.
212 BOOST_TEST(CheckOrder(graph, layer0, layer1));
213 BOOST_TEST(CheckOrder(graph, layer1, layer2));
214 BOOST_TEST(CheckOrder(graph, layer2, layer3));
215 BOOST_TEST(CheckOrder(graph, layer3, layer4));
216 BOOST_TEST(CheckOrder(graph, layer4, layer5));
217
218 // Load it into the runtime. It should pass.
219 NetworkId netId;
220 std::string ignoredErrorMessage;
221 INetworkProperties networkProperties(true, true);
222
223 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
224
225 // Creates structures for input & output
226 std::vector<float> inputData0
227 {
228 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f
229 };
230 std::vector<float> inputData1
231 {
232 0.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f
233 };
234
235 std::vector<float> outputData(2);
236
237 std::vector<float> expectedOutput
238 {
239 6.0f, 12.0f
240 };
241
242 InputTensors inputTensors
243 {
244 { 0, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData0.data()) },
245 { 1, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 1), inputData1.data()) }
246 };
247 OutputTensors outputTensors
248 {
249 { 0, armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data()) }
250 };
251
252 runtime->GetProfiler(netId)->EnableProfiling(true);
253
254 // Do the inference
255 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
256
257 // Retrieve the Profiler.Print() output to get the workload execution
258 ProfilerManager& profilerManager = armnn::ProfilerManager::GetInstance();
259 std::stringstream ss;
260 profilerManager.GetProfiler()->Print(ss);;
261 std::string dump = ss.str();
262
263 // Contains CopyMemGeneric between the backends
264 std::size_t found = dump.find("CopyMemGeneric");
265 BOOST_TEST(found != std::string::npos);
266
267 // Contains SyncMemGeneric for the output
268 found = dump.find("SyncMemGeneric");
269 BOOST_TEST(found != std::string::npos);
270
271 // Does not contain ImportMemGeneric
272 found = dump.find("ImportMemGeneric");
273 BOOST_TEST(found == std::string::npos);
274
275 // Use memory import between backends
276 BOOST_TEST((layer3->GetType() == LayerType::MemCopy));
277
278 // Check output is as expected
279 BOOST_TEST(outputData == expectedOutput);
280}
281
282BOOST_AUTO_TEST_CASE(FallbackImportFromCpuAcc)
283{
284 using namespace armnn;
285
286 // Create a mock backend object
287 MockImportBackendInitialiser initialiser; // Register the Mock Backend
288 auto backendObjPtr = CreateBackendObject(MockImportBackendId());
289 BOOST_TEST((backendObjPtr != nullptr));
290
291 BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
292 if (backendIds.find("MockRef") == backendIds.end())
293 {
294 std::string message = "Cannot load MockRef";
295 BOOST_FAIL(message);
296 }
297
298 // Create runtime in which test will run and allow fallback to CpuRef.
299 IRuntime::CreationOptions options;
300 IRuntimePtr runtime(IRuntime::Create(options));
301
302 // Builds up the structure of the network.
303 INetworkPtr net(INetwork::Create());
304
305 IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
306 IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
307 IConnectableLayer* input2 = net->AddInputLayer(2, "input2");
308 IConnectableLayer* sub = net->AddSubtractionLayer("sub");
309 IConnectableLayer* add = net->AddAdditionLayer("add");
310 IConnectableLayer* output = net->AddOutputLayer(0, "output");
311
312 input0->GetOutputSlot(0).Connect(sub->GetInputSlot(0));
313 input1->GetOutputSlot(0).Connect(sub->GetInputSlot(1));
314 input2->GetOutputSlot(0).Connect(add->GetInputSlot(0));
315 sub->GetOutputSlot(0).Connect(add->GetInputSlot(1));
316 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
317
318 TensorInfo info = TensorInfo({ 1, 2, 3, 2 }, DataType::Float32);
319
320 input0->GetOutputSlot(0).SetTensorInfo(info);
321 input1->GetOutputSlot(0).SetTensorInfo(info);
322 input2->GetOutputSlot(0).SetTensorInfo(info);
323 sub->GetOutputSlot(0).SetTensorInfo(info);
324 add->GetOutputSlot(0).SetTensorInfo(info);
325
326 // optimize the network
327 std::vector<BackendId> backends = { "MockRef", Compute::CpuAcc };
328 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
329
330 OptimizedNetwork* optNetObjPtr = PolymorphicDowncast<OptimizedNetwork*>(optNet.get());
331 Graph& graph = optNetObjPtr->GetGraph();
332
333 armnn::Layer* const layer0 = GetFirstLayerWithName(graph, "input0");
334 armnn::Layer* const layer1 = GetFirstLayerWithName(graph, "input1");
335 armnn::Layer* const layer2 = GetFirstLayerWithName(graph, "input2");
336 armnn::Layer* const layer3 = GetFirstLayerWithName(graph, "sub");
337 armnn::Layer* const layer4 = GetFirstLayerWithName(graph, "[ sub (0) -> add (1) ]");
338 armnn::Layer* const layer5 = GetFirstLayerWithName(graph, "add");
339 armnn::Layer* const layer6 = GetFirstLayerWithName(graph, "output");
340
341 // Checks order is valid.
342 BOOST_TEST(CheckOrder(graph, layer0, layer1));
343 BOOST_TEST(CheckOrder(graph, layer1, layer2));
344 BOOST_TEST(CheckOrder(graph, layer2, layer3));
345 BOOST_TEST(CheckOrder(graph, layer3, layer4));
346 BOOST_TEST(CheckOrder(graph, layer4, layer5));
347 BOOST_TEST(CheckOrder(graph, layer5, layer6));
348
349 // Load it into the runtime. It should pass.
350 NetworkId netId;
351 std::string ignoredErrorMessage;
352 INetworkProperties networkProperties(true, true);
353
354 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
355
356 // Creates structures for input & output
357 std::vector<float> inputData0
358 {
359 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 0.0f
360 };
361 std::vector<float> inputData1
362 {
363 0.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f
364 };
365 std::vector<float> inputData2
366 {
367 12.0f, 11.0f, 10.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f
368 };
369
370 std::vector<float> outputData(12);
371
372 std::vector<float> expectedOutput
373 {
374 13.0f, 11.0f, 11.0f, 9.0f, 7.0f, 7.0f, 7.0f, 5.0f, 5.0f, 3.0f, 3.0f, -5.0f
375 };
376
377 InputTensors inputTensors
378 {
379 { 0, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData0.data()) },
380 { 1, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 1), inputData1.data()) },
381 { 2, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 2), inputData2.data()) }
382 };
383 OutputTensors outputTensors
384 {
385 { 0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data()) }
386 };
387
388 runtime->GetProfiler(netId)->EnableProfiling(true);
389
390 // Do the inference
391 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
392
393 // Retrieve the Profiler.Print() output to get the workload execution
394 ProfilerManager& profilerManager = armnn::ProfilerManager::GetInstance();
395 std::stringstream ss;
396 profilerManager.GetProfiler()->Print(ss);;
397 std::string dump = ss.str();
398
399 // Contains ImportMemGeneric
400 std::size_t found = dump.find("ImportMemGeneric");
401 BOOST_TEST(found != std::string::npos);
402
403 // Contains SyncMemGeneric
404 found = dump.find("SyncMemGeneric");
405 BOOST_TEST(found != std::string::npos);
406
407 // Does not contain CopyMemGeneric
408 found = dump.find("CopyMemGeneric");
409 BOOST_TEST(found == std::string::npos);
410
411 // Use memory import between backends
412 BOOST_TEST((layer4->GetType() == LayerType::MemImport));
413
414 // Check output is as expected
415 BOOST_TEST(outputData == expectedOutput);
416}
417
418BOOST_AUTO_TEST_CASE(FallbackPaddingCopyFromCpuAcc)
419{
420 using namespace armnn;
421
422 // Create a mock backend object
423 MockImportBackendInitialiser initialiser; // Register the Mock Backend
424 auto backendObjPtr = CreateBackendObject(MockImportBackendId());
425 BOOST_TEST((backendObjPtr != nullptr));
426
427 BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
428 if (backendIds.find("MockRef") == backendIds.end())
429 {
430 std::string message = "Cannot load MockRef";
431 BOOST_FAIL(message);
432 }
433
434 // Create runtime in which test will run and allow fallback to CpuRef.
435 IRuntime::CreationOptions options;
436 IRuntimePtr runtime(IRuntime::Create(options));
437
438 // Builds up the structure of the network.
439 INetworkPtr net(INetwork::Create());
440
441 Pooling2dDescriptor desc;
442
443 IConnectableLayer* input0 = net->AddInputLayer(0, "input0");
444 IConnectableLayer* input1 = net->AddInputLayer(1, "input1");
445 IConnectableLayer* pooling = net->AddPooling2dLayer(desc, "pooling");
446 IConnectableLayer* add = net->AddAdditionLayer("add");
447 IConnectableLayer* output = net->AddOutputLayer(0, "output");
448
449 input0->GetOutputSlot(0).Connect(pooling->GetInputSlot(0));
450 input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
451 pooling->GetOutputSlot(0).Connect(add->GetInputSlot(0));
452 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
453
454 TensorInfo inputInfo = TensorInfo({ 1, 2, 3, 2 }, DataType::Float32);
455 TensorInfo poolingInfo = TensorInfo({ 1, 2, 1, 1 }, DataType::Float32);
456
457 input0->GetOutputSlot(0).SetTensorInfo(inputInfo);
458 input1->GetOutputSlot(0).SetTensorInfo(poolingInfo);
459 pooling->GetOutputSlot(0).SetTensorInfo(poolingInfo);
460 add->GetOutputSlot(0).SetTensorInfo(poolingInfo);
461
462 // optimize the network
463 std::vector<BackendId> backends = { "MockRef", Compute::CpuAcc };
464 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
465
466 OptimizedNetwork* optNetObjPtr = PolymorphicDowncast<OptimizedNetwork*>(optNet.get());
467 Graph& graph = optNetObjPtr->GetGraph();
468
469 armnn::Layer* const layer0 = GetFirstLayerWithName(graph, "input0");
470 armnn::Layer* const layer1 = GetFirstLayerWithName(graph, "input1");
471 armnn::Layer* const layer2 = GetFirstLayerWithName(graph, "pooling");
472 armnn::Layer* const layer3 = GetFirstLayerWithName(graph, "[ pooling (0) -> add (0) ]");
473 armnn::Layer* const layer4 = GetFirstLayerWithName(graph, "add");
474 armnn::Layer* const layer5 = GetFirstLayerWithName(graph, "output");
475
476 // Checks order is valid.
477 BOOST_TEST(CheckOrder(graph, layer0, layer1));
478 BOOST_TEST(CheckOrder(graph, layer1, layer2));
479 BOOST_TEST(CheckOrder(graph, layer2, layer3));
480 BOOST_TEST(CheckOrder(graph, layer3, layer4));
481 BOOST_TEST(CheckOrder(graph, layer4, layer5));
482
483 // Load it into the runtime. It should pass.
484 NetworkId netId;
485 std::string ignoredErrorMessage;
486 INetworkProperties networkProperties(true, true);
487
488 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
489
490 // Creates structures for input & output
491 std::vector<float> inputData0
492 {
493 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f
494 };
495 std::vector<float> inputData1
496 {
497 -1.0f, 3.0f
498 };
499
500 std::vector<float> outputData(2);
501
502 std::vector<float> expectedOutput
503 {
504 5.0f, 15.0f
505 };
506
507 InputTensors inputTensors
508 {
509 { 0, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData0.data()) },
510 { 1, armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 1), inputData1.data()) }
511 };
512 OutputTensors outputTensors
513 {
514 { 0, armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data()) }
515 };
516
517 runtime->GetProfiler(netId)->EnableProfiling(true);
518
519 // Do the inference
520 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
521
522 // Retrieve the Profiler.Print() output to get the workload execution
523 ProfilerManager& profilerManager = armnn::ProfilerManager::GetInstance();
524 std::stringstream ss;
525 profilerManager.GetProfiler()->Print(ss);;
526 std::string dump = ss.str();
527
528 // Contains CopyMemGeneric between the backends
529 std::size_t found = dump.find("CopyMemGeneric");
530 BOOST_TEST(found != std::string::npos);
531
532 // Contains SyncMemGeneric for the output
533 found = dump.find("SyncMemGeneric");
534 BOOST_TEST(found != std::string::npos);
535
536 // Does not contain ImportMemGeneric
537 found = dump.find("ImportMemGeneric");
538 BOOST_TEST(found == std::string::npos);
539
540 // Use memory import between backends
541 BOOST_TEST((layer3->GetType() == LayerType::MemCopy));
542
543 // Check output is as expected
544 BOOST_TEST(outputData == expectedOutput);
545}
546
547BOOST_AUTO_TEST_SUITE_END()