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);