CnC
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends Groups Pages
itac.h
1 //********************************************************************************
2 // Copyright (c) 2007-2013 Intel Corporation. All Rights Reserved. **
3 // **
4 // The source code contained or described herein and all documents related to **
5 // the source code ("Material") are owned by Intel Corporation or its suppliers **
6 // or licensors. Title to the Material remains with Intel Corporation or its **
7 // suppliers and licensors. The Material contains trade secrets and proprietary **
8 // and confidential information of Intel or its suppliers and licensors. The **
9 // Material is protected by worldwide copyright and trade secret laws and **
10 // treaty provisions. No part of the Material may be used, copied, reproduced, **
11 // modified, published, uploaded, posted, transmitted, distributed, or **
12 // disclosed in any way without Intel's prior express written permission. **
13 // **
14 // No license under any patent, copyright, trade secret or other intellectual **
15 // property right is granted to or conferred upon you by disclosure or delivery **
16 // of the Materials, either expressly, by implication, inducement, estoppel or **
17 // otherwise. Any license under such intellectual property rights must be **
18 // express and approved by Intel in writing. **
19 //********************************************************************************
20 
21 #pragma once
22 #ifndef _CNC_ITAC_H_
23 #define _CNC_ITAC_H_
24 
25 /**
26 \page itac Using Intel(R) Trace Analyzer and Collector with CnC
27 A CnC program run can be traced with Intel(R) Trace Collector (ITC)
28 and post-morten analyzed with Intel(R) Trace Analyzer (ITA)
29 (http://software.intel.com/en-us/intel-trace-analyzer)
30 
31 The CnC header files are instrumented with hooks into ITC; when
32 compiling with CNC_WITH_ITAC being defined the compiler will insert
33 calls into ITC. Those work in shared and distributed mode, with distCnC
34 you'll not only see the step-execution but also the communication.
35 If you construct your collections with names (string parameters to
36 their constructors) then the instrumentation will use those names and
37 create a meaningful trace without further manual instrumentation.
38 
39 The CnC runtime will initialize ITC automatically. In shared memory
40 this will happen when the first context is created, in distributed memory
41 right when dist_cnc_init is created. You can call VT_INIT earlier
42 in the code if you want to to see ITC things before the first context
43 creation (shared memory).
44 
45 Please see \ref itac_in on how to instrument your code further.
46 
47 After instrumentation/recompilation the execution of your applicaton
48 "app" will let ITC write a tracefile "app.stf". To start analysis,
49 simply execute "traceanalyzer app.stf".
50 
51 \section itac-tips Hints
52 For a more convinient file handling it is
53 recommended to let ITC write the trac in the "SINGLESTF" format:
54 simply set VT_LOGFILE_FORMAT=SINGLESTF when runnig your application.
55 
56 Usually CnC codes are threaded. ITC will create a trace in which every
57 thread is shown as busy from it's first acitivity to its termination,
58 even if it is actually idle. To prevent this set VT_ENTER_USCERCODE=0
59 at application runtime.
60 
61 \section mpitrace Intel(R) MPI and ITC
62 The switch "-trace" to mpi[exec|run|cc] does not work
63 out-of-the-box. However, if using the instrumented version ITC will
64 load automatically. For this, compile with -DCNC_WITH_ITAC and link
65 against ITAC (see \ref itac_build). To load ITC in a
66 "plain" MPI environment (without recompiling or -linking), just
67 preload the following libraries:
68 \code
69 env LD_PRELOAD="libcnc.so:libcnc_mpi_itac.so:libVT.so" env DIST_CNC=MPI mpiexec -n ...
70 \endcode
71 or in debug mode
72 \code
73 env LD_PRELOAD="libcnc_debug.so:libcnc_mpi_itac_debug.so:libVT.so" env DIST_CNC=MPI mpiexec -n ...
74 \endcode
75 
76 \section itac_build Compiling and linking with ITAC instrumentation
77 Apparently you need a working isntallation of ITAC. When compiling add
78 the include-directory of ITAC to your include path
79 (-I$VT_ROOT/include). When linking, add the slib directory to the
80 lib-path and link against the following libraries
81 - SOCKETS:-L$VT_SLIB_DIR -lVTcs $VT_ADD_LIBS
82 - MPI: use mpicxx/mpiicpc -trace -L$VT_SLIB_DIR
83 Please refer to the ITAC documentation for more details.
84 **/
85 
86 /// \defgroup itac_in Instrumenting with/for ITAC
87 /// @{
88 /// Two Macros are provided for a convenient way to instrument your code with ITAC.
89 /// When adding instrumentation you need to take care about building your bainry properly (\ref itac_build).
90 #ifdef CNC_WITH_ITAC
91 
92 #include <VT.h>
93 #include <iostream>
94 
95 namespace CnC {
96 namespace Internal {
97 
98  struct ITAC_FUNC {
99  ITAC_FUNC( int id ) { VT_enter( id, VT_NOSCL ); }
100  ~ITAC_FUNC() { VT_leave( VT_NOSCL ); }
101  };
102 
103 } // namespace Internal
104 } // namespace CnC
105 
106 #define VT_THREAD_NAME( threadName ) VT_registernamed( threadName, -1 )
107 
108 #define VT_FUNC( funcName ) __VT_FUNC__( funcName, __LINE__ )
109 #define VT_FUNC_D( funcName ) __VT_FUNC_D__( funcName, __LINE__ )
110 
111 #define VT_INIT() VT_initialize( 0, 0 )
112 
113 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 
115 // -- Implementational macros for VT_FUNC --
116 // Guarantee that generated variable names get the line number appended.
117 // This allows to have several VT_FUNC statements in the same scope.
118 #define __VT_FUNC__( _funcName, _line ) ____VT_FUNC____( _funcName, _line, static )
119 #define __VT_FUNC_D__( _funcName, _line ) ____VT_FUNC____( _funcName, _line, )
120 #define ____VT_FUNC____( _funcName, _line, _qual ) \
121  _qual int ____CnC_vt_func_id____##_line = 0; \
122  if ( ____CnC_vt_func_id____##_line == 0 ) { VT_funcdef( _funcName, VT_NOCLASS, &____CnC_vt_func_id____##_line ); } \
123  CnC::Internal::ITAC_FUNC ____CnC_vt_func_obj____##_line( ____CnC_vt_func_id____##_line )
124 
125 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 
127 // you better not use this
128 #define VT_SYMDEF( _id, _name ) VT_symdef( _id, _name, NULL )
129 
130 #else
131 
132 #define VT_SYMDEF( _id, _name )
133 
134 /// \def VT_THREAD_NAME( threadName )
135 /// Use this macro to define an (optional) name for your application thread, e.g. VT_THREAD_NAME( "myApp" ).
136 /// This name will appear for your thread in ITAC's event timeline.
137 /// \param threadName name of calling thread (in double quotes), to appear in ITAC tracefile
138 #define VT_THREAD_NAME( threadName )
139 
140 /// \def VT_FUNC( funcName )
141 /// Use this macro to manually instrument your function (or scope) at its beginning, e.g. VT_FUNC( "MyClass::myMethod" );
142 /// See also \ref itac_build
143 /// \param funcName name of function (in double quotes), potentially including class/namespace hierachy
144 #define VT_FUNC( funcName )
145 
146 /// \def VT_FUNC_D( funcName )
147 /// Similar to VT_FUNC, but the recorded function name can change between invocations.
148 /// It is slower, so don't use it unless really needed.
149 /// See also \ref itac_build
150 /// \param funcName name of function (in double quotes), potentially including class/namespace hierachy
151 #define VT_FUNC_D( funcName )
152 
153 /// \def VT_INIT()
154 /// In shared memory, ITC needs to be initialized. This is done automatically with the first
155 /// context construction. Use this only if you want to see things in the trace before the first
156 /// context is created. Don't use it for distributed memory.
157 # define VT_INIT()
158 
159 #endif //CNC_WITH_ITAC
160 
161 /// @}
162 
163 #endif // _CNC_ITAC_H_