1 /*
2 Copyright (c) 2005-2022 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 #ifndef _FGT_GRAPH_TRACE_IMPL_H
18 #define _FGT_GRAPH_TRACE_IMPL_H
19
20 #include "../profiling.h"
21 #if (_MSC_VER >= 1900)
22 #include <intrin.h>
23 #endif
24
25 namespace tbb {
26 namespace detail {
27 namespace d1 {
28
29 template< typename T > class sender;
30 template< typename T > class receiver;
31
32 #if TBB_USE_PROFILING_TOOLS
33 #if __TBB_FLOW_TRACE_CODEPTR
34 #if (_MSC_VER >= 1900)
35 #define CODEPTR() (_ReturnAddress())
36 #elif __TBB_GCC_VERSION >= 40800
37 #define CODEPTR() ( __builtin_return_address(0))
38 #else
39 #define CODEPTR() nullptr
40 #endif
41 #else
42 #define CODEPTR() nullptr
43 #endif /* __TBB_FLOW_TRACE_CODEPTR */
44
fgt_alias_port(void * node,void * p,bool visible)45 static inline void fgt_alias_port(void *node, void *p, bool visible) {
46 if(visible)
47 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_NODE );
48 else
49 itt_relation_add( ITT_DOMAIN_FLOW, p, FLOW_NODE, __itt_relation_is_child_of, node, FLOW_NODE );
50 }
51
fgt_composite(void * codeptr,void * node,void * graph)52 static inline void fgt_composite ( void* codeptr, void *node, void *graph ) {
53 itt_make_task_group( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_COMPOSITE_NODE );
54 suppress_unused_warning( codeptr );
55 #if __TBB_FLOW_TRACE_CODEPTR
56 if (codeptr != nullptr) {
57 register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr);
58 }
59 #endif
60 }
61
fgt_internal_alias_input_port(void * node,void * p,string_resource_index name_index)62 static inline void fgt_internal_alias_input_port( void *node, void *p, string_resource_index name_index ) {
63 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index );
64 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_INPUT_PORT );
65 }
66
fgt_internal_alias_output_port(void * node,void * p,string_resource_index name_index)67 static inline void fgt_internal_alias_output_port( void *node, void *p, string_resource_index name_index ) {
68 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index );
69 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_OUTPUT_PORT );
70 }
71
72 template<typename InputType>
alias_input_port(void * node,receiver<InputType> * port,string_resource_index name_index)73 void alias_input_port(void *node, receiver<InputType>* port, string_resource_index name_index) {
74 // TODO: Make fgt_internal_alias_input_port a function template?
75 fgt_internal_alias_input_port( node, port, name_index);
76 }
77
78 template < typename PortsTuple, int N >
79 struct fgt_internal_input_alias_helper {
alias_portfgt_internal_input_alias_helper80 static void alias_port( void *node, PortsTuple &ports ) {
81 alias_input_port( node, &(std::get<N-1>(ports)), static_cast<string_resource_index>(FLOW_INPUT_PORT_0 + N - 1) );
82 fgt_internal_input_alias_helper<PortsTuple, N-1>::alias_port( node, ports );
83 }
84 };
85
86 template < typename PortsTuple >
87 struct fgt_internal_input_alias_helper<PortsTuple, 0> {
88 static void alias_port( void * /* node */, PortsTuple & /* ports */ ) { }
89 };
90
91 template<typename OutputType>
92 void alias_output_port(void *node, sender<OutputType>* port, string_resource_index name_index) {
93 // TODO: Make fgt_internal_alias_output_port a function template?
94 fgt_internal_alias_output_port( node, static_cast<void *>(port), name_index);
95 }
96
97 template < typename PortsTuple, int N >
98 struct fgt_internal_output_alias_helper {
99 static void alias_port( void *node, PortsTuple &ports ) {
100 alias_output_port( node, &(std::get<N-1>(ports)), static_cast<string_resource_index>(FLOW_OUTPUT_PORT_0 + N - 1) );
101 fgt_internal_output_alias_helper<PortsTuple, N-1>::alias_port( node, ports );
102 }
103 };
104
105 template < typename PortsTuple >
106 struct fgt_internal_output_alias_helper<PortsTuple, 0> {
107 static void alias_port( void * /*node*/, PortsTuple &/*ports*/ ) {
108 }
109 };
110
111 static inline void fgt_internal_create_input_port( void *node, void *p, string_resource_index name_index ) {
112 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index );
113 }
114
115 static inline void fgt_internal_create_output_port( void* codeptr, void *node, void *p, string_resource_index name_index ) {
116 itt_make_task_group(ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index);
117 suppress_unused_warning( codeptr );
118 #if __TBB_FLOW_TRACE_CODEPTR
119 if (codeptr != nullptr) {
120 register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr);
121 }
122 #endif
123 }
124
125 template<typename InputType>
126 void register_input_port(void *node, receiver<InputType>* port, string_resource_index name_index) {
127 // TODO: Make fgt_internal_create_input_port a function template?
128 fgt_internal_create_input_port(node, static_cast<void*>(port), name_index);
129 }
130
131 template < typename PortsTuple, int N >
132 struct fgt_internal_input_helper {
133 static void register_port( void *node, PortsTuple &ports ) {
134 register_input_port( node, &(std::get<N-1>(ports)), static_cast<string_resource_index>(FLOW_INPUT_PORT_0 + N - 1) );
135 fgt_internal_input_helper<PortsTuple, N-1>::register_port( node, ports );
136 }
137 };
138
139 template < typename PortsTuple >
140 struct fgt_internal_input_helper<PortsTuple, 1> {
141 static void register_port( void *node, PortsTuple &ports ) {
142 register_input_port( node, &(std::get<0>(ports)), FLOW_INPUT_PORT_0 );
143 }
144 };
145
146 template<typename OutputType>
147 void register_output_port(void* codeptr, void *node, sender<OutputType>* port, string_resource_index name_index) {
148 // TODO: Make fgt_internal_create_output_port a function template?
149 fgt_internal_create_output_port( codeptr, node, static_cast<void *>(port), name_index);
150 }
151
152 template < typename PortsTuple, int N >
153 struct fgt_internal_output_helper {
154 static void register_port( void* codeptr, void *node, PortsTuple &ports ) {
155 register_output_port( codeptr, node, &(std::get<N-1>(ports)), static_cast<string_resource_index>(FLOW_OUTPUT_PORT_0 + N - 1) );
156 fgt_internal_output_helper<PortsTuple, N-1>::register_port( codeptr, node, ports );
157 }
158 };
159
160 template < typename PortsTuple >
161 struct fgt_internal_output_helper<PortsTuple,1> {
162 static void register_port( void* codeptr, void *node, PortsTuple &ports ) {
163 register_output_port( codeptr, node, &(std::get<0>(ports)), FLOW_OUTPUT_PORT_0 );
164 }
165 };
166
167 template< typename NodeType >
168 void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) {
169 void *addr = (void *)( static_cast< receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) );
170 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
171 }
172
173 template< typename NodeType >
174 void fgt_multiinput_multioutput_node_desc( const NodeType *node, const char *desc ) {
175 void *addr = const_cast<NodeType *>(node);
176 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
177 }
178
179 template< typename NodeType >
180 static inline void fgt_node_desc( const NodeType *node, const char *desc ) {
181 void *addr = (void *)( static_cast< sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) );
182 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
183 }
184
185 static inline void fgt_graph_desc( const void *g, const char *desc ) {
186 void *addr = const_cast< void *>(g);
187 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_GRAPH, FLOW_OBJECT_NAME, desc );
188 }
189
190 static inline void fgt_body( void *node, void *body ) {
191 itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE );
192 }
193
194 template< int N, typename PortsTuple >
195 static inline void fgt_multioutput_node(void* codeptr, string_resource_index t, void *g, void *input_port, PortsTuple &ports ) {
196 itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t );
197 fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 );
198 fgt_internal_output_helper<PortsTuple, N>::register_port(codeptr, input_port, ports );
199 }
200
201 template< int N, typename PortsTuple >
202 static inline void fgt_multioutput_node_with_body( void* codeptr, string_resource_index t, void *g, void *input_port, PortsTuple &ports, void *body ) {
203 itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t );
204 fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 );
205 fgt_internal_output_helper<PortsTuple, N>::register_port( codeptr, input_port, ports );
206 fgt_body( input_port, body );
207 }
208
209 template< int N, typename PortsTuple >
210 static inline void fgt_multiinput_node( void* codeptr, string_resource_index t, void *g, PortsTuple &ports, void *output_port) {
211 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
212 fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
213 fgt_internal_input_helper<PortsTuple, N>::register_port( output_port, ports );
214 }
215
216 static inline void fgt_multiinput_multioutput_node( void* codeptr, string_resource_index t, void *n, void *g ) {
217 itt_make_task_group( ITT_DOMAIN_FLOW, n, FLOW_NODE, g, FLOW_GRAPH, t );
218 suppress_unused_warning( codeptr );
219 #if __TBB_FLOW_TRACE_CODEPTR
220 if (codeptr != nullptr) {
221 register_node_addr(ITT_DOMAIN_FLOW, n, FLOW_NODE, CODE_ADDRESS, &codeptr);
222 }
223 #endif
224 }
225
226 static inline void fgt_node( void* codeptr, string_resource_index t, void *g, void *output_port ) {
227 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
228 fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
229 }
230
231 static void fgt_node_with_body( void* codeptr, string_resource_index t, void *g, void *output_port, void *body ) {
232 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
233 fgt_internal_create_output_port(codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
234 fgt_body( output_port, body );
235 }
236
237 static inline void fgt_node( void* codeptr, string_resource_index t, void *g, void *input_port, void *output_port ) {
238 fgt_node( codeptr, t, g, output_port );
239 fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 );
240 }
241
242 static inline void fgt_node_with_body( void* codeptr, string_resource_index t, void *g, void *input_port, void *output_port, void *body ) {
243 fgt_node_with_body( codeptr, t, g, output_port, body );
244 fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 );
245 }
246
247
248 static inline void fgt_node( void* codeptr, string_resource_index t, void *g, void *input_port, void *decrement_port, void *output_port ) {
249 fgt_node( codeptr, t, g, input_port, output_port );
250 fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 );
251 }
252
253 static inline void fgt_make_edge( void *output_port, void *input_port ) {
254 itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_predecessor_to, input_port, FLOW_INPUT_PORT);
255 }
256
257 static inline void fgt_remove_edge( void *output_port, void *input_port ) {
258 itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_sibling_of, input_port, FLOW_INPUT_PORT);
259 }
260
261 static inline void fgt_graph( void *g ) {
262 itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, nullptr, FLOW_NULL, FLOW_GRAPH );
263 }
264
265 static inline void fgt_begin_body( void *body ) {
266 itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, nullptr, FLOW_NULL, FLOW_BODY );
267 }
268
269 static inline void fgt_end_body( void * ) {
270 itt_task_end( ITT_DOMAIN_FLOW );
271 }
272
273 static inline void fgt_async_try_put_begin( void *node, void *port ) {
274 itt_task_begin( ITT_DOMAIN_FLOW, port, FLOW_OUTPUT_PORT, node, FLOW_NODE, FLOW_OUTPUT_PORT );
275 }
276
277 static inline void fgt_async_try_put_end( void *, void * ) {
278 itt_task_end( ITT_DOMAIN_FLOW );
279 }
280
281 static inline void fgt_async_reserve( void *node, void *graph ) {
282 itt_region_begin( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_NULL );
283 }
284
285 static inline void fgt_async_commit( void *node, void * /*graph*/) {
286 itt_region_end( ITT_DOMAIN_FLOW, node, FLOW_NODE );
287 }
288
289 static inline void fgt_reserve_wait( void *graph ) {
290 itt_region_begin( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH, nullptr, FLOW_NULL, FLOW_NULL );
291 }
292
293 static inline void fgt_release_wait( void *graph ) {
294 itt_region_end( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH );
295 }
296
297 #else // TBB_USE_PROFILING_TOOLS
298
299 #define CODEPTR() nullptr
300
301 static inline void fgt_alias_port(void * /*node*/, void * /*p*/, bool /*visible*/ ) { }
302
303 static inline void fgt_composite ( void* /*codeptr*/, void * /*node*/, void * /*graph*/ ) { }
304
305 static inline void fgt_graph( void * /*g*/ ) { }
306
307 template< typename NodeType >
308 static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
309
310 template< typename NodeType >
311 static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
312
313 static inline void fgt_graph_desc( const void * /*g*/, const char * /*desc*/ ) { }
314
315 template< int N, typename PortsTuple >
316 static inline void fgt_multioutput_node( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { }
317
318 template< int N, typename PortsTuple >
319 static inline void fgt_multioutput_node_with_body( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { }
320
321 template< int N, typename PortsTuple >
322 static inline void fgt_multiinput_node( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { }
323
324 static inline void fgt_multiinput_multioutput_node( void* /*codeptr*/, string_resource_index /*t*/, void * /*node*/, void * /*graph*/ ) { }
325
326 static inline void fgt_node( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { }
327 static inline void fgt_node( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { }
328
329 static inline void fgt_node_with_body( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { }
330 static inline void fgt_node_with_body( void* /*codeptr*/, string_resource_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { }
331
332 static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { }
333 static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { }
334
335 static inline void fgt_begin_body( void * /*body*/ ) { }
336 static inline void fgt_end_body( void * /*body*/) { }
337
338 static inline void fgt_async_try_put_begin( void * /*node*/, void * /*port*/ ) { }
339 static inline void fgt_async_try_put_end( void * /*node*/ , void * /*port*/ ) { }
340 static inline void fgt_async_reserve( void * /*node*/, void * /*graph*/ ) { }
341 static inline void fgt_async_commit( void * /*node*/, void * /*graph*/ ) { }
342 static inline void fgt_reserve_wait( void * /*graph*/ ) { }
343 static inline void fgt_release_wait( void * /*graph*/ ) { }
344
345 template< typename NodeType >
346 void fgt_multiinput_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
347
348 template < typename PortsTuple, int N >
349 struct fgt_internal_input_alias_helper {
350 static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { }
351 };
352
353 template < typename PortsTuple, int N >
354 struct fgt_internal_output_alias_helper {
355 static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { }
356 };
357
358 #endif // TBB_USE_PROFILING_TOOLS
359
360 } // d1
361 } // namespace detail
362 } // namespace tbb
363
364 #endif // _FGT_GRAPH_TRACE_IMPL_H
365