xref: /oneTBB/include/oneapi/tbb/profiling.h (revision 0cf592bd)
149e08aacStbbdev /*
2*0cf592bdSAndrew Corrigan     Copyright (c) 2005-2023 Intel Corporation
349e08aacStbbdev 
449e08aacStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
549e08aacStbbdev     you may not use this file except in compliance with the License.
649e08aacStbbdev     You may obtain a copy of the License at
749e08aacStbbdev 
849e08aacStbbdev         http://www.apache.org/licenses/LICENSE-2.0
949e08aacStbbdev 
1049e08aacStbbdev     Unless required by applicable law or agreed to in writing, software
1149e08aacStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1249e08aacStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349e08aacStbbdev     See the License for the specific language governing permissions and
1449e08aacStbbdev     limitations under the License.
1549e08aacStbbdev */
1649e08aacStbbdev 
1749e08aacStbbdev #ifndef __TBB_profiling_H
1849e08aacStbbdev #define __TBB_profiling_H
1949e08aacStbbdev 
2049e08aacStbbdev #include "detail/_config.h"
2149e08aacStbbdev #include <cstdint>
2249e08aacStbbdev 
2349e08aacStbbdev #include <string>
2449e08aacStbbdev 
2549e08aacStbbdev namespace tbb {
2649e08aacStbbdev namespace detail {
2749e08aacStbbdev inline namespace d0 {
2849e08aacStbbdev     // include list of index names
2949e08aacStbbdev     #define TBB_STRING_RESOURCE(index_name,str) index_name,
3049e08aacStbbdev     enum string_resource_index : std::uintptr_t {
3149e08aacStbbdev         #include "detail/_string_resource.h"
3249e08aacStbbdev         NUM_STRINGS
3349e08aacStbbdev     };
3449e08aacStbbdev     #undef TBB_STRING_RESOURCE
3549e08aacStbbdev 
3649e08aacStbbdev     enum itt_relation
3749e08aacStbbdev     {
3849e08aacStbbdev     __itt_relation_is_unknown = 0,
3949e08aacStbbdev     __itt_relation_is_dependent_on,         /**< "A is dependent on B" means that A cannot start until B completes */
4049e08aacStbbdev     __itt_relation_is_sibling_of,           /**< "A is sibling of B" means that A and B were created as a group */
4149e08aacStbbdev     __itt_relation_is_parent_of,            /**< "A is parent of B" means that A created B */
4249e08aacStbbdev     __itt_relation_is_continuation_of,      /**< "A is continuation of B" means that A assumes the dependencies of B */
4349e08aacStbbdev     __itt_relation_is_child_of,             /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */
4449e08aacStbbdev     __itt_relation_is_continued_by,         /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */
4549e08aacStbbdev     __itt_relation_is_predecessor_to        /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */
4649e08aacStbbdev     };
4749e08aacStbbdev 
4849e08aacStbbdev //! Unicode support
498827ea7dSLong Nguyen #if (_WIN32||_WIN64)
5049e08aacStbbdev     //! Unicode character type. Always wchar_t on Windows.
5149e08aacStbbdev     using tchar = wchar_t;
5249e08aacStbbdev #else /* !WIN */
5349e08aacStbbdev     using tchar = char;
5449e08aacStbbdev #endif /* !WIN */
5549e08aacStbbdev 
5649e08aacStbbdev } // namespace d0
5749e08aacStbbdev } // namespace detail
5849e08aacStbbdev } // namespace tbb
5949e08aacStbbdev 
6049e08aacStbbdev #include <atomic>
6149e08aacStbbdev #if _WIN32||_WIN64
6249e08aacStbbdev #include <stdlib.h>  /* mbstowcs_s */
6349e08aacStbbdev #endif
6449e08aacStbbdev // Need these to work regardless of tools support
6549e08aacStbbdev namespace tbb {
6649e08aacStbbdev namespace detail {
6749e08aacStbbdev namespace d1 {
6849e08aacStbbdev     enum notify_type {prepare=0, cancel, acquired, releasing, destroy};
6949e08aacStbbdev     enum itt_domain_enum { ITT_DOMAIN_FLOW=0, ITT_DOMAIN_MAIN=1, ITT_DOMAIN_ALGO=2, ITT_NUM_DOMAINS };
7049e08aacStbbdev } // namespace d1
7149e08aacStbbdev 
7249e08aacStbbdev namespace r1 {
738827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC call_itt_notify(int t, void* ptr);
748827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC create_itt_sync(void* ptr, const tchar* objtype, const tchar* objname);
758827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_make_task_group(d1::itt_domain_enum domain, void* group, unsigned long long group_extra,
7649e08aacStbbdev         void* parent, unsigned long long parent_extra, string_resource_index name_index);
778827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_task_begin(d1::itt_domain_enum domain, void* task, unsigned long long task_extra,
7849e08aacStbbdev         void* parent, unsigned long long parent_extra, string_resource_index name_index);
798827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_task_end(d1::itt_domain_enum domain);
808827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_set_sync_name(void* obj, const tchar* name);
818827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_metadata_str_add(d1::itt_domain_enum domain, void* addr, unsigned long long addr_extra,
8249e08aacStbbdev         string_resource_index key, const char* value);
838827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_metadata_ptr_add(d1::itt_domain_enum domain, void* addr, unsigned long long addr_extra,
8449e08aacStbbdev         string_resource_index key, void* value);
858827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_relation_add(d1::itt_domain_enum domain, void* addr0, unsigned long long addr0_extra,
8649e08aacStbbdev         itt_relation relation, void* addr1, unsigned long long addr1_extra);
878827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_region_begin(d1::itt_domain_enum domain, void* region, unsigned long long region_extra,
8849e08aacStbbdev         void* parent, unsigned long long parent_extra, string_resource_index /* name_index */);
898827ea7dSLong Nguyen     TBB_EXPORT void __TBB_EXPORTED_FUNC itt_region_end(d1::itt_domain_enum domain, void* region, unsigned long long region_extra);
9049e08aacStbbdev } // namespace r1
9149e08aacStbbdev 
9249e08aacStbbdev namespace d1 {
938827ea7dSLong Nguyen #if TBB_USE_PROFILING_TOOLS && (_WIN32||_WIN64)
multibyte_to_widechar(wchar_t * wcs,const char * mbs,std::size_t bufsize)9449e08aacStbbdev     inline std::size_t multibyte_to_widechar(wchar_t* wcs, const char* mbs, std::size_t bufsize) {
9549e08aacStbbdev         std::size_t len;
9649e08aacStbbdev         mbstowcs_s(&len, wcs, bufsize, mbs, _TRUNCATE);
9749e08aacStbbdev         return len;   // mbstowcs_s counts null terminator
9849e08aacStbbdev     }
9949e08aacStbbdev #endif
10049e08aacStbbdev 
10149e08aacStbbdev #if TBB_USE_PROFILING_TOOLS
create_itt_sync(void * ptr,const char * objtype,const char * objname)10249e08aacStbbdev     inline void create_itt_sync(void *ptr, const char *objtype, const char *objname) {
1038827ea7dSLong Nguyen #if (_WIN32||_WIN64)
10449e08aacStbbdev         std::size_t len_type = multibyte_to_widechar(nullptr, objtype, 0);
10549e08aacStbbdev         wchar_t *type = new wchar_t[len_type];
10649e08aacStbbdev         multibyte_to_widechar(type, objtype, len_type);
10749e08aacStbbdev         std::size_t len_name = multibyte_to_widechar(nullptr, objname, 0);
10849e08aacStbbdev         wchar_t *name = new wchar_t[len_name];
10949e08aacStbbdev         multibyte_to_widechar(name, objname, len_name);
11049e08aacStbbdev #else // WIN
11149e08aacStbbdev         const char *type = objtype;
11249e08aacStbbdev         const char *name = objname;
11349e08aacStbbdev #endif
11449e08aacStbbdev         r1::create_itt_sync(ptr, type, name);
11549e08aacStbbdev 
1168827ea7dSLong Nguyen #if (_WIN32||_WIN64)
11749e08aacStbbdev         delete[] type;
11849e08aacStbbdev         delete[] name;
11949e08aacStbbdev #endif // WIN
12049e08aacStbbdev     }
12149e08aacStbbdev 
12249e08aacStbbdev // Distinguish notifications on task for reducing overheads
12349e08aacStbbdev #if TBB_USE_PROFILING_TOOLS == 2
call_itt_task_notify(d1::notify_type t,void * ptr)12449e08aacStbbdev     inline void call_itt_task_notify(d1::notify_type t, void *ptr) {
125*0cf592bdSAndrew Corrigan         r1::call_itt_notify(static_cast<int>(t), ptr);
12649e08aacStbbdev     }
12749e08aacStbbdev #else
call_itt_task_notify(d1::notify_type,void *)12849e08aacStbbdev     inline void call_itt_task_notify(d1::notify_type, void *) {}
12949e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS
13049e08aacStbbdev 
call_itt_notify(d1::notify_type t,void * ptr)13149e08aacStbbdev     inline void call_itt_notify(d1::notify_type t, void *ptr) {
132*0cf592bdSAndrew Corrigan         r1::call_itt_notify(static_cast<int>(t), ptr);
13349e08aacStbbdev     }
13449e08aacStbbdev 
13549e08aacStbbdev #if (_WIN32||_WIN64) && !__MINGW32__
itt_set_sync_name(void * obj,const wchar_t * name)13649e08aacStbbdev     inline void itt_set_sync_name(void* obj, const wchar_t* name) {
13749e08aacStbbdev         r1::itt_set_sync_name(obj, name);
13849e08aacStbbdev     }
itt_set_sync_name(void * obj,const char * name)13949e08aacStbbdev     inline void itt_set_sync_name(void* obj, const char* name) {
14049e08aacStbbdev         std::size_t len_name = multibyte_to_widechar(nullptr, name, 0);
14149e08aacStbbdev         wchar_t *obj_name = new wchar_t[len_name];
14249e08aacStbbdev         multibyte_to_widechar(obj_name, name, len_name);
14349e08aacStbbdev         r1::itt_set_sync_name(obj, obj_name);
14449e08aacStbbdev         delete[] obj_name;
14549e08aacStbbdev     }
14649e08aacStbbdev #else
itt_set_sync_name(void * obj,const char * name)14749e08aacStbbdev     inline void itt_set_sync_name( void* obj, const char* name) {
14849e08aacStbbdev         r1::itt_set_sync_name(obj, name);
14949e08aacStbbdev     }
15049e08aacStbbdev #endif //WIN
15149e08aacStbbdev 
itt_make_task_group(itt_domain_enum domain,void * group,unsigned long long group_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)15249e08aacStbbdev     inline void itt_make_task_group(itt_domain_enum domain, void* group, unsigned long long group_extra,
15349e08aacStbbdev         void* parent, unsigned long long parent_extra, string_resource_index name_index) {
15449e08aacStbbdev         r1::itt_make_task_group(domain, group, group_extra, parent, parent_extra, name_index);
15549e08aacStbbdev     }
15649e08aacStbbdev 
itt_metadata_str_add(itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,const char * value)15749e08aacStbbdev     inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra,
15849e08aacStbbdev                                         string_resource_index key, const char *value ) {
15949e08aacStbbdev         r1::itt_metadata_str_add( domain, addr, addr_extra, key, value );
16049e08aacStbbdev     }
16149e08aacStbbdev 
register_node_addr(itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,void * value)16249e08aacStbbdev     inline void register_node_addr(itt_domain_enum domain, void *addr, unsigned long long addr_extra,
16349e08aacStbbdev         string_resource_index key, void *value) {
16449e08aacStbbdev         r1::itt_metadata_ptr_add(domain, addr, addr_extra, key, value);
16549e08aacStbbdev     }
16649e08aacStbbdev 
itt_relation_add(itt_domain_enum domain,void * addr0,unsigned long long addr0_extra,itt_relation relation,void * addr1,unsigned long long addr1_extra)16749e08aacStbbdev     inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra,
16849e08aacStbbdev                                     itt_relation relation, void *addr1, unsigned long long addr1_extra ) {
16949e08aacStbbdev         r1::itt_relation_add( domain, addr0, addr0_extra, relation, addr1, addr1_extra );
17049e08aacStbbdev     }
17149e08aacStbbdev 
itt_task_begin(itt_domain_enum domain,void * task,unsigned long long task_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)17249e08aacStbbdev     inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra,
17349e08aacStbbdev                                                     void *parent, unsigned long long parent_extra, string_resource_index name_index ) {
17449e08aacStbbdev         r1::itt_task_begin( domain, task, task_extra, parent, parent_extra, name_index );
17549e08aacStbbdev     }
17649e08aacStbbdev 
itt_task_end(itt_domain_enum domain)17749e08aacStbbdev     inline void itt_task_end( itt_domain_enum domain ) {
17849e08aacStbbdev         r1::itt_task_end( domain );
17949e08aacStbbdev     }
18049e08aacStbbdev 
itt_region_begin(itt_domain_enum domain,void * region,unsigned long long region_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)18149e08aacStbbdev     inline void itt_region_begin( itt_domain_enum domain, void *region, unsigned long long region_extra,
18249e08aacStbbdev                                     void *parent, unsigned long long parent_extra, string_resource_index name_index ) {
18349e08aacStbbdev         r1::itt_region_begin( domain, region, region_extra, parent, parent_extra, name_index );
18449e08aacStbbdev     }
18549e08aacStbbdev 
itt_region_end(itt_domain_enum domain,void * region,unsigned long long region_extra)18649e08aacStbbdev     inline void itt_region_end( itt_domain_enum domain, void *region, unsigned long long region_extra  ) {
18749e08aacStbbdev         r1::itt_region_end( domain, region, region_extra );
18849e08aacStbbdev     }
18949e08aacStbbdev #else
create_itt_sync(void *,const char *,const char *)19049e08aacStbbdev     inline void create_itt_sync(void* /*ptr*/, const char* /*objtype*/, const char* /*objname*/) {}
19149e08aacStbbdev 
call_itt_notify(notify_type,void *)19249e08aacStbbdev     inline void call_itt_notify(notify_type /*t*/, void* /*ptr*/) {}
19349e08aacStbbdev 
call_itt_task_notify(notify_type,void *)19449e08aacStbbdev     inline void call_itt_task_notify(notify_type /*t*/, void* /*ptr*/) {}
19549e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS
19649e08aacStbbdev 
19749e08aacStbbdev #if TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2)
19849e08aacStbbdev class event {
19949e08aacStbbdev /** This class supports user event traces through itt.
20049e08aacStbbdev     Common use-case is tagging data flow graph tasks (data-id)
20149e08aacStbbdev     and visualization by Intel Advisor Flow Graph Analyzer (FGA)  **/
20249e08aacStbbdev //  TODO: Replace implementation by itt user event api.
20349e08aacStbbdev 
20449e08aacStbbdev     const std::string my_name;
20549e08aacStbbdev 
emit_trace(const std::string & input)20649e08aacStbbdev     static void emit_trace(const std::string &input) {
20757f524caSIlya Isaev         itt_metadata_str_add( ITT_DOMAIN_FLOW, nullptr, FLOW_NULL, USER_EVENT, ( "FGA::DATAID::" + input ).c_str() );
20849e08aacStbbdev     }
20949e08aacStbbdev 
21049e08aacStbbdev public:
event(const std::string & input)21149e08aacStbbdev     event(const std::string &input)
21249e08aacStbbdev               : my_name( input )
21349e08aacStbbdev     { }
21449e08aacStbbdev 
emit()21549e08aacStbbdev     void emit() {
21649e08aacStbbdev         emit_trace(my_name);
21749e08aacStbbdev     }
21849e08aacStbbdev 
emit(const std::string & description)21949e08aacStbbdev     static void emit(const std::string &description) {
22049e08aacStbbdev         emit_trace(description);
22149e08aacStbbdev     }
22249e08aacStbbdev 
22349e08aacStbbdev };
22449e08aacStbbdev #else // TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2)
22549e08aacStbbdev // Using empty struct if user event tracing is disabled:
22649e08aacStbbdev struct event {
eventevent22749e08aacStbbdev     event(const std::string &) { }
22849e08aacStbbdev 
emitevent22949e08aacStbbdev     void emit() { }
23049e08aacStbbdev 
emitevent23149e08aacStbbdev     static void emit(const std::string &) { }
23249e08aacStbbdev };
23349e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2)
23449e08aacStbbdev } // namespace d1
23549e08aacStbbdev } // namespace detail
23649e08aacStbbdev 
23749e08aacStbbdev namespace profiling {
23849e08aacStbbdev     using detail::d1::event;
23949e08aacStbbdev }
24049e08aacStbbdev } // namespace tbb
24149e08aacStbbdev 
24249e08aacStbbdev 
24349e08aacStbbdev #endif /* __TBB_profiling_H */
244