ArmNN
 21.11
BackendProfilingTests.cpp File Reference
#include "CounterDirectory.hpp"
#include "CounterIdMap.hpp"
#include "Holder.hpp"
#include "MockBackend.hpp"
#include "MockBackendId.hpp"
#include "PeriodicCounterCapture.hpp"
#include "PeriodicCounterSelectionCommandHandler.hpp"
#include "ProfilingStateMachine.hpp"
#include "ProfilingUtils.hpp"
#include "RequestCounterDirectoryCommandHandler.hpp"
#include <test/TestUtils.hpp>
#include <armnn/utility/IgnoreUnused.hpp>
#include <armnn/BackendId.hpp>
#include <armnn/Logging.hpp>
#include <armnn/profiling/ISendTimelinePacket.hpp>
#include <doctest/doctest.h>
#include <vector>
#include <cstdint>
#include <limits>
#include <backends/BackendProfiling.hpp>

Go to the source code of this file.

Functions

arm::pipe::Packet PacketWriter (uint32_t period, std::vector< uint16_t > countervalues)
 
 TEST_SUITE ("BackendProfilingTestSuite")
 

Function Documentation

◆ PacketWriter()

arm::pipe::Packet PacketWriter ( uint32_t  period,
std::vector< uint16_t >  countervalues 
)

Definition at line 95 of file BackendProfilingTests.cpp.

References armnn::profiling::WriteUint16(), and armnn::profiling::WriteUint32().

Referenced by TEST_SUITE().

96 {
97  const uint32_t packetId = 0x40000;
98  uint32_t offset = 0;
99  uint32_t dataLength = static_cast<uint32_t>(4 + countervalues.size() * 2);
100  std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
101  unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData.get());
102 
103  WriteUint32(data1, offset, period);
104  offset += 4;
105  for (auto countervalue : countervalues)
106  {
107  WriteUint16(data1, offset, countervalue);
108  offset += 2;
109  }
110 
111  return {packetId, dataLength, uniqueData};
112 }
void WriteUint16(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint16_t value)
void WriteUint32(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint32_t value)

◆ TEST_SUITE()

TEST_SUITE ( "BackendProfilingTestSuite"  )

Definition at line 114 of file BackendProfilingTests.cpp.

References armnn::profiling::Active, ProfilingService::ConfigureProfilingService(), armnn::CpuAcc, IRuntime::Create(), armnn::Fatal, MockBackendProfilingContext::GetBackendProfiling(), MockBackendProfilingService::GetContext(), ProfilingService::GetCounterMappings(), ICounterMappings::GetGlobalId(), armnn::GetProfilingService(), armnn::GpuAcc, MockBackendProfilingService::Instance(), IRuntime::CreationOptions::ExternalProfilingOptions::m_EnableProfiling, IRuntime::CreationOptions::m_ProfilingOptions, armnn::MockBackendId(), armnn::profiling::NotConnected, PacketWriter(), CounterIdMap::RegisterMapping(), ProfilingService::ResetExternalProfilingOptions(), armnn::SetAllLoggingSinks(), armnn::SetLogFilter(), ProfilingStateMachine::TransitionToState(), armnn::profiling::WaitingForAck, and armnn::Warning.

115 {
116 TEST_CASE("BackendProfilingCounterRegisterMockBackendTest")
117 {
118  // Reset the profiling service to the uninitialized state
120  options.m_ProfilingOptions.m_EnableProfiling = true;
121 
122  armnn::MockBackendInitialiser initialiser;
123  // Create a runtime
124  armnn::RuntimeImpl runtime(options);
125 
126  unsigned int shiftedId = 0;
127 
128  if (armnn::BackendRegistry().IsBackendRegistered("EthosNAcc"))
129  {
130  shiftedId = 4;
131  }
132 
133  // Check if the MockBackends 3 dummy counters {0, 1, 2-5 (four cores)} are registered
136  CHECK(counterMap.GetGlobalId(0, mockId) == 5 + shiftedId);
137  CHECK(counterMap.GetGlobalId(1, mockId) == 6 + shiftedId);
138  CHECK(counterMap.GetGlobalId(2, mockId) == 7 + shiftedId);
139  CHECK(counterMap.GetGlobalId(3, mockId) == 8 + shiftedId);
140  CHECK(counterMap.GetGlobalId(4, mockId) == 9 + shiftedId);
141  CHECK(counterMap.GetGlobalId(5, mockId) == 10 + shiftedId);
142  options.m_ProfilingOptions.m_EnableProfiling = false;
144 }
145 
146 TEST_CASE("TestBackendCounters")
147 {
148  Holder holder;
149  arm::pipe::PacketVersionResolver packetVersionResolver;
150  ProfilingStateMachine stateMachine;
151  ReadCounterVals readCounterVals;
152  CounterIdMap counterIdMap;
153  MockBackendSendCounterPacket sendCounterPacket;
154 
157 
159  options.m_ProfilingOptions.m_EnableProfiling = true;
160 
161  armnn::profiling::ProfilingService profilingService;
162 
163  std::unique_ptr<armnn::profiling::IBackendProfiling> cpuBackendProfilingPtr =
164  std::make_unique<BackendProfiling>(options, profilingService, cpuAccId);
165  std::unique_ptr<armnn::profiling::IBackendProfiling> gpuBackendProfilingPtr =
166  std::make_unique<BackendProfiling>(options, profilingService, gpuAccId);
167 
168  std::shared_ptr<armnn::profiling::IBackendProfilingContext> cpuProfilingContextPtr =
169  std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
170  std::shared_ptr<armnn::profiling::IBackendProfilingContext> gpuProfilingContextPtr =
171  std::make_shared<armnn::MockBackendProfilingContext>(gpuBackendProfilingPtr);
172 
173  std::unordered_map<armnn::BackendId,
174  std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContexts;
175 
176  backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
177  backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
178 
179  uint16_t globalId = 5;
180 
181  counterIdMap.RegisterMapping(globalId++, 0, cpuAccId);
182  counterIdMap.RegisterMapping(globalId++, 1, cpuAccId);
183  counterIdMap.RegisterMapping(globalId++, 2, cpuAccId);
184 
185  counterIdMap.RegisterMapping(globalId++, 0, gpuAccId);
186  counterIdMap.RegisterMapping(globalId++, 1, gpuAccId);
187  counterIdMap.RegisterMapping(globalId++, 2, gpuAccId);
188 
189  backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
190  backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr;
191 
192  PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
193  counterIdMap, backendProfilingContexts);
194 
195  uint16_t maxArmnnCounterId = 4;
196 
197  PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
198  4,
199  packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
200  backendProfilingContexts,
201  counterIdMap,
202  holder,
203  maxArmnnCounterId,
204  periodicCounterCapture,
205  readCounterVals,
206  sendCounterPacket,
207  stateMachine);
208 
209  stateMachine.TransitionToState(ProfilingState::NotConnected);
210  stateMachine.TransitionToState(ProfilingState::WaitingForAck);
211  stateMachine.TransitionToState(ProfilingState::Active);
212 
213  uint32_t period = 12345u;
214 
215  std::vector<uint16_t> cpuCounters{5, 6, 7};
216  std::vector<uint16_t> gpuCounters{8, 9, 10};
217 
218  // Request only gpu counters
219  periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters));
220  periodicCounterCapture.Stop();
221 
222  std::set<armnn::BackendId> activeIds = holder.GetCaptureData().GetActiveBackends();
223  CHECK(activeIds.size() == 1);
224  CHECK((activeIds.find(gpuAccId) != activeIds.end()));
225 
226  std::vector<Timestamp> recievedTimestamp = sendCounterPacket.GetTimestamps();
227 
228  CHECK(recievedTimestamp[0].timestamp == period);
229  CHECK(recievedTimestamp.size() == 1);
230  CHECK(recievedTimestamp[0].counterValues.size() == gpuCounters.size());
231  for (unsigned long i=0; i< gpuCounters.size(); ++i)
232  {
233  CHECK(recievedTimestamp[0].counterValues[i].counterId == gpuCounters[i]);
234  CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
235  }
236  sendCounterPacket.ClearTimestamps();
237 
238  // Request only cpu counters
239  periodicCounterSelectionCommandHandler(PacketWriter(period, cpuCounters));
240  periodicCounterCapture.Stop();
241 
242  activeIds = holder.GetCaptureData().GetActiveBackends();
243  CHECK(activeIds.size() == 1);
244  CHECK((activeIds.find(cpuAccId) != activeIds.end()));
245 
246  recievedTimestamp = sendCounterPacket.GetTimestamps();
247 
248  CHECK(recievedTimestamp[0].timestamp == period);
249  CHECK(recievedTimestamp.size() == 1);
250  CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
251  for (unsigned long i=0; i< cpuCounters.size(); ++i)
252  {
253  CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
254  CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
255  }
256  sendCounterPacket.ClearTimestamps();
257 
258  // Request combination of cpu & gpu counters with new period
259  period = 12222u;
260  periodicCounterSelectionCommandHandler(PacketWriter(period, {cpuCounters[0], gpuCounters[2],
261  gpuCounters[1], cpuCounters[1], gpuCounters[0]}));
262  periodicCounterCapture.Stop();
263 
264  activeIds = holder.GetCaptureData().GetActiveBackends();
265  CHECK(activeIds.size() == 2);
266  CHECK((activeIds.find(cpuAccId) != activeIds.end()));
267  CHECK((activeIds.find(gpuAccId) != activeIds.end()));
268 
269  recievedTimestamp = sendCounterPacket.GetTimestamps();
270 //
271  CHECK(recievedTimestamp[0].timestamp == period);
272  CHECK(recievedTimestamp[1].timestamp == period);
273 
274  CHECK(recievedTimestamp.size() == 2);
275  CHECK(recievedTimestamp[0].counterValues.size() == 2);
276  CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
277 
278  CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
279  CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
280  CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[1]);
281  CHECK(recievedTimestamp[0].counterValues[1].counterValue == 2u);
282 
283  for (unsigned long i=0; i< gpuCounters.size(); ++i)
284  {
285  CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
286  CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
287  }
288 
289  sendCounterPacket.ClearTimestamps();
290 
291  // Request all counters
292  std::vector<uint16_t> counterValues;
293  counterValues.insert(counterValues.begin(), cpuCounters.begin(), cpuCounters.end());
294  counterValues.insert(counterValues.begin(), gpuCounters.begin(), gpuCounters.end());
295 
296  periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
297  periodicCounterCapture.Stop();
298 
299  activeIds = holder.GetCaptureData().GetActiveBackends();
300  CHECK(activeIds.size() == 2);
301  CHECK((activeIds.find(cpuAccId) != activeIds.end()));
302  CHECK((activeIds.find(gpuAccId) != activeIds.end()));
303 
304  recievedTimestamp = sendCounterPacket.GetTimestamps();
305 
306  CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size());
307  for (unsigned long i=0; i< cpuCounters.size(); ++i)
308  {
309  CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]);
310  CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u);
311  }
312 
313  CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size());
314  for (unsigned long i=0; i< gpuCounters.size(); ++i)
315  {
316  CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]);
317  CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u);
318  }
319  sendCounterPacket.ClearTimestamps();
320 
321  // Request random counters with duplicates and invalid counters
322  counterValues = {0, 0, 200, cpuCounters[2], gpuCounters[0],3 ,30, cpuCounters[0],cpuCounters[2], gpuCounters[1], 3,
323  90, 0, 30, gpuCounters[0], gpuCounters[0]};
324 
325  periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues));
326  periodicCounterCapture.Stop();
327 
328  activeIds = holder.GetCaptureData().GetActiveBackends();
329  CHECK(activeIds.size() == 2);
330  CHECK((activeIds.find(cpuAccId) != activeIds.end()));
331  CHECK((activeIds.find(gpuAccId) != activeIds.end()));
332 
333  recievedTimestamp = sendCounterPacket.GetTimestamps();
334 
335  CHECK(recievedTimestamp.size() == 2);
336 
337  CHECK(recievedTimestamp[0].counterValues.size() == 2);
338 
339  CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]);
340  CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u);
341  CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[2]);
342  CHECK(recievedTimestamp[0].counterValues[1].counterValue == 3u);
343 
344  CHECK(recievedTimestamp[1].counterValues.size() == 2);
345 
346  CHECK(recievedTimestamp[1].counterValues[0].counterId == gpuCounters[0]);
347  CHECK(recievedTimestamp[1].counterValues[0].counterValue == 1u);
348  CHECK(recievedTimestamp[1].counterValues[1].counterId == gpuCounters[1]);
349  CHECK(recievedTimestamp[1].counterValues[1].counterValue == 2u);
350 
351  sendCounterPacket.ClearTimestamps();
352 
353  // Request no counters
354  periodicCounterSelectionCommandHandler(PacketWriter(period, {}));
355  periodicCounterCapture.Stop();
356 
357  activeIds = holder.GetCaptureData().GetActiveBackends();
358  CHECK(activeIds.size() == 0);
359 
360  recievedTimestamp = sendCounterPacket.GetTimestamps();
361  CHECK(recievedTimestamp.size() == 0);
362 
363  sendCounterPacket.ClearTimestamps();
364 
365  // Request period of zero
366  periodicCounterSelectionCommandHandler(PacketWriter(0, counterValues));
367  periodicCounterCapture.Stop();
368 
369  activeIds = holder.GetCaptureData().GetActiveBackends();
370  CHECK(activeIds.size() == 0);
371 
372  recievedTimestamp = sendCounterPacket.GetTimestamps();
373  CHECK(recievedTimestamp.size() == 0);
374 }
375 
376 TEST_CASE("TestBackendCounterLogging")
377 {
378  std::stringstream ss;
379 
380  struct StreamRedirector
381  {
382  public:
383  StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer)
384  : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer))
385  {}
386 
388  { m_Stream.rdbuf(m_BackupBuffer); }
389 
390  private:
391  std::ostream &m_Stream;
392  std::streambuf *m_BackupBuffer;
393  };
394 
395  Holder holder;
396  arm::pipe::PacketVersionResolver packetVersionResolver;
397  ProfilingStateMachine stateMachine;
398  ReadCounterVals readCounterVals;
399  StreamRedirector redirect(std::cout, ss.rdbuf());
400  CounterIdMap counterIdMap;
401  MockBackendSendCounterPacket sendCounterPacket;
402 
403  const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc);
404  const armnn::BackendId gpuAccId(armnn::Compute::GpuAcc);
405 
407  options.m_ProfilingOptions.m_EnableProfiling = true;
408 
409  armnn::profiling::ProfilingService profilingService;
410 
411  std::unique_ptr<armnn::profiling::IBackendProfiling> cpuBackendProfilingPtr =
412  std::make_unique<BackendProfiling>(options, profilingService, cpuAccId);
413 
414  std::shared_ptr<armnn::profiling::IBackendProfilingContext> cpuProfilingContextPtr =
415  std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr);
416 
417  std::unordered_map<armnn::BackendId,
418  std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContexts;
419 
420  uint16_t globalId = 5;
421  counterIdMap.RegisterMapping(globalId, 0, cpuAccId);
422  backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr;
423 
424  PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals,
425  counterIdMap, backendProfilingContexts);
426 
427  uint16_t maxArmnnCounterId = 4;
428 
429  PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0,
430  4,
431  packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
432  backendProfilingContexts,
433  counterIdMap,
434  holder,
435  maxArmnnCounterId,
436  periodicCounterCapture,
437  readCounterVals,
438  sendCounterPacket,
439  stateMachine);
440 
441  stateMachine.TransitionToState(ProfilingState::NotConnected);
442  stateMachine.TransitionToState(ProfilingState::WaitingForAck);
443  stateMachine.TransitionToState(ProfilingState::Active);
444 
445  uint32_t period = 15939u;
446 
447  armnn::SetAllLoggingSinks(true, false, false);
449  periodicCounterSelectionCommandHandler(PacketWriter(period, {5}));
450  periodicCounterCapture.Stop();
452 
453  CHECK(ss.str().find("ActivateCounters example test error") != std::string::npos);
454 }
455 
456 TEST_CASE("BackendProfilingContextGetSendTimelinePacket")
457 {
458  // Reset the profiling service to the uninitialized state
460  options.m_ProfilingOptions.m_EnableProfiling = true;
461  armnn::profiling::ProfilingService profilingService;
462  profilingService.ConfigureProfilingService(options.m_ProfilingOptions, true);
463 
464  armnn::MockBackendInitialiser initialiser;
465  // Create a runtime. During this the mock backend will be registered and context returned.
468  armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
469  // Check that there is a valid context set.
470  CHECK(mockBackEndProfilingContext);
471  armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
472  mockBackEndProfilingContext->GetBackendProfiling();
473  CHECK(backendProfilingIface);
474 
475  // Now for the meat of the test. We're just going to send a random packet and make sure there
476  // are no exceptions or errors. The sending of packets is already tested in SendTimelinePacketTests.
477  std::unique_ptr<armnn::profiling::ISendTimelinePacket> timelinePacket =
478  backendProfilingIface->GetSendTimelinePacket();
479  // Send TimelineEntityClassBinaryPacket
480  const uint64_t entityBinaryPacketProfilingGuid = 123456u;
481  timelinePacket->SendTimelineEntityBinaryPacket(entityBinaryPacketProfilingGuid);
482  timelinePacket->Commit();
483 
484  // Reset the profiling servie after the test.
485  options.m_ProfilingOptions.m_EnableProfiling = false;
486  profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true);
487 }
488 
489 TEST_CASE("GetProfilingGuidGenerator")
490 {
491  // Reset the profiling service to the uninitialized state
493  options.m_ProfilingOptions.m_EnableProfiling = true;
494 
495  armnn::MockBackendInitialiser initialiser;
496  // Create a runtime. During this the mock backend will be registered and context returned.
499  armnn::MockBackendProfilingContext *mockBackEndProfilingContext = mockProfilingService.GetContext();
500  // Check that there is a valid context set.
501  CHECK(mockBackEndProfilingContext);
502  armnn::IBackendInternal::IBackendProfilingPtr& backendProfilingIface =
503  mockBackEndProfilingContext->GetBackendProfiling();
504  CHECK(backendProfilingIface);
505 
506  // Get the Guid generator and check the getting two Guid's results in the second being greater than the first.
507  armnn::profiling::IProfilingGuidGenerator& guidGenerator = backendProfilingIface->GetProfilingGuidGenerator();
508  const armnn::profiling::ProfilingDynamicGuid& firstGuid = guidGenerator.NextGuid();
509  const armnn::profiling::ProfilingDynamicGuid& secondGuid = guidGenerator.NextGuid();
510  CHECK(secondGuid > firstGuid);
511 
512  // Reset the profiling servie after the test.
513  options.m_ProfilingOptions.m_EnableProfiling = false;
514 }
515 
516 }
profiling::ProfilingService & GetProfilingService(armnn::RuntimeImpl *runtime)
Definition: TestUtils.cpp:57
static IRuntimePtr Create(const CreationOptions &options)
Definition: Runtime.cpp:40
void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured)
Definition: Logging.cpp:142
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
Definition: IRuntime.hpp:31
constexpr const char * MockBackendId()
void RegisterMapping(uint16_t globalCounterId, uint16_t backendCounterId, const armnn::BackendId &backendId) override
bool m_EnableProfiling
Indicates whether external profiling is enabled or not.
Definition: IRuntime.hpp:169
std::unique_ptr< armnn::profiling::IBackendProfiling > IBackendProfilingPtr
void SetLogFilter(LogSeverity level)
Definition: Logging.cpp:24
const ICounterMappings & GetCounterMappings() const override
void ResetExternalProfilingOptions(const ExternalProfilingOptions &options, bool resetProfilingService=false)
GPU Execution: OpenCL: ArmCompute.
static MockBackendProfilingService & Instance()
arm::pipe::Packet PacketWriter(uint32_t period, std::vector< uint16_t > countervalues)
MockBackendProfilingContext * GetContext()
CPU Execution: NEON: ArmCompute.
void TransitionToState(ProfilingState newState)
IBackendInternal::IBackendProfilingPtr & GetBackendProfiling()
Definition: MockBackend.hpp:40
ExternalProfilingOptions m_ProfilingOptions
Definition: IRuntime.hpp:184
ProfilingState ConfigureProfilingService(const ExternalProfilingOptions &options, bool resetProfilingService=false)
virtual uint16_t GetGlobalId(uint16_t backendCounterId, const armnn::BackendId &backendId) const =0