1 /* 2 Copyright (c) 2005-2021 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() NULL 40 #endif 41 #else 42 #define CODEPTR() NULL 43 #endif /* __TBB_FLOW_TRACE_CODEPTR */ 44 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 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 != NULL) { 57 register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr); 58 } 59 #endif 60 } 61 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 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> 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 { 80 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 != NULL) { 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 != NULL) { 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, NULL, 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, NULL, 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, NULL, 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() NULL 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