itt.hpp
Go to the documentation of this file.
1 //*****************************************************************************
2 // Copyright 2017-2020 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //*****************************************************************************
16 
17 /**
18  * @brief Defines API to trace using Intel ITT.
19  * @file itt.hpp
20  */
21 
22 #pragma once
25 #include <string>
26 #include <utility>
27 
28 namespace openvino
29 {
30  namespace itt
31  {
32  /**
33  * @typedef domain_t
34  * @ingroup ie_dev_profiling
35  * @brief A domain type which enables tagging trace data for different modules or libraries in a program.
36  */
37  typedef struct domain_ {} *domain_t;
38 
39  /**
40  * @typedef handle_t
41  * @ingroup ie_dev_profiling
42  * @brief Annotation handle for section of code which would be named at runtime.
43  */
44  typedef struct handle_ {} *handle_t;
45 
46 /**
47  * @cond
48  */
49  namespace internal
50  {
51  domain_t domain(char const* name);
52  handle_t handle(char const* name);
53  void taskBegin(domain_t d, handle_t t);
54  void taskEnd(domain_t d);
55  void threadName(const char* name);
56  }
57 /**
58  * @endcond
59  */
60 
61  /**
62  * @fn void threadName(const char* name)
63  * @ingroup ie_dev_profiling
64  * @brief Set thread name using a char string.
65  * @param name [in] The thread name
66  */
67  inline void threadName(const char* name)
68  {
69  internal::threadName(name);
70  }
71 
72  inline void threadName(const std::string &name)
73  {
74  internal::threadName(name.c_str());
75  }
76 
77  inline handle_t handle(char const *name)
78  {
79  return internal::handle(name);
80  }
81 
82  inline handle_t handle(const std::string &name)
83  {
84  return internal::handle(name.c_str());
85  }
86 
87  /**
88  * @fn handle_t handle(char const *name)
89  * @ingroup ie_dev_profiling
90  * @brief Create annotation handle with a given name.
91  * @details If template function is instantiated with a tag, the handle is created as a singleton.
92  * @param name [in] The annotation name
93  */
94  template <typename Tag>
95  handle_t handle(char const *name)
96  {
97  static auto h = internal::handle(name);
98  return h;
99  }
100 
101  template <typename Tag>
102  handle_t handle(const std::string &name)
103  {
104  return handle<Tag>(name.c_str());
105  }
106 
107  template <typename Tag>
108  handle_t handle(handle_t h)
109  {
110  return h;
111  }
112 
113  /**
114  * @class ScopedTask
115  * @ingroup ie_dev_profiling
116  * @brief Used to annotate section of code which would be named at runtime
117  * @tparam The @p domain parameter is domain type which shoud be defined with OV_ITT_DOMAIN() macro.
118  */
119  template <domain_t(*domain)()>
120  struct ScopedTask
121  {
122  /**
123  * @brief Construct ScopedTask with defined annotation handle
124  */
125  ScopedTask(handle_t taskHandle) noexcept
126  {
127  internal::taskBegin(domain(), taskHandle);
128  }
129 
130  /**
131  * @brief The ScopedTask destructor closes or ends the task scope
132  */
133  ~ScopedTask() noexcept { internal::taskEnd(domain()); }
134 
135  ScopedTask(const ScopedTask&) = delete;
136  ScopedTask& operator=(const ScopedTask&) = delete;
137  };
138 
139  /**
140  * @class TaskChain
141  * @ingroup ie_dev_profiling
142  * @brief Used to annotate a sequence of sections of code which would be named at runtime
143  * @tparam The @p domain parameter is domain type which shoud be defined with OV_ITT_DOMAIN() macro.
144  */
145  template <domain_t(*domain)()>
146  class TaskChain
147  {
148  uint32_t _id = 1;
149  std::string _prefix;
150  bool _skipped {};
151 
152  TaskChain(const TaskChain&) = delete;
153  TaskChain& operator=(const TaskChain&) = delete;
154 
155  public:
156  /**
157  * @brief Construct TaskChain with defined annotation handle
158  */
159  TaskChain(handle_t taskHandle, std::string && prefix) noexcept
160  : _prefix(std::forward<std::string>(prefix))
161  {
162  internal::taskBegin(domain(), taskHandle);
163  }
164 
165  /**
166  * @brief The TaskChain destructor closes or ends the task scope
167  */
168  ~TaskChain() noexcept { skip(); }
169 
170  /**
171  * @brief Ends the previous task from the chain and starts a new one with the given annotation handle
172  */
173  void next(handle_t taskHandle)
174  {
175  if(_skipped)
176  _skipped = false;
177  else
178  internal::taskEnd(domain());
179  internal::taskBegin(domain(), taskHandle);
180  ++_id;
181  }
182 
183  /*
184  * @brief Generating a task name using a sequence number.
185  */
186  std::string taskName() const
187  {
188  return _prefix + "_" + std::to_string(_id);
189  }
190 
191  /*
192  * @brief Generating a task name using a scope name.
193  */
194  std::string taskNameOrHandle(const std::string & name) const
195  {
196  return _prefix + "_" + name;
197  }
198 
199  /*
200  * @brief Returns a handle provided as argument.
201  */
202  handle_t taskNameOrHandle(handle_t handle) const
203  {
204  return handle;
205  }
206 
207  /*
208  * @brief Skips the remaining task scope.
209  */
210  void skip()
211  {
212  if(!_skipped)
213  {
214  _skipped = true;
215  internal::taskEnd(domain());
216  }
217  }
218  };
219 
220 /**
221  * @def OV_ITT_DOMAIN(domainName)
222  * @ingroup ie_dev_profiling
223  * @brief Declare domain with a given name.
224  * @param domainName [in] Known at compile time name of module or library (the domain name).
225  * @param domainDisplayName [in] Domain name used as the ITT counter name and displayed in Intel VTune. Parameter is optional.
226  */
227 #define OV_ITT_DOMAIN(...) OV_ITT_MACRO_OVERLOAD(OV_ITT_DOMAIN, __VA_ARGS__)
228 
229 /**
230  * @cond
231  */
232 
233 #define OV_ITT_CONCAT2(X, Y) X ## Y
234 #define OV_ITT_CONCAT(X, Y) OV_ITT_CONCAT2(X, Y)
235 
236 #define OV_ITT_DOMAIN_1(domainName) \
237 inline openvino::itt::domain_t domainName() noexcept \
238 { \
239  static auto d = openvino::itt::internal::domain(#domainName); \
240  return d; \
241 }
242 
243 #define OV_ITT_DOMAIN_2(domainName, domainDisplayName) \
244 inline openvino::itt::domain_t domainName() noexcept \
245 { \
246  static auto d = openvino::itt::internal::domain(domainDisplayName); \
247  return d; \
248 }
249 
250 /**
251  * @endcond
252  */
253 
254 /**
255  * @def OV_ITT_SCOPED_TASK(domain, handleOrTaskName)
256  * @ingroup ie_dev_profiling
257  * @brief Annotate section of code till scope exit to be profiled using known @p handle or @p taskName as section id.
258  * @details In case if handle or taskName absent, the current function name is used.
259  * @param domainName [in] Known at compile time name of module or library (the domain name).
260  * @param handleOrTaskName [in] The annotation name or handle for section of code. Parameter is optional.
261  */
262 #define OV_ITT_SCOPED_TASK(...) OV_ITT_MACRO_OVERLOAD(OV_ITT_SCOPED_TASK, __VA_ARGS__)
263 
264 /**
265  * @cond
266  */
267 
268 #define OV_ITT_SCOPED_TASK_1(domain) \
269  openvino::itt::ScopedTask<domain> OV_ITT_CONCAT(ittScopedTask, __LINE__) \
270  (openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)>(ITT_FUNCTION_NAME));
271 
272 #define OV_ITT_SCOPED_TASK_2(domain, taskOrTaskName) \
273  openvino::itt::ScopedTask<domain> OV_ITT_CONCAT(ittScopedTask, __LINE__) \
274  (openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)>(taskOrTaskName));
275 
276 /**
277  * @endcond
278  */
279 
280 /**
281  * @def OV_ITT_TASK_CHAIN(chainId, domain, prefix, taskName)
282  * @ingroup ie_dev_profiling
283  * @brief Begins the sequrence of an annotated sections of code using @p prefix and @p taskName as section id.
284  * @details In case if prefix absent, the current function name is used,
285  * if taskName absent, the first chain index is used, i.e 1.
286  * @param chainId [in] The tasks chain identifier.
287  * @param domainName [in] Known at compile time name of module or library (the domain name).
288  * @param prefix [in] The task chain name prefix. The task name starts with this prefix. Parameter is optional.
289  * @param taskName [in] The annotation name for section of code. Parameter is optional.
290  */
291 #define OV_ITT_TASK_CHAIN(...) OV_ITT_MACRO_OVERLOAD(OV_ITT_TASK_CHAIN, __VA_ARGS__)
292 
293 /**
294  * @cond
295  */
296 
297 #define OV_ITT_TASK_CHAIN_2(chainId, domain) \
298  openvino::itt::TaskChain<domain> chainId \
299  (openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)> \
300  (std::string(ITT_FUNCTION_NAME) + "_1"), \
301  ITT_FUNCTION_NAME);
302 
303 #define OV_ITT_TASK_CHAIN_3(chainId, domain, prefix) \
304  openvino::itt::TaskChain<domain> chainId \
305  (openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)> \
306  (std::string(prefix) + "_1"), \
307  prefix);
308 
309 #define OV_ITT_TASK_CHAIN_4(chainId, domain, prefix, taskName) \
310  openvino::itt::TaskChain<domain> chainId \
311  (openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)> \
312  (std::string(prefix) + "_" + taskName), \
313  prefix);
314 
315 /**
316  * @endcond
317  */
318 
319 /**
320  * @def OV_ITT_TASK_NEXT(chainId, taskName)
321  * @ingroup ie_dev_profiling
322  * @brief Inserts new annotated section of code to tasks chain using @p taskName as section id.
323  * @details If taskName is missing, the current chain index is used.
324  * @param chainId [in] The tasks chain identifier.
325  * @param taskOrTaskName [in] The annotation name or handle for section of code. Parameter is optional.
326  */
327 #define OV_ITT_TASK_NEXT(...) OV_ITT_MACRO_OVERLOAD(OV_ITT_TASK_NEXT, __VA_ARGS__)
328 
329 /**
330  * @cond
331  */
332 
333 #define OV_ITT_TASK_NEXT_1(chainId) \
334  chainId.next(openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)>(chainId.taskName()));
335 
336 #define OV_ITT_TASK_NEXT_2(chainId, taskOrTaskName) \
337  chainId.next(openvino::itt::handle<struct OV_ITT_CONCAT(Task, __LINE__)>(chainId.taskNameOrHandle(taskOrTaskName)));
338 
339 /**
340  * @endcond
341  */
342 
343 /**
344  * @def OV_ITT_TASK_SKIP(chainId)
345  * @ingroup ie_dev_profiling
346  * @brief Skips the remaining task scope.
347  * @param chainId [in] The tasks chain identifier.
348  */
349 #define OV_ITT_TASK_SKIP(chainId) chainId.skip();
350 
351  } // namespace itt
352 } // namespace openvino
Used to annotate a sequence of sections of code which would be named at runtime.
Definition: itt.hpp:147
TaskChain(handle_t taskHandle, std::string &&prefix) noexcept
Construct TaskChain with defined annotation handle.
Definition: itt.hpp:159
~TaskChain() noexcept
The TaskChain destructor closes or ends the task scope.
Definition: itt.hpp:168
void next(handle_t taskHandle)
Ends the previous task from the chain and starts a new one with the given annotation handle.
Definition: itt.hpp:173
Defines a macro to get the name of a function.
handle_t handle(char const *name)
Create annotation handle with a given name.
Definition: itt.hpp:77
struct openvino::itt::handle_ * handle_t
Annotation handle for section of code which would be named at runtime.
void threadName(const char *name)
Set thread name using a char string.
Definition: itt.hpp:67
Macro overloading feature support.
Used to annotate section of code which would be named at runtime.
Definition: itt.hpp:121
ScopedTask(handle_t taskHandle) noexcept
Construct ScopedTask with defined annotation handle.
Definition: itt.hpp:125
~ScopedTask() noexcept
The ScopedTask destructor closes or ends the task scope.
Definition: itt.hpp:133
Definition: itt.hpp:37
Definition: itt.hpp:44