ArmNN
 24.08
Profiling.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017,2024 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "Profiling.hpp"
6 
7 #include <armnn/BackendId.hpp>
9 
10 #include "JsonPrinter.hpp"
11 
12 #if ARMNN_STREAMLINE_ENABLED
13 #include <streamline_annotate.h>
14 #endif
15 
16 #include <algorithm>
17 #include <iomanip>
18 #include <iostream>
19 #include <fstream>
20 #include <map>
21 #include <stack>
22 
23 namespace armnn
24 {
25 
26 // Controls the amount of memory initially allocated to store profiling events.
27 // If chosen carefully, the profiling system will not make any additional allocations, thus minimizing its impact on
28 // measured times.
29 constexpr std::size_t g_ProfilingEventCountHint = 1024;
30 
31 // Whether profiling reports should include the sequence of events together with their timings.
32 constexpr bool g_WriteProfilingEventSequence = true;
33 
34 // Whether profiling reports should also report detailed information on events grouped by inference.
35 // This can spam the output stream, so use carefully (or adapt the code to just output information
36 // of interest).
38 
39 // Whether a call to Profiler::AnalyzeEventsAndWriteResults() will be made when the Profiler is destroyed.
40 // It can be convenient for local tests.
42 
43 Measurement FindMeasurement(const std::string& name, const Event* event)
44 {
45 
46  ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(event, "event should not be null.");
47 
48  // Search though the measurements.
49  for (const auto& measurement : event->GetMeasurements())
50  {
51  if (measurement.m_Name == name)
52  {
53  // Measurement found.
54  return measurement;
55  }
56  }
57 
58  // Measurement not found.
59  return Measurement{ "", 0.f, Measurement::Unit::TIME_MS };
60 }
61 
62 std::vector<Measurement> FindKernelMeasurements(const Event* event)
63 {
64  ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(event, "event should not be null.");
65 
66  std::vector<Measurement> measurements;
67 
68  // Search through the measurements.
69  for (const auto& measurement : event->GetMeasurements())
70  {
71  if (measurement.m_Name.rfind("OpenClKernelTimer", 0) == 0
72  || measurement.m_Name.rfind("NeonKernelTimer", 0) == 0)
73  {
74  // Measurement found.
75  measurements.push_back(measurement);
76  }
77  }
78 
79  return measurements;
80 }
81 
82 std::map<std::string, ProfilerImpl::ProfilingEventStats> ProfilerImpl::CalculateProfilingEventStats() const
83 {
84  std::map<std::string, ProfilingEventStats> nameToStatsMap;
85 
86  for (const auto& event : m_EventSequence)
87  {
89 
90  double durationMs = measurement.m_Value;
91  auto it = nameToStatsMap.find(event->GetName());
92  if (it != nameToStatsMap.end())
93  {
94  ProfilingEventStats& stats = it->second;
95  stats.m_TotalMs += durationMs;
96  stats.m_MinMs = std::min(stats.m_MinMs, durationMs);
97  stats.m_MaxMs = std::max(stats.m_MaxMs, durationMs);
98  ++stats.m_Count;
99  }
100  else
101  {
102  nameToStatsMap.emplace(event->GetName(), ProfilingEventStats{ durationMs, durationMs, durationMs, 1 });
103  }
104  }
105 
106  return nameToStatsMap;
107 }
108 
109 const Event* GetEventPtr(const Event* ptr) { return ptr;}
110 const Event* GetEventPtr(const std::unique_ptr<Event>& ptr) {return ptr.get(); }
111 
112 template<typename ItertType>
113 void ProfilerImpl::AnalyzeEventSequenceAndWriteResults(ItertType first, ItertType last, std::ostream& outStream) const
114 {
115  // Outputs event sequence, if needed.
117  {
118  // Makes sure timestamps are output with 6 decimals, and save old settings.
119  std::streamsize oldPrecision = outStream.precision();
120  outStream.precision(6);
121  std::ios_base::fmtflags oldFlags = outStream.flags();
122  outStream.setf(std::ios::fixed);
123  // Outputs fields.
124  outStream << "Event Sequence - Name | Duration (ms) | Start (ms) | Stop (ms) | Device" << std::endl;
125  for (auto event = first; event != last; ++event)
126  {
127  const Event* eventPtr = GetEventPtr((*event));
128  double startTimeMs = FindMeasurement(WallClockTimer::WALL_CLOCK_TIME_START, eventPtr).m_Value;
129  double stopTimeMs = FindMeasurement(WallClockTimer::WALL_CLOCK_TIME_STOP, eventPtr).m_Value;
130 
131  // Find the WallClock measurement if there is one.
132  double durationMs = FindMeasurement(WallClockTimer::WALL_CLOCK_TIME, eventPtr).m_Value;
133  outStream << std::setw(50) << eventPtr->GetName() << " "
134  << std::setw(20) << durationMs
135  << std::setw(20) << startTimeMs
136  << std::setw(20) << stopTimeMs
137  << std::setw(20) << eventPtr->GetBackendId().Get()
138  << std::endl;
139  }
140  outStream << std::endl;
141  // Restores previous precision settings.
142  outStream.flags(oldFlags);
143  outStream.precision(oldPrecision);
144  }
145 
146  // Aggregates results per event name.
147  std::map<std::string, ProfilingEventStats> nameToStatsMap = CalculateProfilingEventStats();
148 
149  // Outputs aggregated stats.
150  outStream << "Event Stats - Name | Avg (ms) | Min (ms) | Max (ms) | Total (ms) | Count" << std::endl;
151  for (const auto& pair : nameToStatsMap)
152  {
153  const std::string& eventLabel = pair.first;
154  const ProfilingEventStats& eventStats = pair.second;
155  const double avgMs = eventStats.m_TotalMs / double(eventStats.m_Count);
156 
157  outStream << "\t" << std::setw(50) << eventLabel << " " << std::setw(9) << avgMs << " "
158  << std::setw(9) << eventStats.m_MinMs << " " << std::setw(9) << eventStats.m_MaxMs << " "
159  << std::setw(9) << eventStats.m_TotalMs << " " << std::setw(9) << eventStats.m_Count << std::endl;
160  }
161  outStream << std::endl;
162 }
163 
165  : m_ProfilingEnabled(false),
166  m_DetailsToStdOutMethod(ProfilingDetailsMethod::Undefined)
167 {
169 
170 #if ARMNN_STREAMLINE_ENABLED
171  // Initialises streamline annotations.
172  ANNOTATE_SETUP;
173 #endif
174 }
175 
177 {
178  if (m_ProfilingEnabled)
179  {
181  {
182  Print(std::cout);
183  }
184  }
185 
186  // Un-register this profiler from the current thread.
188 }
189 
191 {
192  return m_ProfilingEnabled;
193 }
194 
195 void ProfilerImpl::EnableProfiling(bool enableProfiling)
196 {
197  m_ProfilingEnabled = enableProfiling;
198 }
199 
201 {
202  m_DetailsToStdOutMethod = details;
203 }
204 
206  const BackendId& backendId,
207  const std::string& label,
208  std::vector<InstrumentPtr>&& instruments,
210 {
211  Event* parent = m_Parents.empty() ? nullptr : m_Parents.top();
212  m_EventSequence.push_back(std::make_unique<Event>(label,
213  profiler,
214  parent,
215  backendId,
216  std::move(instruments),
217  guid));
218  Event* event = m_EventSequence.back().get();
219  event->Start();
220 
221 #if ARMNN_STREAMLINE_ENABLED
222  ANNOTATE_CHANNEL_COLOR(uint32_t(m_Parents.size()), GetEventColor(backendId), label.c_str());
223 #endif
224 
225  m_Parents.push(event);
226  return event;
227 }
228 
230 {
231  event->Stop();
232 
233  if (!!m_Parents.empty())
234  {
235  throw armnn::Exception("m_Parents must not be empty.");
236  }
237 
238  if (event != m_Parents.top())
239  {
240  throw armnn::Exception("event must match the top of m_Parents.");
241  }
242 
243  m_Parents.pop();
244 
245  Event* parent = m_Parents.empty() ? nullptr : m_Parents.top();
246 
247  if (event->GetParentEvent() != parent)
248  {
249  throw armnn::Exception("parent events must match.");
250  }
251 
252 #if ARMNN_STREAMLINE_ENABLED
253  ANNOTATE_CHANNEL_END(uint32_t(m_Parents.size()));
254 #endif
255 }
256 
257 int CalcLevel(const Event* eventPtr)
258 {
259  int level = 0;
260  while (eventPtr != nullptr)
261  {
262  eventPtr = eventPtr->GetParentEvent();
263  level++;
264  }
265  return level;
266 }
267 
268 void ProfilerImpl::PopulateParent(std::vector<const Event*>& outEvents, int& outBaseLevel, std::string parentName) const
269 {
270  outEvents.reserve(m_EventSequence.size());
271  for (const auto& event : m_EventSequence)
272  {
273  const Event* eventPtrRaw = event.get();
274  if (eventPtrRaw->GetName() == parentName)
275  {
276  outBaseLevel = (outBaseLevel == -1) ? CalcLevel(eventPtrRaw) : outBaseLevel;
277  outEvents.push_back(eventPtrRaw);
278  }
279  }
280 }
281 
282 void ProfilerImpl::PopulateDescendants(std::map<const Event*, std::vector<const Event*>>& outDescendantsMap) const
283 {
284  for (const auto& event : m_EventSequence)
285  {
286  const Event* eventPtrRaw = event.get();
287  const Event* parent = eventPtrRaw->GetParentEvent();
288 
289  if (!parent)
290  {
291  continue;
292  }
293 
294  auto it = outDescendantsMap.find(parent);
295  if (it == outDescendantsMap.end())
296  {
297  outDescendantsMap.emplace(parent, std::vector<const Event*>({ eventPtrRaw }));
298  }
299  else
300  {
301  it->second.push_back(eventPtrRaw);
302  }
303  }
304 }
305 
307  std::string layerDetailsStr)
308 {
310  detailsObject.SetAndParseDetails(layerDetailsStr);
311 
312 }
313 
314 void ExtractJsonObjects(unsigned int inferenceIndex,
315  const Event* parentEvent,
316  JsonChildObject& parentObject,
317  std::map<const Event*, std::vector<const Event*>> descendantsMap)
318 {
319  ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(parentEvent, "parentEvent must not be null.");
320 
321  // If profiling GUID is entered, process it
322  if (parentEvent->GetProfilingGuid().has_value())
323  {
324  arm::pipe::ProfilingGuid profilingGuid;
325  profilingGuid = parentEvent->GetProfilingGuid().value();
326  parentObject.SetGuid(profilingGuid);
327  }
328  std::vector<Measurement> instrumentMeasurements = parentEvent->GetMeasurements();
329  unsigned int childIdx = 0;
330  unsigned int numSkippedKernels = 0;
331  if (inferenceIndex > 0)
332  {
333  for (auto &i: parentEvent->GetInstruments())
334  {
335  if (i->HasKernelMeasurements())
336  {
337  numSkippedKernels = static_cast<unsigned int>(parentObject.m_Children.size() -
338  instrumentMeasurements.size());
339  childIdx = numSkippedKernels;
340  }
341  }
342  }
343 
344  for (size_t measurementIndex = 0; measurementIndex < instrumentMeasurements.size(); ++measurementIndex, ++childIdx)
345  {
346  if (inferenceIndex == 0)
347  {
348  // Only add kernel measurement once, in case of multiple inferences
349  JsonChildObject measurementObject{ instrumentMeasurements[measurementIndex].m_Name };
350  measurementObject.SetUnit(instrumentMeasurements[measurementIndex].m_Unit);
351  measurementObject.SetType(JsonObjectType::Measurement);
352 
353  if (parentObject.NumChildren() != childIdx)
354  {
355  throw armnn::Exception("parentObject must have the same number of children as childIdx.");
356  }
357  parentObject.AddChild(measurementObject);
358  }
359  else
360  {
361  if (numSkippedKernels > 0)
362  {
363  parentObject.GetChild(--numSkippedKernels).AddMeasurement(0.0);
364  }
365  }
366 
367  parentObject.GetChild(childIdx).AddMeasurement(instrumentMeasurements[measurementIndex].m_Value);
368  }
369 
370  auto childEventsIt = descendantsMap.find(parentEvent);
371  if (childEventsIt != descendantsMap.end())
372  {
373  for (auto childEvent : childEventsIt->second)
374  {
375  if (inferenceIndex == 0)
376  {
377  // Only add second level once, in case of multiple inferences
378  JsonChildObject childObject{ childEvent->GetName() };
379  childObject.SetType(JsonObjectType::Event);
380  parentObject.AddChild(childObject);
381  }
382 
383  // It's possible that childIdx can overrun the parents' child vector. Check before we try to process a
384  // non-existent child.
385  if (childIdx < parentObject.NumChildren())
386  {
387  // Recursively process children.
388  ExtractJsonObjects(inferenceIndex, childEvent, parentObject.GetChild(childIdx), descendantsMap);
389  childIdx++;
390  }
391  }
392  }
393 }
394 
395 void ProfilerImpl::Print(std::ostream& outStream) const
396 {
397  // Makes sure timestamps are output with 6 decimals, and save old settings.
398  std::streamsize oldPrecision = outStream.precision();
399  outStream.precision(6);
400  std::ios_base::fmtflags oldFlags = outStream.flags();
401  outStream.setf(std::ios::fixed);
402  JsonPrinter printer(outStream);
403 
404  // First find all the parent Events and print out duration measurements.
405  int baseLevel = -1;
406 
407  std::vector<const Event*> optimizations;
408  PopulateParent(optimizations, baseLevel, "Optimizer");
409 
410  std::vector<const Event*> loadedNetworks;
411  PopulateParent(loadedNetworks, baseLevel, "LoadedNetwork");
412 
413  std::vector<const Event*> inferences;
414  PopulateParent(inferences, baseLevel, "EnqueueWorkload");
415 
416  // Second map out descendants hierarchy
417  std::map<const Event*, std::vector<const Event*>> descendantsMap;
418  PopulateDescendants(descendantsMap);
419 
420  // Extract json objects for each parent event type
421  JsonChildObject optimizeObject{ "optimize_measurements" };
422 
423  for (unsigned int optimizeIndex = 0; optimizeIndex < optimizations.size(); ++optimizeIndex)
424  {
425  auto optimization = optimizations[optimizeIndex];
426  ExtractJsonObjects(optimizeIndex, optimization, optimizeObject, descendantsMap);
427  }
428 
429  JsonChildObject loadedNetworkObject{ "loaded_network_measurements" };
430 
431  for (unsigned int loadedNetworkIndex = 0; loadedNetworkIndex < loadedNetworks.size(); ++loadedNetworkIndex)
432  {
433  auto loadedNetwork = loadedNetworks[loadedNetworkIndex];
434  ExtractJsonObjects(loadedNetworkIndex, loadedNetwork, loadedNetworkObject, descendantsMap);
435  }
436 
437  JsonChildObject inferenceObject{ "inference_measurements" };
438 
439  for (unsigned int inferenceIndex = 0; inferenceIndex < inferences.size(); ++inferenceIndex)
440  {
441  auto inference = inferences[inferenceIndex];
442  ExtractJsonObjects(inferenceIndex, inference, inferenceObject, descendantsMap);
443  }
444 
445  printer.PrintHeader();
446  printer.PrintArmNNHeader();
447 
448  if (m_ProfilingDetails.get()->DetailsExist() &&
451  {
452  JsonChildObject detailsObject{ "layer_details" };
454  {
455  detailsObject.EnableDetailsOnly();
456  }
457  detailsObject.SetType(JsonObjectType::ExecObjectDesc);
458  detailsObject.SetAndParseDetails(m_ProfilingDetails.get()->GetProfilingDetails());
459 
460  size_t id = 0;
461  printer.PrintJsonChildObject(detailsObject, id);
462  }
463 
464  // print inference object, also prints child layer and kernel measurements
465  size_t id = 0;
467  {
468  printer.PrintJsonChildObject(optimizeObject, id);
469  printer.PrintSeparator();
470  printer.PrintNewLine();
471  printer.PrintJsonChildObject(loadedNetworkObject, id);
472  printer.PrintSeparator();
473  printer.PrintNewLine();
474  printer.PrintJsonChildObject(inferenceObject, id);
475  printer.PrintNewLine();
476  }
477  // end of ArmNN
478  printer.PrintFooter();
479 
480  // end of main JSON object
481  printer.PrintNewLine();
482  printer.PrintFooter();
483  printer.PrintNewLine();
484 
485  // Restores previous precision settings.
486  outStream.flags(oldFlags);
487  outStream.precision(oldPrecision);
488 
489 }
490 void ProfilerImpl::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
491 {
492  // Stack should be empty now.
493  const bool saneMarkerSequence = m_Parents.empty();
494 
495  // Abort if the sequence of markers was found to have incorrect information:
496  // The stats cannot be trusted.
497  if (!saneMarkerSequence)
498  {
499  outStream << "Cannot write profiling stats. "
500  "Unexpected errors were found when analyzing the sequence of logged events, "
501  "which may lead to plainly wrong stats. The profiling system may contain implementation "
502  "issues or could have been used in an unsafe manner." << std::endl;
503  return;
504  }
505 
506  // Analyzes the full sequence of events.
508  m_EventSequence.cend(),
509  outStream);
510 
511  // Aggregates events by tag if requested (spams the output stream if done for all tags).
513  {
514  outStream << std::endl;
515  outStream << "***" << std::endl;
516  outStream << "*** Per Inference Stats" << std::endl;
517  outStream << "***" << std::endl;
518  outStream << std::endl;
519 
520  int baseLevel = -1;
521  std::vector<const Event*> inferences;
522  PopulateParent(inferences, baseLevel, "EnqueueWorkload");
523 
524  // Second map out descendants hierarchy
525  std::map<const Event*, std::vector<const Event*>> descendantsMap;
526  PopulateDescendants(descendantsMap);
527 
528  std::function<void(const Event*, std::vector<const Event*>&)>
529  FindDescendantEvents = [&](const Event* eventPtr, std::vector<const Event*>& sequence)
530  {
531  sequence.push_back(eventPtr);
532 
533  if (CalcLevel(eventPtr) > baseLevel+2) //We only care about levels as deep as workload executions.
534  {
535  return;
536  }
537 
538  auto children = descendantsMap.find(eventPtr);
539  if (children == descendantsMap.end())
540  {
541  return;
542  }
543 
544  if (!(children->second.empty()))
545  {
546  return FindDescendantEvents(children->second[0], sequence);
547  }
548  };
549 
550  // Third, find events belonging to each inference
551  int inferenceIdx = 0;
552  for (auto inference : inferences)
553  {
554  std::vector<const Event*> sequence;
555 
556  //build sequence, depth first
557  FindDescendantEvents(inference, sequence);
558 
559  outStream << "> Begin Inference: " << inferenceIdx << std::endl;
560  outStream << std::endl;
561  AnalyzeEventSequenceAndWriteResults(sequence.cbegin(),
562  sequence.cend(),
563  outStream);
564  outStream << std::endl;
565  outStream << "> End Inference: " << inferenceIdx << std::endl;
566 
567  inferenceIdx++;
568  }
569  }
570 }
571 
572 std::uint32_t ProfilerImpl::GetEventColor(const BackendId& backendId) const
573 {
574  static BackendId cpuRef("CpuRef");
575  static BackendId cpuAcc("CpuAcc");
576  static BackendId gpuAcc("GpuAcc");
577  if (backendId == cpuRef)
578  {
579  // Cyan
580  return 0xffff001b;
581  }
582  else if (backendId == cpuAcc)
583  {
584  // Green
585  return 0x00ff001b;
586  }
587  else if (backendId == gpuAcc)
588  {
589  // Purple
590  return 0xff007f1b;
591  }
592  else
593  {
594  // Dark gray
595  return 0x5555551b;
596  }
597 }
598 
599 // The thread_local pointer to the profiler instance.
600 thread_local IProfiler* tl_Profiler = nullptr;
601 
603 {
604  // Global reference to the single ProfileManager instance allowed.
605  static ProfilerManager s_ProfilerManager;
606  return s_ProfilerManager;
607 }
608 
610 {
611  tl_Profiler = profiler;
612 }
613 
615 {
616  return tl_Profiler;
617 }
618 
619 void IProfiler::EnableProfiling(bool enableProfiling)
620 {
621  pProfilerImpl->EnableProfiling(enableProfiling);
622 }
623 
625 {
626  pProfilerImpl->EnableNetworkDetailsToStdOut(detailsMethod);
627 }
628 
630 {
631  return pProfilerImpl->IsProfilingEnabled();
632 }
633 
634 void IProfiler::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
635 {
636  pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
637 }
638 
639 void IProfiler::Print(std::ostream& outStream) const
640 {
641  pProfilerImpl->Print(outStream);
642 }
643 
644 Event* IProfiler::BeginEvent(const BackendId& backendId,
645  const std::string& label,
646  std::vector<InstrumentPtr>&& instruments,
648 {
649  return pProfilerImpl->BeginEvent(this, backendId, label, std::move(instruments), guid);
650 }
651 
652 IProfiler::~IProfiler() = default;
653 IProfiler::IProfiler() : pProfilerImpl(new ProfilerImpl())
654 {};
655 
656 } // namespace armnn
armnn::Measurement::m_Value
double m_Value
Definition: Instrument.hpp:43
armnn::CalcLevel
int CalcLevel(const Event *eventPtr)
Definition: Profiling.cpp:257
armnn::Compute::Undefined
@ Undefined
armnn::Event::GetName
const std::string & GetName() const
Get the name of the event.
Definition: ProfilingEvent.cpp:74
armnn::ProfilerImpl::m_Parents
std::stack< Event * > m_Parents
Definition: Profiling.hpp:101
armnn::Optional< arm::pipe::ProfilingGuid >
armnn::ProfilerImpl
Definition: Profiling.hpp:29
armnn::JsonChildObject::AddChild
void AddChild(const JsonChildObject &childObject)
Definition: JsonPrinter.hpp:59
armnn::ProfilerManager::RegisterProfiler
void RegisterProfiler(IProfiler *profiler)
Definition: Profiling.cpp:609
armnn::ProfilerImpl::EnableProfiling
void EnableProfiling(bool enableProfiling)
Definition: Profiling.cpp:195
armnn::JsonUtils::PrintNewLine
void PrintNewLine()
Definition: JsonUtils.hpp:46
armnn::WallClockTimer::WALL_CLOCK_TIME_STOP
static const std::string WALL_CLOCK_TIME_STOP
Definition: WallClockTimer.hpp:65
armnn::ProfilerImpl::m_EventSequence
std::vector< EventPtr > m_EventSequence
Definition: Profiling.hpp:102
armnn::Event::GetParentEvent
const Event * GetParentEvent() const
Get the pointer of the parent event.
Definition: ProfilingEvent.cpp:84
armnn::ProfilerImpl::ProfilingEventStats::m_MinMs
double m_MinMs
Definition: Profiling.hpp:89
armnn::JsonObjectType::Measurement
@ Measurement
armnn::ProfilerImpl::EndEvent
void EndEvent(Event *event)
Definition: Profiling.cpp:229
armnn::FindKernelMeasurements
std::vector< Measurement > FindKernelMeasurements(const Event *event)
Definition: Profiling.cpp:62
BackendId.hpp
armnn::JsonChildObject::SetUnit
void SetUnit(const Measurement::Unit unit)
Definition: JsonPrinter.hpp:69
armnn::JsonChildObject::SetAndParseDetails
void SetAndParseDetails(std::string layerDetailsStr)
Definition: JsonPrinter.hpp:44
Profiling.hpp
armnn::IProfiler::IProfiler
IProfiler()
Definition: Profiling.cpp:653
armnn::IProfiler::IsProfilingEnabled
bool IsProfilingEnabled()
Checks whether profiling is enabled.
Definition: Profiling.cpp:629
armnn::GetEventPtr
const Event * GetEventPtr(const Event *ptr)
Definition: Profiling.cpp:109
armnn::ProfilerManager
Definition: Profiling.hpp:111
armnn::ProfilerImpl::CalculateProfilingEventStats
std::map< std::string, ProfilingEventStats > CalculateProfilingEventStats() const
Definition: Profiling.cpp:82
armnn::IProfiler::~IProfiler
~IProfiler()
armnn::ProfilerImpl::ProfilingEventStats::m_Count
uint32_t m_Count
Definition: Profiling.hpp:91
armnn::JsonChildObject::AddMeasurement
void AddMeasurement(const double measurement)
Definition: JsonPrinter.hpp:39
armnn::Event::GetMeasurements
const std::vector< Measurement > GetMeasurements() const
Get the recorded measurements calculated between Start() and Stop()
Definition: ProfilingEvent.cpp:56
armnn::JsonUtils::PrintArmNNHeader
void PrintArmNNHeader()
Definition: JsonUtils.hpp:64
armnn::ProfilerImpl::ProfilerImpl
ProfilerImpl()
Definition: Profiling.cpp:164
armnn::ProfilerImpl::IsProfilingEnabled
bool IsProfilingEnabled()
Definition: Profiling.cpp:190
armnn::ProfilerImpl::PopulateParent
void PopulateParent(std::vector< const Event * > &outEvents, int &outBaseLevel, std::string parentName) const
Definition: Profiling.cpp:268
armnn::ProfilerImpl::EnableNetworkDetailsToStdOut
void EnableNetworkDetailsToStdOut(ProfilingDetailsMethod detailsMethod)
Definition: Profiling.cpp:200
armnn::ProfilerImpl::m_ProfilingEnabled
bool m_ProfilingEnabled
Definition: Profiling.hpp:104
Assert.hpp
armnn::ConfigureDetailsObject
void ConfigureDetailsObject(JsonChildObject &detailsObject, std::string layerDetailsStr)
Definition: Profiling.cpp:306
armnn::Event::GetProfilingGuid
Optional< arm::pipe::ProfilingGuid > GetProfilingGuid() const
Get the associated profiling GUID if the event is a workload.
Definition: ProfilingEvent.cpp:94
armnn::tl_Profiler
thread_local IProfiler * tl_Profiler
Definition: Profiling.cpp:600
armnn::JsonChildObject::GetChild
JsonChildObject & GetChild(const unsigned int index)
Definition: JsonPrinter.hpp:64
armnn::g_AggregateProfilingEventsByInference
constexpr bool g_AggregateProfilingEventsByInference
Definition: Profiling.cpp:37
armnn::ProfilerImpl::ProfilingEventStats::m_TotalMs
double m_TotalMs
Definition: Profiling.hpp:88
armnn::IProfiler::EnableProfiling
void EnableProfiling(bool enableProfiling)
Enables/disables profiling for this profiler.
Definition: Profiling.cpp:619
armnn::WallClockTimer::WALL_CLOCK_TIME
static const std::string WALL_CLOCK_TIME
Definition: WallClockTimer.hpp:63
armnn::BackendId::Get
const std::string & Get() const
Definition: BackendId.hpp:138
armnn::Event
Event class records measurements reported by BeginEvent()/EndEvent() and returns measurements when Ev...
Definition: ProfilingEvent.hpp:27
armnn::Event::GetInstruments
const std::vector< InstrumentPtr > & GetInstruments() const
Get the Instruments used by this Event.
Definition: ProfilingEvent.cpp:69
armnn::ProfilingDetailsMethod
ProfilingDetailsMethod
Define the behaviour of the internal profiler when outputting network details.
Definition: Types.hpp:71
armnn::FindMeasurement
Measurement FindMeasurement(const std::string &name, const Event *event)
Definition: Profiling.cpp:43
armnn::ProfilerImpl::Print
void Print(std::ostream &outStream) const
Definition: Profiling.cpp:395
armnn::JsonChildObject::SetType
void SetType(JsonObjectType type)
Definition: JsonPrinter.hpp:79
armnn::Exception
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
armnn::IProfiler::AnalyzeEventsAndWriteResults
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
Analyzes the tracked events and writes the results to the given output stream.
Definition: Profiling.cpp:634
armnn::g_WriteProfilingEventSequence
constexpr bool g_WriteProfilingEventSequence
Definition: Profiling.cpp:32
armnn::Measurement
Definition: Instrument.hpp:14
armnn::ProfilerImpl::m_DetailsToStdOutMethod
ProfilingDetailsMethod m_DetailsToStdOutMethod
Definition: Profiling.hpp:105
armnn::ProfilerImpl::GetEventColor
uint32_t GetEventColor(const BackendId &backendId) const
Definition: Profiling.cpp:572
armnn::JsonObjectType::ExecObjectDesc
@ ExecObjectDesc
armnn::ProfilerImpl::~ProfilerImpl
~ProfilerImpl()
Definition: Profiling.cpp:176
armnn::JsonObjectType::Event
@ Event
armnn::ExtractJsonObjects
void ExtractJsonObjects(unsigned int inferenceIndex, const Event *parentEvent, JsonChildObject &parentObject, std::map< const Event *, std::vector< const Event * >> descendantsMap)
Definition: Profiling.cpp:314
armnn::ProfilingDetailsMethod::DetailsOnly
@ DetailsOnly
armnn::g_WriteReportToStdOutOnProfilerDestruction
constexpr bool g_WriteReportToStdOutOnProfilerDestruction
Definition: Profiling.cpp:41
armnn::ProfilerManager::GetInstance
static ProfilerManager & GetInstance()
Definition: Profiling.cpp:602
armnn::ProfilerImpl::BeginEvent
Event * BeginEvent(armnn::IProfiler *profiler, const BackendId &backendId, const std::string &name, std::vector< InstrumentPtr > &&instruments, const Optional< arm::pipe::ProfilingGuid > &guid)
Definition: Profiling.cpp:205
armnn::JsonChildObject::SetGuid
void SetGuid(arm::pipe::ProfilingGuid guid)
Definition: JsonPrinter.hpp:54
armnn::JsonChildObject::m_Children
std::vector< JsonChildObject > m_Children
Definition: JsonPrinter.hpp:107
armnn::ProfilerImpl::AnalyzeEventsAndWriteResults
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
Definition: Profiling.cpp:490
armnn::ProfilerImpl::PopulateDescendants
void PopulateDescendants(std::map< const Event *, std::vector< const Event * >> &outDescendantsMap) const
Definition: Profiling.cpp:282
armnn::BackendId
Definition: BackendId.hpp:75
armnn::JsonChildObject::NumChildren
size_t NumChildren() const
Definition: JsonPrinter.hpp:74
armnn::JsonUtils::PrintHeader
void PrintHeader()
Definition: JsonUtils.hpp:58
armnn::ProfilerImpl::ProfilingEventStats::m_MaxMs
double m_MaxMs
Definition: Profiling.hpp:90
armnn::ProfilingDetailsMethod::DetailsWithEvents
@ DetailsWithEvents
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::IProfiler::Print
void Print(std::ostream &outStream) const
Print stats for events in JSON Format to the given output stream.
Definition: Profiling.cpp:639
armnn::JsonPrinter
Definition: JsonPrinter.hpp:114
armnn::ProfilerImpl::ProfilingEventStats
Definition: Profiling.hpp:86
armnn::IProfiler
Definition: IProfiler.hpp:21
armnn::ProfilerImpl::AnalyzeEventSequenceAndWriteResults
void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream &outStream) const
armnn::JsonUtils::PrintFooter
void PrintFooter()
Definition: JsonUtils.hpp:51
armnn::JsonUtils::PrintSeparator
void PrintSeparator()
Definition: JsonUtils.hpp:70
armnn::IProfiler::EnableNetworkDetailsToStdOut
void EnableNetworkDetailsToStdOut(ProfilingDetailsMethod detailsMethod)
Print out details of each layer within the network that possesses a descriptor.
Definition: Profiling.cpp:624
armnn::g_ProfilingEventCountHint
constexpr std::size_t g_ProfilingEventCountHint
Definition: Profiling.cpp:29
armnn::WallClockTimer::WALL_CLOCK_TIME_START
static const std::string WALL_CLOCK_TIME_START
Definition: WallClockTimer.hpp:64
armnn::JsonPrinter::PrintJsonChildObject
void PrintJsonChildObject(const JsonChildObject &object, size_t &id)
Definition: JsonPrinter.cpp:15
armnn::Event::GetBackendId
BackendId GetBackendId() const
Get the backend id of the event.
Definition: ProfilingEvent.cpp:89
armnn::JsonChildObject::EnableDetailsOnly
void EnableDetailsOnly()
Definition: JsonPrinter.hpp:89
JsonPrinter.hpp
armnn::OptionalReferenceSwitch::value
const T & value() const
Definition: Optional.hpp:146
armnn::ProfilerImpl::m_ProfilingDetails
DescPtr m_ProfilingDetails
Definition: Profiling.hpp:103
armnn::OptionalBase::has_value
bool has_value() const noexcept
Definition: Optional.hpp:53
armnn::ProfilerManager::GetProfiler
IProfiler * GetProfiler()
Definition: Profiling.cpp:614
ARMNN_THROW_INVALIDARG_MSG_IF_FALSE
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
Definition: Exceptions.hpp:210
armnn::JsonChildObject
Definition: JsonPrinter.hpp:27