12 #if ARMNN_STREAMLINE_ENABLED 13 #include <streamline_annotate.h> 51 if (measurement.m_Name == name)
59 return Measurement{
"", 0.f, Measurement::Unit::TIME_MS };
66 std::vector<Measurement> measurements;
71 if (measurement.m_Name.rfind(
"OpenClKernelTimer", 0) == 0
72 || measurement.m_Name.rfind(
"NeonKernelTimer", 0) == 0)
75 measurements.push_back(measurement);
84 std::map<std::string, ProfilingEventStats> nameToStatsMap;
90 double durationMs = measurement.
m_Value;
91 auto it = nameToStatsMap.find(event->GetName());
92 if (it != nameToStatsMap.end())
102 nameToStatsMap.emplace(event->GetName(),
ProfilingEventStats{ durationMs, durationMs, durationMs, 1 });
106 return nameToStatsMap;
112 template<
typename ItertType>
116 if (g_WriteProfilingEventSequence)
119 std::streamsize oldPrecision = outStream.precision();
120 outStream.precision(6);
121 std::ios_base::fmtflags oldFlags = outStream.flags();
122 outStream.setf(std::ios::fixed);
124 outStream <<
"Event Sequence - Name | Duration (ms) | Start (ms) | Stop (ms) | Device" << std::endl;
125 for (
auto event = first;
event != last; ++event)
133 outStream << std::setw(50) << eventPtr->
GetName() <<
" " 134 << std::setw(20) << durationMs
135 << std::setw(20) << startTimeMs
136 << std::setw(20) << stopTimeMs
140 outStream << std::endl;
142 outStream.flags(oldFlags);
143 outStream.precision(oldPrecision);
150 outStream <<
"Event Stats - Name | Avg (ms) | Min (ms) | Max (ms) | Total (ms) | Count" << std::endl;
151 for (
const auto& pair : nameToStatsMap)
153 const std::string& eventLabel = pair.first;
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;
161 outStream << std::endl;
170 #if ARMNN_STREAMLINE_ENABLED 180 if (g_WriteReportToStdOutOnProfilerDestruction)
207 const std::string& label,
208 std::vector<InstrumentPtr>&& instruments,
216 std::move(instruments),
221 #if ARMNN_STREAMLINE_ENABLED 241 #if ARMNN_STREAMLINE_ENABLED 242 ANNOTATE_CHANNEL_END(uint32_t(
m_Parents.size()));
249 while (eventPtr !=
nullptr)
262 const Event* eventPtrRaw =
event.get();
263 if (eventPtrRaw->
GetName() ==
"EnqueueWorkload")
265 outBaseLevel = (outBaseLevel == -1) ?
CalcLevel(eventPtrRaw) : outBaseLevel;
266 outInferences.push_back(eventPtrRaw);
275 const Event* eventPtrRaw =
event.get();
283 auto it = outDescendantsMap.find(parent);
284 if (it == outDescendantsMap.end())
286 outDescendantsMap.emplace(parent, std::vector<const Event*>({ eventPtrRaw }));
290 it->second.push_back(eventPtrRaw);
296 std::string layerDetailsStr)
304 const Event* parentEvent,
306 std::map<
const Event*, std::vector<const Event*>> descendantsMap)
313 profiling::ProfilingGuid profilingGuid;
315 parentObject.
SetGuid(profilingGuid);
317 std::vector<Measurement> instrumentMeasurements = parentEvent->
GetMeasurements();
318 unsigned int childIdx = 0;
319 for (
size_t measurementIndex = 0; measurementIndex < instrumentMeasurements.size(); ++measurementIndex, ++childIdx)
321 if (inferenceIndex == 0)
324 JsonChildObject measurementObject{ instrumentMeasurements[measurementIndex].m_Name };
325 measurementObject.
SetUnit(instrumentMeasurements[measurementIndex].m_Unit);
329 parentObject.
AddChild(measurementObject);
335 auto childEventsIt = descendantsMap.find(parentEvent);
336 if (childEventsIt != descendantsMap.end())
338 for (
auto childEvent : childEventsIt->second)
340 if (inferenceIndex == 0)
359 std::streamsize oldPrecision = outStream.precision();
360 outStream.precision(6);
361 std::ios_base::fmtflags oldFlags = outStream.flags();
362 outStream.setf(std::ios::fixed);
367 std::vector<const Event*> inferences;
371 std::map<const Event*, std::vector<const Event*>> descendantsMap;
375 std::vector<JsonChildObject> workloadObjects;
376 std::map<unsigned int, std::vector<JsonChildObject>> workloadToKernelObjects;
378 for (
unsigned int inferenceIndex = 0; inferenceIndex < inferences.size(); ++inferenceIndex)
380 auto inference = inferences[inferenceIndex];
410 outStream.flags(oldFlags);
411 outStream.precision(oldPrecision);
417 const bool saneMarkerSequence =
m_Parents.empty();
421 if (!saneMarkerSequence)
423 outStream <<
"Cannot write profiling stats. " 424 "Unexpected errors were found when analyzing the sequence of logged events, " 425 "which may lead to plainly wrong stats. The profiling system may contain implementation " 426 "issues or could have been used in an unsafe manner." << std::endl;
436 if (g_AggregateProfilingEventsByInference)
438 outStream << std::endl;
439 outStream <<
"***" << std::endl;
440 outStream <<
"*** Per Inference Stats" << std::endl;
441 outStream <<
"***" << std::endl;
442 outStream << std::endl;
445 std::vector<const Event*> inferences;
449 std::map<const Event*, std::vector<const Event*>> descendantsMap;
452 std::function<void(const Event*, std::vector<const Event*>&)>
453 FindDescendantEvents = [&](
const Event* eventPtr, std::vector<const Event*>& sequence)
455 sequence.push_back(eventPtr);
462 auto children = descendantsMap.find(eventPtr);
463 if (children == descendantsMap.end())
468 if (!(children->second.empty()))
470 return FindDescendantEvents(children->second[0], sequence);
475 int inferenceIdx = 0;
476 for (
auto inference : inferences)
478 std::vector<const Event*> sequence;
481 FindDescendantEvents(inference, sequence);
483 outStream <<
"> Begin Inference: " << inferenceIdx << std::endl;
484 outStream << std::endl;
488 outStream << std::endl;
489 outStream <<
"> End Inference: " << inferenceIdx << std::endl;
501 if (backendId == cpuRef)
506 else if (backendId == cpuAcc)
511 else if (backendId == gpuAcc)
530 return s_ProfilerManager;
535 tl_Profiler = profiler;
545 pProfilerImpl->EnableProfiling(enableProfiling);
550 pProfilerImpl->EnableNetworkDetailsToStdOut();
555 return pProfilerImpl->IsProfilingEnabled();
560 pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
565 pProfilerImpl->Print(outStream);
569 const std::string& label,
570 std::vector<InstrumentPtr>&& instruments,
573 return pProfilerImpl->BeginEvent(
this, backendId, label, std::move(instruments), guid);
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 &&...)
Optional< profiling::ProfilingGuid > GetProfilingGuid() const
Get the associated profiling GUID if the event is a workload.
void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream &outStream) const
void EnableNetworkDetailsToStdOut()
Print out details of each layer within the network that possesses a descriptor.
void SetAndParseDetails(std::string layerDetailsStr)
size_t NumChildren() const
IProfiler * GetProfiler()
void ConfigureDetailsObject(JsonChildObject &detailsObject, std::string layerDetailsStr)
BackendId GetBackendId() const
Get the backend id of the event.
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
void EnableNetworkDetailsToStdOut()
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
bool has_value() const noexcept
static const std::string WALL_CLOCK_TIME
bool IsProfilingEnabled()
Checks whether profiling is enabled.
void AddMeasurement(const double measurement)
#define ARMNN_ASSERT(COND)
bool m_EnableDetailsToStdOut
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
void RegisterProfiler(IProfiler *profiler)
DescPtr m_ProfilingDetails
const std::string & Get() const
void SetUnit(const Measurement::Unit unit)
void SetGuid(profiling::ProfilingGuid guid)
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
Event * BeginEvent(armnn::IProfiler *profiler, const BackendId &backendId, const std::string &name, std::vector< InstrumentPtr > &&instruments, const Optional< profiling::ProfilingGuid > &guid)
std::vector< EventPtr > m_EventSequence
void EnableProfiling(bool enableProfiling)