13 #if ARMNN_STREAMLINE_ENABLED 14 #include <streamline_annotate.h> 52 if (measurement.m_Name == name)
60 return Measurement{
"", 0.f, Measurement::Unit::TIME_MS };
67 std::vector<Measurement> measurements;
72 if (measurement.m_Name.rfind(
"OpenClKernelTimer", 0) == 0
73 || measurement.m_Name.rfind(
"NeonKernelTimer", 0) == 0)
76 measurements.push_back(measurement);
85 std::map<std::string, ProfilingEventStats> nameToStatsMap;
91 double durationMs = measurement.
m_Value;
92 auto it = nameToStatsMap.find(event->GetName());
93 if (it != nameToStatsMap.end())
103 nameToStatsMap.emplace(event->GetName(),
ProfilingEventStats{ durationMs, durationMs, durationMs, 1 });
107 return nameToStatsMap;
113 template<
typename ItertType>
117 if (g_WriteProfilingEventSequence)
120 std::streamsize oldPrecision = outStream.precision();
121 outStream.precision(6);
122 std::ios_base::fmtflags oldFlags = outStream.flags();
123 outStream.setf(std::ios::fixed);
125 outStream <<
"Event Sequence - Name | Duration (ms) | Start (ms) | Stop (ms) | Device" << std::endl;
126 for (
auto event = first;
event != last; ++event)
134 outStream << std::setw(50) << eventPtr->
GetName() <<
" " 135 << std::setw(20) << durationMs
136 << std::setw(20) << startTimeMs
137 << std::setw(20) << stopTimeMs
141 outStream << std::endl;
143 outStream.flags(oldFlags);
144 outStream.precision(oldPrecision);
151 outStream <<
"Event Stats - Name | Avg (ms) | Min (ms) | Max (ms) | Total (ms) | Count" << std::endl;
152 for (
const auto& pair : nameToStatsMap)
154 const std::string& eventLabel = pair.first;
158 outStream <<
"\t" << std::setw(50) << eventLabel <<
" " << std::setw(9) << avgMs <<
" " 159 << std::setw(9) << eventStats.
m_MinMs <<
" " << std::setw(9) << eventStats.
m_MaxMs <<
" " 160 << std::setw(9) << eventStats.
m_TotalMs <<
" " << std::setw(9) << eventStats.
m_Count << std::endl;
162 outStream << std::endl;
170 #if ARMNN_STREAMLINE_ENABLED 180 if (g_WriteReportToStdOutOnProfilerDestruction)
202 const std::string& label,
203 std::vector<InstrumentPtr>&& instruments)
206 m_EventSequence.push_back(std::make_unique<Event>(label, profiler, parent, backendId, std::move(instruments)));
210 #if ARMNN_STREAMLINE_ENABLED 230 #if ARMNN_STREAMLINE_ENABLED 231 ANNOTATE_CHANNEL_END(uint32_t(
m_Parents.size()));
238 while (eventPtr !=
nullptr)
251 const Event* eventPtrRaw =
event.get();
252 if (eventPtrRaw->
GetName() ==
"EnqueueWorkload")
254 outBaseLevel = (outBaseLevel == -1) ?
CalcLevel(eventPtrRaw) : outBaseLevel;
255 outInferences.push_back(eventPtrRaw);
264 const Event* eventPtrRaw =
event.get();
272 auto it = outDescendantsMap.find(parent);
273 if (it == outDescendantsMap.end())
275 outDescendantsMap.emplace(parent, std::vector<const Event*>({eventPtrRaw}));
279 it->second.push_back(eventPtrRaw);
286 const Event* parentEvent,
288 std::map<
const Event*, std::vector<const Event*>> descendantsMap)
291 std::vector<Measurement> instrumentMeasurements = parentEvent->
GetMeasurements();
292 unsigned int childIdx=0;
293 for(
size_t measurementIndex = 0; measurementIndex < instrumentMeasurements.size(); ++measurementIndex, ++childIdx)
295 if (inferenceIndex == 0)
298 JsonChildObject measurementObject{instrumentMeasurements[measurementIndex].m_Name};
299 measurementObject.
SetUnit(instrumentMeasurements[measurementIndex].m_Unit);
303 parentObject.
AddChild(measurementObject);
310 auto childEventsIt = descendantsMap.find(parentEvent);
311 if (childEventsIt != descendantsMap.end())
313 for (
auto childEvent : childEventsIt->second)
315 if (inferenceIndex == 0)
334 std::streamsize oldPrecision = outStream.precision();
335 outStream.precision(6);
336 std::ios_base::fmtflags oldFlags = outStream.flags();
337 outStream.setf(std::ios::fixed);
342 std::vector<const Event*> inferences;
346 std::map<const Event*, std::vector<const Event*>> descendantsMap;
351 std::vector<JsonChildObject> workloadObjects;
352 std::map<unsigned int, std::vector<JsonChildObject>> workloadToKernelObjects;
354 for (
unsigned int inferenceIndex = 0; inferenceIndex < inferences.size(); ++inferenceIndex)
356 auto inference = inferences[inferenceIndex];
377 outStream.flags(oldFlags);
378 outStream.precision(oldPrecision);
384 const bool saneMarkerSequence =
m_Parents.empty();
388 if (!saneMarkerSequence)
390 outStream <<
"Cannot write profiling stats. " 391 "Unexpected errors were found when analyzing the sequence of logged events, which may lead to plainly " 392 "wrong stats. The profiling system may contain implementation issues or could have been used in an " 393 "unsafe manner." << std::endl;
403 if (g_AggregateProfilingEventsByInference)
405 outStream << std::endl;
406 outStream <<
"***" << std::endl;
407 outStream <<
"*** Per Inference Stats" << std::endl;
408 outStream <<
"***" << std::endl;
409 outStream << std::endl;
412 std::vector<const Event*> inferences;
416 std::map<const Event*, std::vector<const Event*>> descendantsMap;
419 std::function<void (const Event*, std::vector<const Event*>&)>
420 FindDescendantEvents = [&](
const Event* eventPtr,
421 std::vector<const Event*>& sequence)
423 sequence.push_back(eventPtr);
430 auto children = descendantsMap.find(eventPtr);
431 if (children == descendantsMap.end())
436 if (!(children->second.empty()))
438 return FindDescendantEvents(children->second[0], sequence);
443 int inferenceIdx = 0;
444 for (
auto inference : inferences)
446 std::vector<const Event*> sequence;
449 FindDescendantEvents(inference, sequence);
451 outStream <<
"> Begin Inference: " << inferenceIdx << std::endl;
452 outStream << std::endl;
456 outStream << std::endl;
457 outStream <<
"> End Inference: " << inferenceIdx << std::endl;
469 if (backendId == cpuRef) {
472 }
else if (backendId == cpuAcc) {
475 }
else if (backendId == gpuAcc) {
493 return s_ProfilerManager;
498 tl_Profiler = profiler;
509 pProfilerImpl->EnableProfiling(enableProfiling);
514 return pProfilerImpl->IsProfilingEnabled();
519 pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
524 pProfilerImpl->Print(outStream);
528 const std::string& label,
529 std::vector<InstrumentPtr>&& instruments)
531 return pProfilerImpl->BeginEvent(
this, backendId, label, std::move(instruments));
JsonChildObject & GetChild(const unsigned int index)
Event class records measurements reported by BeginEvent()/EndEvent() and returns measurements when Ev...
const Event * GetEventPtr(const Event *ptr)
constexpr bool g_WriteReportToStdOutOnProfilerDestruction
void AddChild(const JsonChildObject &childObject)
int CalcLevel(const Event *eventPtr)
bool IsProfilingEnabled()
static ProfilerManager & GetInstance()
Measurement FindMeasurement(const std::string &name, const Event *event)
uint32_t GetEventColor(const BackendId &backendId) const
std::vector< Measurement > FindKernelMeasurements(const Event *event)
void Print(std::ostream &outStream) const
Print stats for events in JSON Format to the given output stream.
std::map< std::string, ProfilingEventStats > CalculateProfilingEventStats() const
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
Analyzes the tracked events and writes the results to the given output stream.
const std::string & GetName() const
Get the name of the event.
Copyright (c) 2021 ARM Limited and Contributors.
void IgnoreUnused(Ts &&...)
void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream &outStream) const
size_t NumChildren() const
IProfiler * GetProfiler()
BackendId GetBackendId() const
Get the backend id of the event.
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
const std::vector< Measurement > GetMeasurements() const
Get the recorded measurements calculated between Start() and Stop()
void ExtractJsonObjects(unsigned int inferenceIndex, const Event *parentEvent, JsonChildObject &parentObject, std::map< const Event *, std::vector< const Event *>> descendantsMap)
void EnableProfiling(bool enableProfiling)
Enables/disables profiling for this profiler.
static const std::string WALL_CLOCK_TIME_STOP
void SetType(JsonObjectType type)
static const std::string WALL_CLOCK_TIME_START
constexpr std::size_t g_ProfilingEventCountHint
static const std::string WALL_CLOCK_TIME
bool IsProfilingEnabled()
Checks whether profiling is enabled.
void AddMeasurement(const double measurement)
#define ARMNN_ASSERT(COND)
void EndEvent(Event *event)
void PrintJsonChildObject(const JsonChildObject &object, size_t &id)
constexpr bool g_WriteProfilingEventSequence
constexpr bool g_AggregateProfilingEventsByInference
void Print(std::ostream &outStream) const
Event * BeginEvent(armnn::IProfiler *profiler, const BackendId &backendId, const std::string &name, std::vector< InstrumentPtr > &&instruments)
void RegisterProfiler(IProfiler *profiler)
const std::string & Get() const
void SetUnit(const Measurement::Unit unit)
void PopulateInferences(std::vector< const Event *> &outInferences, int &outBaseLevel) const
std::stack< Event * > m_Parents
const Event * GetParentEvent() const
Get the pointer of the parent event.
thread_local IProfiler * tl_Profiler
void PopulateDescendants(std::map< const Event *, std::vector< const Event *>> &outDescendantsMap) const
std::vector< EventPtr > m_EventSequence
void EnableProfiling(bool enableProfiling)