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>
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;
165 : m_ProfilingEnabled(false),
170 #if ARMNN_STREAMLINE_ENABLED
207 const std::string& label,
208 std::vector<InstrumentPtr>&& instruments,
216 std::move(instruments),
221 #if ARMNN_STREAMLINE_ENABLED
252 #if ARMNN_STREAMLINE_ENABLED
253 ANNOTATE_CHANNEL_END(uint32_t(
m_Parents.size()));
260 while (eventPtr !=
nullptr)
273 const Event* eventPtrRaw =
event.get();
274 if (eventPtrRaw->
GetName() == parentName)
276 outBaseLevel = (outBaseLevel == -1) ?
CalcLevel(eventPtrRaw) : outBaseLevel;
277 outEvents.push_back(eventPtrRaw);
286 const Event* eventPtrRaw =
event.get();
294 auto it = outDescendantsMap.find(parent);
295 if (it == outDescendantsMap.end())
297 outDescendantsMap.emplace(parent, std::vector<const Event*>({ eventPtrRaw }));
301 it->second.push_back(eventPtrRaw);
307 std::string layerDetailsStr)
315 const Event* parentEvent,
317 std::map<
const Event*, std::vector<const Event*>> descendantsMap)
324 arm::pipe::ProfilingGuid profilingGuid;
326 parentObject.
SetGuid(profilingGuid);
328 std::vector<Measurement> instrumentMeasurements = parentEvent->
GetMeasurements();
329 unsigned int childIdx = 0;
330 unsigned int numSkippedKernels = 0;
331 if (inferenceIndex > 0)
335 if (i->HasKernelMeasurements())
337 numSkippedKernels =
static_cast<unsigned int>(parentObject.
m_Children.size() -
338 instrumentMeasurements.size());
339 childIdx = numSkippedKernels;
344 for (
size_t measurementIndex = 0; measurementIndex < instrumentMeasurements.size(); ++measurementIndex, ++childIdx)
346 if (inferenceIndex == 0)
349 JsonChildObject measurementObject{ instrumentMeasurements[measurementIndex].m_Name };
350 measurementObject.
SetUnit(instrumentMeasurements[measurementIndex].m_Unit);
355 throw armnn::Exception(
"parentObject must have the same number of children as childIdx.");
357 parentObject.
AddChild(measurementObject);
361 if (numSkippedKernels > 0)
370 auto childEventsIt = descendantsMap.find(parentEvent);
371 if (childEventsIt != descendantsMap.end())
373 for (
auto childEvent : childEventsIt->second)
375 if (inferenceIndex == 0)
398 std::streamsize oldPrecision = outStream.precision();
399 outStream.precision(6);
400 std::ios_base::fmtflags oldFlags = outStream.flags();
401 outStream.setf(std::ios::fixed);
407 std::vector<const Event*> optimizations;
410 std::vector<const Event*> loadedNetworks;
413 std::vector<const Event*> inferences;
417 std::map<const Event*, std::vector<const Event*>> descendantsMap;
423 for (
unsigned int optimizeIndex = 0; optimizeIndex < optimizations.size(); ++optimizeIndex)
425 auto optimization = optimizations[optimizeIndex];
431 for (
unsigned int loadedNetworkIndex = 0; loadedNetworkIndex < loadedNetworks.size(); ++loadedNetworkIndex)
433 auto loadedNetwork = loadedNetworks[loadedNetworkIndex];
434 ExtractJsonObjects(loadedNetworkIndex, loadedNetwork, loadedNetworkObject, descendantsMap);
439 for (
unsigned int inferenceIndex = 0; inferenceIndex < inferences.size(); ++inferenceIndex)
441 auto inference = inferences[inferenceIndex];
486 outStream.flags(oldFlags);
487 outStream.precision(oldPrecision);
493 const bool saneMarkerSequence =
m_Parents.empty();
497 if (!saneMarkerSequence)
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;
514 outStream << std::endl;
515 outStream <<
"***" << std::endl;
516 outStream <<
"*** Per Inference Stats" << std::endl;
517 outStream <<
"***" << std::endl;
518 outStream << std::endl;
521 std::vector<const Event*> inferences;
525 std::map<const Event*, std::vector<const Event*>> descendantsMap;
528 std::function<void(
const Event*, std::vector<const Event*>&)>
529 FindDescendantEvents = [&](
const Event* eventPtr, std::vector<const Event*>& sequence)
531 sequence.push_back(eventPtr);
538 auto children = descendantsMap.find(eventPtr);
539 if (children == descendantsMap.end())
544 if (!(children->second.empty()))
546 return FindDescendantEvents(children->second[0], sequence);
551 int inferenceIdx = 0;
552 for (
auto inference : inferences)
554 std::vector<const Event*> sequence;
557 FindDescendantEvents(inference, sequence);
559 outStream <<
"> Begin Inference: " << inferenceIdx << std::endl;
560 outStream << std::endl;
564 outStream << std::endl;
565 outStream <<
"> End Inference: " << inferenceIdx << std::endl;
577 if (backendId == cpuRef)
582 else if (backendId == cpuAcc)
587 else if (backendId == gpuAcc)
606 return s_ProfilerManager;
621 pProfilerImpl->EnableProfiling(enableProfiling);
626 pProfilerImpl->EnableNetworkDetailsToStdOut(detailsMethod);
631 return pProfilerImpl->IsProfilingEnabled();
636 pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
641 pProfilerImpl->Print(outStream);
645 const std::string& label,
646 std::vector<InstrumentPtr>&& instruments,
649 return pProfilerImpl->BeginEvent(
this, backendId, label, std::move(instruments), guid);
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
const std::string & Get() const
Event class records measurements reported by BeginEvent()/EndEvent() and returns measurements when Ev...
const Event * GetParentEvent() const
Get the pointer of the parent event.
const std::string & GetName() const
Get the name of the event.
Optional< arm::pipe::ProfilingGuid > GetProfilingGuid() const
Get the associated profiling GUID if the event is a workload.
BackendId GetBackendId() const
Get the backend id of the event.
const std::vector< Measurement > GetMeasurements() const
Get the recorded measurements calculated between Start() and Stop()
const std::vector< InstrumentPtr > & GetInstruments() const
Get the Instruments used by this Event.
Base class for all ArmNN exceptions so that users can filter to just those.
void Print(std::ostream &outStream) const
Print stats for events in JSON Format to the given output stream.
void EnableNetworkDetailsToStdOut(ProfilingDetailsMethod detailsMethod)
Print out details of each layer within the network that possesses a descriptor.
bool IsProfilingEnabled()
Checks whether profiling is enabled.
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
Analyzes the tracked events and writes the results to the given output stream.
void EnableProfiling(bool enableProfiling)
Enables/disables profiling for this profiler.
void PrintJsonChildObject(const JsonChildObject &object, size_t &id)
bool has_value() const noexcept
void Print(std::ostream &outStream) const
std::map< std::string, ProfilingEventStats > CalculateProfilingEventStats() const
DescPtr m_ProfilingDetails
void EnableNetworkDetailsToStdOut(ProfilingDetailsMethod detailsMethod)
std::vector< EventPtr > m_EventSequence
std::stack< Event * > m_Parents
Event * BeginEvent(armnn::IProfiler *profiler, const BackendId &backendId, const std::string &name, std::vector< InstrumentPtr > &&instruments, const Optional< arm::pipe::ProfilingGuid > &guid)
void EndEvent(Event *event)
void PopulateParent(std::vector< const Event * > &outEvents, int &outBaseLevel, std::string parentName) const
bool IsProfilingEnabled()
uint32_t GetEventColor(const BackendId &backendId) const
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream &outStream) const
ProfilingDetailsMethod m_DetailsToStdOutMethod
void EnableProfiling(bool enableProfiling)
void PopulateDescendants(std::map< const Event *, std::vector< const Event * >> &outDescendantsMap) const
IProfiler * GetProfiler()
void RegisterProfiler(IProfiler *profiler)
static ProfilerManager & GetInstance()
static const std::string WALL_CLOCK_TIME_STOP
static const std::string WALL_CLOCK_TIME
static const std::string WALL_CLOCK_TIME_START
Copyright (c) 2021 ARM Limited and Contributors.
Measurement FindMeasurement(const std::string &name, const Event *event)
std::vector< Measurement > FindKernelMeasurements(const Event *event)
int CalcLevel(const Event *eventPtr)
constexpr bool g_WriteProfilingEventSequence
constexpr std::size_t g_ProfilingEventCountHint
constexpr bool g_WriteReportToStdOutOnProfilerDestruction
void ExtractJsonObjects(unsigned int inferenceIndex, const Event *parentEvent, JsonChildObject &parentObject, std::map< const Event *, std::vector< const Event * >> descendantsMap)
constexpr bool g_AggregateProfilingEventsByInference
const Event * GetEventPtr(const Event *ptr)
thread_local IProfiler * tl_Profiler
ProfilingDetailsMethod
Define the behaviour of the internal profiler when outputting network details.
void ConfigureDetailsObject(JsonChildObject &detailsObject, std::string layerDetailsStr)
size_t NumChildren() const
void AddChild(const JsonChildObject &childObject)
void SetAndParseDetails(std::string layerDetailsStr)
void SetType(JsonObjectType type)
JsonChildObject & GetChild(const unsigned int index)
void SetUnit(const Measurement::Unit unit)
void SetGuid(arm::pipe::ProfilingGuid guid)
std::vector< JsonChildObject > m_Children
void AddMeasurement(const double measurement)