ArmNN
 21.08
Profiling.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <common/include/ProfilingGuid.hpp>
8 #include "ProfilingEvent.hpp"
9 #include "ProfilingDetails.hpp"
10 #include "armnn/IProfiler.hpp"
11 
12 #include <armnn/Optional.hpp>
14 #include "WallClockTimer.hpp"
15 
16 #include <chrono>
17 #include <iosfwd>
18 #include <ctime>
19 #include <vector>
20 #include <stack>
21 #include <map>
22 
23 namespace armnn
24 {
25 
26 // Simple single-threaded profiler.
27 // Tracks events reported by BeginEvent()/EndEvent() and outputs detailed information and stats when
28 // Profiler::AnalyzeEventsAndWriteResults() is called.
30 {
31 public:
32  ProfilerImpl();
33  ~ProfilerImpl();
34  using InstrumentPtr = std::unique_ptr<Instrument>;
35 
36  // Marks the beginning of a user-defined event.
37  // No attempt will be made to copy the name string: it must be known at compile time.
39  const BackendId& backendId,
40  const std::string& name,
41  std::vector<InstrumentPtr>&& instruments,
43 
44  template<typename DescriptorType>
45  void AddLayerDetails(const std::string& label,
46  const DescriptorType& desc,
47  const WorkloadInfo& infos,
48  const profiling::ProfilingGuid guid)
49  {
50  m_ProfilingDetails->AddDetailsToString(label, desc, infos, guid);
51  }
52 
53  // Marks the end of a user-defined event.
54  void EndEvent(Event* event);
55 
56  // Enables/disables profiling.
57  void EnableProfiling(bool enableProfiling);
58 
59  // Checks if profiling is enabled.
60  bool IsProfilingEnabled();
61 
62  // Enables outputting the layer descriptors and infos to stdout
64 
65  // Increments the event tag, allowing grouping of events in a user-defined manner (e.g. per inference).
66  void UpdateEventTag();
67 
68  // Analyzes the tracked events and writes the results to the given output stream.
69  // Please refer to the configuration variables in Profiling.cpp to customize the information written.
70  void AnalyzeEventsAndWriteResults(std::ostream& outStream) const;
71 
72  // Print stats for events in JSON Format to the given output stream.
73  void Print(std::ostream& outStream) const;
74 
75  // Gets the color to render an event with, based on which device it denotes.
76  uint32_t GetEventColor(const BackendId& backendId) const;
77 
78  using EventPtr = std::unique_ptr<Event>;
79  using DescPtr = std::unique_ptr<ProfilingDetails>;
80 
81  struct Marker
82  {
83  std::size_t m_Id;
84  };
85 
87  {
88  double m_TotalMs;
89  double m_MinMs;
90  double m_MaxMs;
91  uint32_t m_Count;
92  };
93 
94  template<typename EventIterType>
95  void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream& outStream) const;
96 
97  std::map<std::string, ProfilingEventStats> CalculateProfilingEventStats() const;
98  void PopulateInferences(std::vector<const Event*>& outInferences, int& outBaseLevel) const;
99  void PopulateDescendants(std::map<const Event*, std::vector<const Event*>>& outDescendantsMap) const;
100 
101  std::stack<Event*> m_Parents;
102  std::vector<EventPtr> m_EventSequence;
103  DescPtr m_ProfilingDetails = std::make_unique<ProfilingDetails>();
106 };
107 
108 // Singleton profiler manager.
109 // Keeps track of all the running profiler instances.
111 {
112 public:
113  // Register the given profiler as a thread local pointer.
114  void RegisterProfiler(IProfiler* profiler);
115 
116  // Gets the thread local pointer to the profiler.
117  IProfiler* GetProfiler();
118 
119  // Accesses the singleton.
120  static ProfilerManager& GetInstance();
121 
122 private:
123  // The constructor is kept private so that other instances of this class (other that the singleton's)
124  // can't be allocated.
125  ProfilerManager() {}
126 };
127 
128 // Helper to easily add event markers to the codebase.
130 {
131 public:
132  using InstrumentPtr = std::unique_ptr<Instrument>;
133 
134  template<typename... Args>
135  ScopedProfilingEvent(const BackendId& backendId,
137  const std::string& name,
138  Args&& ... args)
139  : m_Event(nullptr)
140  , m_Profiler(ProfilerManager::GetInstance().GetProfiler())
141  {
142  if (m_Profiler && m_Profiler->IsProfilingEnabled())
143  {
144  std::vector<InstrumentPtr> instruments(0);
145  instruments.reserve(sizeof...(args)); //One allocation
146  ConstructNextInVector(instruments, std::forward<Args>(args)...);
147  m_Event = m_Profiler->BeginEvent(backendId, name, std::move(instruments), guid);
148  }
149  }
150 
152  {
153  if (m_Profiler && m_Event)
154  {
155  m_Profiler->pProfilerImpl->EndEvent(m_Event);
156  }
157  }
158 
159 private:
160 
161  void ConstructNextInVector(std::vector<InstrumentPtr>& instruments)
162  {
163  IgnoreUnused(instruments);
164  }
165 
166  template<typename Arg, typename... Args>
167  void ConstructNextInVector(std::vector<InstrumentPtr>& instruments, Arg&& arg, Args&&... args)
168  {
169  instruments.emplace_back(std::make_unique<Arg>(std::forward<Arg>(arg)));
170  ConstructNextInVector(instruments, std::forward<Args>(args)...);
171  }
172 
173  Event* m_Event; ///< Event to track
174  IProfiler* m_Profiler; ///< Profiler used
175 };
176 
177 // Helper to easily add operator details during profiling.
178 template<typename DescriptorType>
179 inline void ProfilingUpdateDescriptions(const std::string& name,
180  const DescriptorType& desc,
181  const WorkloadInfo& infos,
182  const profiling::ProfilingGuid guid)
183 {
184  IProfiler* profiler(ProfilerManager::GetInstance().GetProfiler()); ///< Profiler used
185  if (profiler && profiler->IsProfilingEnabled())
186  {
187  profiler->AddLayerDetails(name, desc, infos, guid);
188  }
189 }
190 
191 template<typename DescriptorType>
192 void IProfiler::AddLayerDetails(const std::string& name,
193  const DescriptorType& desc,
194  const WorkloadInfo& infos,
195  const profiling::ProfilingGuid guid)
196 {
197  return pProfilerImpl->AddLayerDetails(name, desc, infos, guid);
198 }
199 
200 } // namespace armnn
201 
202 // Event Definitions for profiling
203 #define ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS_UNIQUE_LOC_INNER(lineNumber, backendId, guid, /*name,*/ ...) \
204  armnn::ScopedProfilingEvent e_ ## lineNumber(backendId, guid, /*name,*/ __VA_ARGS__);
205 
206 #define ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS_UNIQUE_LOC(lineNumber, backendId, guid, /*name,*/ ...) \
207  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS_UNIQUE_LOC_INNER(lineNumber, backendId, guid, /*name,*/ __VA_ARGS__)
208 
209 // The event name must be known at compile time i.e. if you are going to use this version of the macro
210 // in code the first argument you supply after the backendId must be the name.
211 // NOTE: need to pass the line number as an argument from here so by the time it gets to the UNIQUE_LOC_INNER
212 // above it has expanded to a string and will concat (##) correctly with the 'e_' prefix to yield a
213 // legal and unique variable name (so long as you don't use the macro twice on the same line).
214 // The concat preprocessing operator (##) very unhelpfully will not expand macros see
215 // https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html for the gory details.
216 #define ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(backendId, guid, /*name,*/ ...) \
217  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS_UNIQUE_LOC(__LINE__,backendId, guid, /*name,*/ __VA_ARGS__)
218 
219 #define ARMNN_SCOPED_PROFILING_EVENT(backendId, name) \
220  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(backendId, armnn::EmptyOptional(), name, armnn::WallClockTimer())
221 
222 #define ARMNN_SCOPED_PROFILING_EVENT_GUID(backendId, name, guid) \
223  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(backendId, guid, name, armnn::WallClockTimer())
224 
225 // Workload Description definitons for profiling
226 #define ARMNN_REPORT_PROFILING_WORKLOAD_DESC(name, desc, infos, guid) \
227  armnn::ProfilingUpdateDescriptions(name, desc, infos, guid);
Event class records measurements reported by BeginEvent()/EndEvent() and returns measurements when Ev...
std::unique_ptr< Instrument > InstrumentPtr
Definition: Profiling.hpp:132
static ProfilerManager & GetInstance()
Definition: Profiling.cpp:526
uint32_t GetEventColor(const BackendId &backendId) const
Definition: Profiling.cpp:496
std::map< std::string, ProfilingEventStats > CalculateProfilingEventStats() const
Definition: Profiling.cpp:82
Copyright (c) 2021 ARM Limited and Contributors.
void IgnoreUnused(Ts &&...)
void AnalyzeEventSequenceAndWriteResults(EventIterType first, EventIterType last, std::ostream &outStream) const
void AnalyzeEventsAndWriteResults(std::ostream &outStream) const
Definition: Profiling.cpp:414
void EnableNetworkDetailsToStdOut()
Definition: Profiling.cpp:200
ScopedProfilingEvent(const BackendId &backendId, const Optional< profiling::ProfilingGuid > &guid, const std::string &name, Args &&... args)
Definition: Profiling.hpp:135
bool IsProfilingEnabled()
Checks whether profiling is enabled.
Definition: Profiling.cpp:553
std::unique_ptr< Event > EventPtr
Definition: Profiling.hpp:78
void EndEvent(Event *event)
Definition: Profiling.cpp:229
void Print(std::ostream &outStream) const
Definition: Profiling.cpp:356
DescPtr m_ProfilingDetails
Definition: Profiling.hpp:103
void PopulateInferences(std::vector< const Event *> &outInferences, int &outBaseLevel) const
Definition: Profiling.cpp:257
std::stack< Event * > m_Parents
Definition: Profiling.hpp:101
Contains information about TensorInfos of a layer.
void AddLayerDetails(const std::string &label, const DescriptorType &desc, const WorkloadInfo &infos, const profiling::ProfilingGuid guid)
Definition: Profiling.hpp:45
void PopulateDescendants(std::map< const Event *, std::vector< const Event *>> &outDescendantsMap) const
Definition: Profiling.cpp:271
void ProfilingUpdateDescriptions(const std::string &name, const DescriptorType &desc, const WorkloadInfo &infos, const profiling::ProfilingGuid guid)
Definition: Profiling.hpp:179
Event * BeginEvent(armnn::IProfiler *profiler, const BackendId &backendId, const std::string &name, std::vector< InstrumentPtr > &&instruments, const Optional< profiling::ProfilingGuid > &guid)
Definition: Profiling.cpp:205
std::unique_ptr< Instrument > InstrumentPtr
Definition: Profiling.hpp:34
std::vector< EventPtr > m_EventSequence
Definition: Profiling.hpp:102
std::unique_ptr< ProfilingDetails > DescPtr
Definition: Profiling.hpp:79
void EnableProfiling(bool enableProfiling)
Definition: Profiling.cpp:195