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
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() == parentName)
265 outBaseLevel = (outBaseLevel == -1) ?
CalcLevel(eventPtrRaw) : outBaseLevel;
266 outEvents.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 arm::pipe::ProfilingGuid profilingGuid;
315 parentObject.
SetGuid(profilingGuid);
317 std::vector<Measurement> instrumentMeasurements = parentEvent->
GetMeasurements();
318 unsigned int childIdx = 0;
319 unsigned int numSkippedKernels = 0;
320 if (inferenceIndex > 0)
324 if (i->HasKernelMeasurements())
326 numSkippedKernels =
static_cast<unsigned int>(parentObject.
m_Children.size() -
327 instrumentMeasurements.size());
328 childIdx = numSkippedKernels;
333 for (
size_t measurementIndex = 0; measurementIndex < instrumentMeasurements.size(); ++measurementIndex, ++childIdx)
335 if (inferenceIndex == 0)
338 JsonChildObject measurementObject{ instrumentMeasurements[measurementIndex].m_Name };
339 measurementObject.
SetUnit(instrumentMeasurements[measurementIndex].m_Unit);
343 parentObject.
AddChild(measurementObject);
347 if (numSkippedKernels > 0)
356 auto childEventsIt = descendantsMap.find(parentEvent);
357 if (childEventsIt != descendantsMap.end())
359 for (
auto childEvent : childEventsIt->second)
361 if (inferenceIndex == 0)
384 std::streamsize oldPrecision = outStream.precision();
385 outStream.precision(6);
386 std::ios_base::fmtflags oldFlags = outStream.flags();
387 outStream.setf(std::ios::fixed);
393 std::vector<const Event*> optimizations;
396 std::vector<const Event*> loadedNetworks;
399 std::vector<const Event*> inferences;
403 std::map<const Event*, std::vector<const Event*>> descendantsMap;
409 for (
unsigned int optimizeIndex = 0; optimizeIndex < optimizations.size(); ++optimizeIndex)
411 auto optimization = optimizations[optimizeIndex];
417 for (
unsigned int loadedNetworkIndex = 0; loadedNetworkIndex < loadedNetworks.size(); ++loadedNetworkIndex)
419 auto loadedNetwork = loadedNetworks[loadedNetworkIndex];
420 ExtractJsonObjects(loadedNetworkIndex, loadedNetwork, loadedNetworkObject, descendantsMap);
425 for (
unsigned int inferenceIndex = 0; inferenceIndex < inferences.size(); ++inferenceIndex)
427 auto inference = inferences[inferenceIndex];
472 outStream.flags(oldFlags);
473 outStream.precision(oldPrecision);
484 const bool saneMarkerSequence =
m_Parents.empty();
488 if (!saneMarkerSequence)
490 outStream <<
"Cannot write profiling stats. "
491 "Unexpected errors were found when analyzing the sequence of logged events, "
492 "which may lead to plainly wrong stats. The profiling system may contain implementation "
493 "issues or could have been used in an unsafe manner." << std::endl;
505 outStream << std::endl;
506 outStream <<
"***" << std::endl;
507 outStream <<
"*** Per Inference Stats" << std::endl;
508 outStream <<
"***" << std::endl;
509 outStream << std::endl;
512 std::vector<const Event*> inferences;
516 std::map<const Event*, std::vector<const Event*>> descendantsMap;
519 std::function<void(
const Event*, std::vector<const Event*>&)>
520 FindDescendantEvents = [&](
const Event* eventPtr, std::vector<const Event*>& sequence)
522 sequence.push_back(eventPtr);
529 auto children = descendantsMap.find(eventPtr);
530 if (children == descendantsMap.end())
535 if (!(children->second.empty()))
537 return FindDescendantEvents(children->second[0], sequence);
542 int inferenceIdx = 0;
543 for (
auto inference : inferences)
545 std::vector<const Event*> sequence;
548 FindDescendantEvents(inference, sequence);
550 outStream <<
"> Begin Inference: " << inferenceIdx << std::endl;
551 outStream << std::endl;
555 outStream << std::endl;
556 outStream <<
"> End Inference: " << inferenceIdx << std::endl;
568 if (backendId == cpuRef)
573 else if (backendId == cpuAcc)
578 else if (backendId == gpuAcc)
597 return s_ProfilerManager;
612 pProfilerImpl->EnableProfiling(enableProfiling);
617 pProfilerImpl->EnableNetworkDetailsToStdOut(detailsMethod);
622 return pProfilerImpl->IsProfilingEnabled();
627 pProfilerImpl->AnalyzeEventsAndWriteResults(outStream);
632 pProfilerImpl->Print(outStream);
636 const std::string& label,
637 std::vector<InstrumentPtr>&& instruments,
640 return pProfilerImpl->BeginEvent(
this, backendId, label, std::move(instruments), guid);