1 //
2 // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "ArmNNProfilingServiceInitialiser.hpp"
7 #include "MockBackendId.hpp"
8 #include "ProfilingOptionsConverter.hpp"
9
10 #include <TestUtils.hpp>
11
12 #include <armnn/BackendId.hpp>
13 #include <armnn/Logging.hpp>
14
15 #include <armnn/profiling/ArmNNProfiling.hpp>
16
17 #include <armnn/utility/IgnoreUnused.hpp>
18
19 #include <armnnTestUtils/MockBackend.hpp>
20
21 #include <client/include/CounterIdMap.hpp>
22 #include <client/include/Holder.hpp>
23 #include <client/include/ISendTimelinePacket.hpp>
24 #include <client/include/ProfilingOptions.hpp>
25
26 #include <client/src/PeriodicCounterCapture.hpp>
27 #include <client/src/PeriodicCounterSelectionCommandHandler.hpp>
28 #include <client/src/ProfilingStateMachine.hpp>
29 #include <client/src/ProfilingUtils.hpp>
30 #include <client/src/RequestCounterDirectoryCommandHandler.hpp>
31
32 #include <client/src/backends/BackendProfiling.hpp>
33
34 #include <common/include/CounterDirectory.hpp>
35 #include <common/include/PacketVersionResolver.hpp>
36
37 #include <doctest/doctest.h>
38
39 #include <vector>
40 #include <cstdint>
41 #include <limits>
42
43 namespace arm
44 {
45
46 namespace pipe
47 {
48
49 struct LogLevelSwapper
50 {
51 public:
LogLevelSwapperarm::pipe::LogLevelSwapper52 LogLevelSwapper(arm::pipe::LogSeverity severity)
53 {
54 // Set the new log level
55 arm::pipe::ConfigureLogging(true, true, severity);
56 }
~LogLevelSwapperarm::pipe::LogLevelSwapper57 ~LogLevelSwapper()
58 {
59 // The default log level for unit tests is "Fatal"
60 arm::pipe::ConfigureLogging(true, true, arm::pipe::LogSeverity::Fatal);
61 }
62 };
63
64 } // namespace pipe
65
66 } // namespace arm
67
68 using namespace arm::pipe;
69
70 class ReadCounterVals : public IReadCounterValues
71 {
IsCounterRegistered(uint16_t counterUid) const72 virtual bool IsCounterRegistered(uint16_t counterUid) const override
73 {
74 return (counterUid > 4 && counterUid < 11);
75 }
IsCounterRegistered(const std::string & counterName) const76 virtual bool IsCounterRegistered(const std::string& counterName) const override
77 {
78 armnn::IgnoreUnused(counterName);
79 return false;
80 }
GetCounterCount() const81 virtual uint16_t GetCounterCount() const override
82 {
83 return 1;
84 }
GetAbsoluteCounterValue(uint16_t counterUid) const85 virtual uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override
86 {
87 return counterUid;
88 }
GetDeltaCounterValue(uint16_t counterUid)89 virtual uint32_t GetDeltaCounterValue(uint16_t counterUid) override
90 {
91 return counterUid;
92 }
93 };
94
95 class MockBackendSendCounterPacket : public ISendCounterPacket
96 {
97 public:
98 using IndexValuePairsVector = std::vector<CounterValue>;
99
100 /// Create and write a StreamMetaDataPacket in the buffer
SendStreamMetaDataPacket()101 virtual void SendStreamMetaDataPacket() {}
102
103 /// Create and write a CounterDirectoryPacket from the parameters to the buffer.
SendCounterDirectoryPacket(const ICounterDirectory & counterDirectory)104 virtual void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory)
105 {
106 armnn::IgnoreUnused(counterDirectory);
107 }
108
109 /// Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
SendPeriodicCounterCapturePacket(uint64_t timestamp,const IndexValuePairsVector & values)110 virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values)
111 {
112 m_timestamps.emplace_back(Timestamp{timestamp, values});
113 }
114
115 /// Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer.
SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,const std::vector<uint16_t> & selectedCounterIds)116 virtual void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
117 const std::vector<uint16_t>& selectedCounterIds)
118 {
119 armnn::IgnoreUnused(capturePeriod);
120 armnn::IgnoreUnused(selectedCounterIds);
121 }
122
GetTimestamps()123 std::vector<Timestamp> GetTimestamps()
124 {
125 return m_timestamps;
126 }
127
ClearTimestamps()128 void ClearTimestamps()
129 {
130 m_timestamps.clear();
131 }
132
133 private:
134 std::vector<Timestamp> m_timestamps;
135 };
136
PacketWriter(uint32_t period,std::vector<uint16_t> countervalues)137 arm::pipe::Packet PacketWriter(uint32_t period, std::vector<uint16_t> countervalues)
138 {
139 const uint32_t packetId = 0x40000;
140 uint32_t offset = 0;
141 uint32_t dataLength = static_cast<uint32_t>(4 + countervalues.size() * 2);
142 std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
143 unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData.get());
144
145 WriteUint32(data1, offset, period);
146 offset += 4;
147 for (auto countervalue : countervalues)
148 {
149 WriteUint16(data1, offset, countervalue);
150 offset += 2;
151 }
152
153 return {packetId, dataLength, uniqueData};
154 }
155
156 TEST_SUITE("BackendProfilingTestSuite")
157 {
158 TEST_CASE("BackendProfilingCounterRegisterMockBackendTest")
159 {
160 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
161
162 // Reset the profiling service to the uninitialized state
163 armnn::IRuntime::CreationOptions options;
164 options.m_ProfilingOptions.m_EnableProfiling = true;
165
166 armnn::MockBackendInitialiser initialiser;
167 // Create a runtime
168 armnn::RuntimeImpl runtime(options);
169
170 unsigned int shiftedId = 0;
171
172 // Check if the MockBackends 3 dummy counters {0, 1, 2-5 (four cores)} are registered
173 armnn::BackendId mockId = armnn::MockBackendId();
174 const ICounterMappings& counterMap = GetProfilingService(&runtime).GetCounterMappings();
175 CHECK(counterMap.GetGlobalId(0, mockId) == 5 + shiftedId);
176 CHECK(counterMap.GetGlobalId(1, mockId) == 6 + shiftedId);
177 CHECK(counterMap.GetGlobalId(2, mockId) == 7 + shiftedId);
178 CHECK(counterMap.GetGlobalId(3, mockId) == 8 + shiftedId);
179 CHECK(counterMap.GetGlobalId(4, mockId) == 9 + shiftedId);
180 CHECK(counterMap.GetGlobalId(5, mockId) == 10 + shiftedId);
181 options.m_ProfilingOptions.m_EnableProfiling = false;
182 GetProfilingService(&runtime).ResetExternalProfilingOptions(
183 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
184 }
185
186 TEST_CASE("TestBackendCounters")
187 {
188 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
189
190 Holder holder;
191 arm::pipe::PacketVersionResolver packetVersionResolver;
192 ProfilingStateMachine stateMachine;
193 ReadCounterVals readCounterVals;
194 CounterIdMap counterIdMap;
195 MockBackendSendCounterPacket sendCounterPacket;
196
197 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
198 const std::string gpuAccId(GetComputeDeviceAsCString(armnn::Compute::GpuAcc));
199
200 ProfilingOptions options;
201 options.m_EnableProfiling = true;
202
203 armnn::ArmNNProfilingServiceInitialiser initialiser;
204 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
205 arm::pipe::MAX_ARMNN_COUNTER,
206 initialiser,
207 arm::pipe::ARMNN_SOFTWARE_INFO,
208 arm::pipe::ARMNN_SOFTWARE_VERSION,
209 arm::pipe::ARMNN_HARDWARE_VERSION);
210
211 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
212 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
213 std::unique_ptr<IBackendProfiling> gpuBackendProfilingPtr =
214 std::make_unique<BackendProfiling>(options, *profilingService.get(), gpuAccId);
215
216 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
217 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
218 std::shared_ptr<IBackendProfilingContext> gpuProfilingContextPtr =
219 std::make_shared<armnn::MockBackendProfilingContext>(gpuBackendProfilingPtr);
220
221 std::unordered_map<std::string,
222 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
223
224 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
225 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
226
227 uint16_t globalId = 5;
228
229 counterIdMap.RegisterMapping(globalId++, 0, cpuAccId);
230 counterIdMap.RegisterMapping(globalId++, 1, cpuAccId);
231 counterIdMap.RegisterMapping(globalId++, 2, cpuAccId);
232
233 counterIdMap.RegisterMapping(globalId++, 0, gpuAccId);
234 counterIdMap.RegisterMapping(globalId++, 1, gpuAccId);
235 counterIdMap.RegisterMapping(globalId++, 2, gpuAccId);
236
237 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
238 backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
239
240 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
241 counterIdMap, backendProfilingContexts);
242
243 uint16_t maxArmnnCounterId = 4;
244
245 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
246 4,
247 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
248 backendProfilingContexts,
249 counterIdMap,
250 holder,
251 maxArmnnCounterId,
252 periodicCounterCapture,
253 readCounterVals,
254 sendCounterPacket,
255 stateMachine);
256
257 stateMachine.TransitionToState(ProfilingState::NotConnected);
258 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
259 stateMachine.TransitionToState(ProfilingState::Active);
260
261 uint32_t period = 12345u;
262
263 std::vector<uint16_t> cpuCounters{5, 6, 7};
264 std::vector<uint16_t> gpuCounters{8, 9, 10};
265
266 // Request only gpu counters
267 periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters));
268 periodicCounterCapture.Stop();
269
270 std::set<std::string> activeIds = holder.GetCaptureData().GetActiveBackends();
271 CHECK(activeIds.size() == 1);
272 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
273
274 std::vector<Timestamp> recievedTimestamp = sendCounterPacket.GetTimestamps();
275
276 CHECK(recievedTimestamp[0].timestamp == period);
277 CHECK(recievedTimestamp.size() == 1);
278 CHECK(recievedTimestamp[0].counterValues.size() == gpuCounters.size());
279 for (unsigned long i=0; i< gpuCounters.size(); ++i)
280 {
281 CHECK(recievedTimestamp[0].counterValues[i].counterId == gpuCounters[i]);
282 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
283 }
284 sendCounterPacket.ClearTimestamps();
285
286 // Request only cpu counters
287 periodicCounterSelectionCommandHandler(PacketWriter(period, cpuCounters));
288 periodicCounterCapture.Stop();
289
290 activeIds = holder.GetCaptureData().GetActiveBackends();
291 CHECK(activeIds.size() == 1);
292 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
293
294 recievedTimestamp = sendCounterPacket.GetTimestamps();
295
296 CHECK(recievedTimestamp[0].timestamp == period);
297 CHECK(recievedTimestamp.size() == 1);
298 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
299 for (unsigned long i=0; i< cpuCounters.size(); ++i)
300 {
301 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
302 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
303 }
304 sendCounterPacket.ClearTimestamps();
305
306 // Request combination of cpu & gpu counters with new period
307 period = 12222u;
308 periodicCounterSelectionCommandHandler(PacketWriter(period, {cpuCounters[0], gpuCounters[2],
309 gpuCounters[1], cpuCounters[1], gpuCounters[0]}));
310 periodicCounterCapture.Stop();
311
312 activeIds = holder.GetCaptureData().GetActiveBackends();
313 CHECK(activeIds.size() == 2);
314 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
315 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
316
317 recievedTimestamp = sendCounterPacket.GetTimestamps();
318 //
319 CHECK(recievedTimestamp[0].timestamp == period);
320 CHECK(recievedTimestamp[1].timestamp == period);
321
322 CHECK(recievedTimestamp.size() == 2);
323 CHECK(recievedTimestamp[0].counterValues.size() == 2);
324 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
325
326 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
327 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
328 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[1]);
329 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 2u);
330
331 for (unsigned long i=0; i< gpuCounters.size(); ++i)
332 {
333 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
334 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
335 }
336
337 sendCounterPacket.ClearTimestamps();
338
339 // Request all counters
340 std::vector<uint16_t> counterValues;
341 counterValues.insert(counterValues.begin(), cpuCounters.begin(), cpuCounters.end());
342 counterValues.insert(counterValues.begin(), gpuCounters.begin(), gpuCounters.end());
343
344 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
345 periodicCounterCapture.Stop();
346
347 activeIds = holder.GetCaptureData().GetActiveBackends();
348 CHECK(activeIds.size() == 2);
349 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
350 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
351
352 recievedTimestamp = sendCounterPacket.GetTimestamps();
353
354 CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
355 for (unsigned long i=0; i< cpuCounters.size(); ++i)
356 {
357 CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
358 CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
359 }
360
361 CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
362 for (unsigned long i=0; i< gpuCounters.size(); ++i)
363 {
364 CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
365 CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
366 }
367 sendCounterPacket.ClearTimestamps();
368
369 // Request random counters with duplicates and invalid counters
370 counterValues = {0, 0, 200, cpuCounters[2], gpuCounters[0],3 ,30, cpuCounters[0],cpuCounters[2], gpuCounters[1], 3,
371 90, 0, 30, gpuCounters[0], gpuCounters[0]};
372
373 periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
374 periodicCounterCapture.Stop();
375
376 activeIds = holder.GetCaptureData().GetActiveBackends();
377 CHECK(activeIds.size() == 2);
378 CHECK((activeIds.find(cpuAccId) != activeIds.end()));
379 CHECK((activeIds.find(gpuAccId) != activeIds.end()));
380
381 recievedTimestamp = sendCounterPacket.GetTimestamps();
382
383 CHECK(recievedTimestamp.size() == 2);
384
385 CHECK(recievedTimestamp[0].counterValues.size() == 2);
386
387 CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
388 CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
389 CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[2]);
390 CHECK(recievedTimestamp[0].counterValues[1].counterValue == 3u);
391
392 CHECK(recievedTimestamp[1].counterValues.size() == 2);
393
394 CHECK(recievedTimestamp[1].counterValues[0].counterId == gpuCounters[0]);
395 CHECK(recievedTimestamp[1].counterValues[0].counterValue == 1u);
396 CHECK(recievedTimestamp[1].counterValues[1].counterId == gpuCounters[1]);
397 CHECK(recievedTimestamp[1].counterValues[1].counterValue == 2u);
398
399 sendCounterPacket.ClearTimestamps();
400
401 // Request no counters
402 periodicCounterSelectionCommandHandler(PacketWriter(period, {}));
403 periodicCounterCapture.Stop();
404
405 activeIds = holder.GetCaptureData().GetActiveBackends();
406 CHECK(activeIds.size() == 0);
407
408 recievedTimestamp = sendCounterPacket.GetTimestamps();
409 CHECK(recievedTimestamp.size() == 0);
410
411 sendCounterPacket.ClearTimestamps();
412
413 // Request period of zero
414 periodicCounterSelectionCommandHandler(PacketWriter(0, counterValues));
415 periodicCounterCapture.Stop();
416
417 activeIds = holder.GetCaptureData().GetActiveBackends();
418 CHECK(activeIds.size() == 0);
419
420 recievedTimestamp = sendCounterPacket.GetTimestamps();
421 CHECK(recievedTimestamp.size() == 0);
422 }
423
424 TEST_CASE("TestBackendCounterLogging")
425 {
426 std::stringstream ss;
427
428 struct StreamRedirector
429 {
430 public:
StreamRedirectorStreamRedirector431 StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer)
432 : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer))
433 {}
434
~StreamRedirectorStreamRedirector435 ~StreamRedirector()
436 { m_Stream.rdbuf(m_BackupBuffer); }
437
438 private:
439 std::ostream &m_Stream;
440 std::streambuf *m_BackupBuffer;
441 };
442
443 Holder holder;
444 arm::pipe::PacketVersionResolver packetVersionResolver;
445 ProfilingStateMachine stateMachine;
446 ReadCounterVals readCounterVals;
447 StreamRedirector redirect(std::cout, ss.rdbuf());
448 CounterIdMap counterIdMap;
449 MockBackendSendCounterPacket sendCounterPacket;
450
451 const std::string cpuAccId(GetComputeDeviceAsCString(armnn::Compute::CpuAcc));
452 const std::string gpuAccId(GetComputeDeviceAsCString(armnn::Compute::GpuAcc));
453
454 ProfilingOptions options;
455 options.m_EnableProfiling = true;
456
457 armnn::ArmNNProfilingServiceInitialiser initialiser;
458 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
459 arm::pipe::MAX_ARMNN_COUNTER,
460 initialiser,
461 arm::pipe::ARMNN_SOFTWARE_INFO,
462 arm::pipe::ARMNN_SOFTWARE_VERSION,
463 arm::pipe::ARMNN_HARDWARE_VERSION);
464
465 std::unique_ptr<IBackendProfiling> cpuBackendProfilingPtr =
466 std::make_unique<BackendProfiling>(options, *profilingService.get(), cpuAccId);
467
468 std::shared_ptr<IBackendProfilingContext> cpuProfilingContextPtr =
469 std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
470
471 std::unordered_map<std::string,
472 std::shared_ptr<IBackendProfilingContext>> backendProfilingContexts;
473
474 uint16_t globalId = 5;
475 counterIdMap.RegisterMapping(globalId, 0, cpuAccId);
476 backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
477
478 PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
479 counterIdMap, backendProfilingContexts);
480
481 uint16_t maxArmnnCounterId = 4;
482
483 PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
484 4,
485 packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
486 backendProfilingContexts,
487 counterIdMap,
488 holder,
489 maxArmnnCounterId,
490 periodicCounterCapture,
491 readCounterVals,
492 sendCounterPacket,
493 stateMachine);
494
495 stateMachine.TransitionToState(ProfilingState::NotConnected);
496 stateMachine.TransitionToState(ProfilingState::WaitingForAck);
497 stateMachine.TransitionToState(ProfilingState::Active);
498
499 uint32_t period = 15939u;
500
501 arm::pipe::SetAllLoggingSinks(true, false, false);
502 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Warning);
503 periodicCounterSelectionCommandHandler(PacketWriter(period, {5}));
504 periodicCounterCapture.Stop();
505 arm::pipe::SetLogFilter(arm::pipe::LogSeverity::Fatal);
506
507 CHECK(ss.str().find("ActivateCounters example test error") != std::string::npos);
508 }
509
510 TEST_CASE("BackendProfilingContextGetSendTimelinePacket")
511 {
512 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
513
514 // Reset the profiling service to the uninitialized state
515 armnn::IRuntime::CreationOptions options;
516 options.m_ProfilingOptions.m_EnableProfiling = true;
517
518 armnn::ArmNNProfilingServiceInitialiser psInitialiser;
519 std::unique_ptr<IProfilingService> profilingService = arm::pipe::IProfilingService::CreateProfilingService(
520 arm::pipe::MAX_ARMNN_COUNTER,
521 psInitialiser,
522 arm::pipe::ARMNN_SOFTWARE_INFO,
523 arm::pipe::ARMNN_SOFTWARE_VERSION,
524 arm::pipe::ARMNN_HARDWARE_VERSION);
525
526 profilingService->ConfigureProfilingService(
527 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
528
529 armnn::MockBackendInitialiser initialiser;
530 // Create a runtime. During this the mock backend will be registered and context returned.
531 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
532 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
533 armnn::MockBackendProfilingContext* mockBackEndProfilingContext = mockProfilingService.GetContext();
534 // Check that there is a valid context set.
535 CHECK(mockBackEndProfilingContext);
536 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
537 mockBackEndProfilingContext->GetBackendProfiling();
538 CHECK(backendProfilingIface);
539
540 // Now for the meat of the test. We're just going to send a random packet and make sure there
541 // are no exceptions or errors. The sending of packets is already tested in SendTimelinePacketTests.
542 std::unique_ptr<ISendTimelinePacket> timelinePacket =
543 backendProfilingIface->GetSendTimelinePacket();
544 // Send TimelineEntityClassBinaryPacket
545 const uint64_t entityBinaryPacketProfilingGuid = 123456u;
546 timelinePacket->SendTimelineEntityBinaryPacket(entityBinaryPacketProfilingGuid);
547 timelinePacket->Commit();
548
549 // Reset the profiling servie after the test.
550 options.m_ProfilingOptions.m_EnableProfiling = false;
551 profilingService->ResetExternalProfilingOptions(
552 ConvertExternalProfilingOptions(options.m_ProfilingOptions), true);
553 }
554
555 TEST_CASE("GetProfilingGuidGenerator")
556 {
557 arm::pipe::LogLevelSwapper logLevelSwapper(arm::pipe::LogSeverity::Fatal);
558
559 // Reset the profiling service to the uninitialized state
560 armnn::IRuntime::CreationOptions options;
561 options.m_ProfilingOptions.m_EnableProfiling = true;
562
563 armnn::MockBackendInitialiser initialiser;
564 // Create a runtime. During this the mock backend will be registered and context returned.
565 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
566 armnn::MockBackendProfilingService mockProfilingService = armnn::MockBackendProfilingService::Instance();
567 armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
568 // Check that there is a valid context set.
569 CHECK(mockBackEndProfilingContext);
570 armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
571 mockBackEndProfilingContext->GetBackendProfiling();
572 CHECK(backendProfilingIface);
573
574 // Get the Guid generator and check the getting two Guid's results in the second being greater than the first.
575 IProfilingGuidGenerator& guidGenerator = backendProfilingIface->GetProfilingGuidGenerator();
576 const ProfilingDynamicGuid& firstGuid = guidGenerator.NextGuid();
577 const ProfilingDynamicGuid& secondGuid = guidGenerator.NextGuid();
578 CHECK(secondGuid > firstGuid);
579
580 // Reset the profiling servie after the test.
581 options.m_ProfilingOptions.m_EnableProfiling = false;
582 }
583
584 }
585