00001 /* ******************************************************************************* 00002 * Copyright (c) 2007-2014, Intel Corporation 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * 00007 * * Redistributions of source code must retain the above copyright notice, 00008 * this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of Intel Corporation nor the names of its contributors 00013 * may be used to endorse or promote products derived from this software 00014 * without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 00020 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00021 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00022 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00023 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00024 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00025 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 ********************************************************************************/ 00027 00028 #pragma once 00029 #ifndef _CNC_ITAC_H_ 00030 #define _CNC_ITAC_H_ 00031 00032 /** 00033 \page itac Using Intel(R) Trace Analyzer and Collector with CnC 00034 A CnC program run can be traced with Intel(R) Trace Collector (ITC) 00035 and post-morten analyzed with Intel(R) Trace Analyzer (ITA) 00036 (http://software.intel.com/en-us/intel-trace-analyzer) 00037 00038 The CnC header files are instrumented with hooks into ITC; when 00039 compiling with CNC_WITH_ITAC being defined the compiler will insert 00040 calls into ITC. Those work in shared and distributed mode, with distCnC 00041 you'll not only see the step-execution but also the communication. 00042 If you construct your collections with names (string parameters to 00043 their constructors) then the instrumentation will use those names and 00044 create a meaningful trace without further manual instrumentation. 00045 00046 The CnC runtime will initialize ITC automatically. In shared memory 00047 this will happen when the first context is created, in distributed memory 00048 right when dist_cnc_init is created. You can call VT_INIT earlier 00049 in the code if you want to to see ITC things before the first context 00050 creation (shared memory). 00051 00052 Please see \ref itac_in on how to instrument your code further. 00053 00054 After instrumentation/recompilation the execution of your applicaton 00055 "app" will let ITC write a tracefile "app.stf". To start analysis, 00056 simply execute "traceanalyzer app.stf". 00057 00058 \section itac-tips Hints 00059 For a more convinient file handling it is 00060 recommended to let ITC write the trac in the "SINGLESTF" format: 00061 simply set VT_LOGFILE_FORMAT=SINGLESTF when runnig your application. 00062 00063 Usually CnC codes are threaded. ITC will create a trace in which every 00064 thread is shown as busy from it's first acitivity to its termination, 00065 even if it is actually idle. To prevent this set VT_ENTER_USERCODE=0 00066 at application runtime. 00067 00068 \section mpitrace Intel(R) MPI and ITC 00069 The switch "-trace" to mpi[exec|run|cc] does not work 00070 out-of-the-box. However, if using the instrumented version ITC will 00071 load automatically. For this, compile with -DCNC_WITH_ITAC and link 00072 against ITAC (see \ref itac_build). To load ITC in a 00073 "plain" MPI environment (without recompiling or -linking), just 00074 preload the following libraries: 00075 \code 00076 env LD_PRELOAD="libcnc.so:libcnc_mpi_itac.so:libVT.so" env DIST_CNC=MPI mpiexec -n ... 00077 \endcode 00078 or in debug mode 00079 \code 00080 env LD_PRELOAD="libcnc_debug.so:libcnc_mpi_itac_debug.so:libVT.so" env DIST_CNC=MPI mpiexec -n ... 00081 \endcode 00082 00083 \section itac_build Compiling and linking with ITAC instrumentation 00084 Apparently you need a working isntallation of ITAC. When compiling add 00085 the include-directory of ITAC to your include path 00086 (-I$VT_ROOT/include). When linking, add the slib directory to the 00087 lib-path and link against the following libraries 00088 - SOCKETS:-L$VT_SLIB_DIR -lVTcs $VT_ADD_LIBS 00089 - MPI: use mpicxx/mpiicpc -trace -L$VT_SLIB_DIR 00090 Please refer to the ITAC documentation for more details. 00091 **/ 00092 00093 /// \defgroup itac_in Instrumenting with/for ITAC 00094 /// @{ 00095 /// Two Macros are provided for a convenient way to instrument your code with ITAC. 00096 /// When adding instrumentation you need to take care about building your bainry properly (\ref itac_build). 00097 #ifdef CNC_WITH_ITAC 00098 00099 #include <VT.h> 00100 #include <iostream> 00101 00102 namespace CnC { 00103 namespace Internal { 00104 00105 struct ITAC_FUNC { 00106 ITAC_FUNC( int id ) { VT_enter( id, VT_NOSCL ); } 00107 ~ITAC_FUNC() { VT_leave( VT_NOSCL ); } 00108 }; 00109 00110 } // namespace Internal 00111 } // namespace CnC 00112 00113 #define VT_THREAD_NAME( threadName ) VT_registernamed( threadName, -1 ) 00114 00115 #define VT_FUNC( funcName ) __VT_FUNC__( funcName, __LINE__ ) 00116 #define VT_FUNC_D( funcName ) __VT_FUNC_D__( funcName, __LINE__ ) 00117 00118 #define VT_INIT() VT_initialize( 0, 0 ) 00119 00120 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00121 00122 // -- Implementational macros for VT_FUNC -- 00123 // Guarantee that generated variable names get the line number appended. 00124 // This allows to have several VT_FUNC statements in the same scope. 00125 #define __VT_FUNC__( _funcName, _line ) ____VT_FUNC____( _funcName, _line, static ) 00126 #define __VT_FUNC_D__( _funcName, _line ) ____VT_FUNC____( _funcName, _line, ) 00127 #define ____VT_FUNC____( _funcName, _line, _qual ) \ 00128 _qual int ____CnC_vt_func_id____##_line = 0; \ 00129 if ( ____CnC_vt_func_id____##_line == 0 ) { VT_funcdef( _funcName, VT_NOCLASS, &____CnC_vt_func_id____##_line ); } \ 00130 CnC::Internal::ITAC_FUNC ____CnC_vt_func_obj____##_line( ____CnC_vt_func_id____##_line ) 00131 00132 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00133 00134 // you better not use this 00135 #define VT_SYMDEF( _id, _name ) VT_symdef( _id, _name, NULL ) 00136 00137 #else 00138 00139 #define VT_SYMDEF( _id, _name ) 00140 00141 /// \def VT_THREAD_NAME( threadName ) 00142 /// Use this macro to define an (optional) name for your application thread, e.g. VT_THREAD_NAME( "myApp" ). 00143 /// This name will appear for your thread in ITAC's event timeline. 00144 /// \param threadName name of calling thread (in double quotes), to appear in ITAC tracefile 00145 #define VT_THREAD_NAME( threadName ) 00146 00147 /// \def VT_FUNC( funcName ) 00148 /// Use this macro to manually instrument your function (or scope) at its beginning, e.g. VT_FUNC( "MyClass::myMethod" ); 00149 /// See also \ref itac_build 00150 /// \param funcName name of function (in double quotes), potentially including class/namespace hierachy 00151 #define VT_FUNC( funcName ) 00152 00153 /// \def VT_FUNC_D( funcName ) 00154 /// Similar to VT_FUNC, but the recorded function name can change between invocations. 00155 /// It is slower, so don't use it unless really needed. 00156 /// See also \ref itac_build 00157 /// \param funcName name of function (in double quotes), potentially including class/namespace hierachy 00158 #define VT_FUNC_D( funcName ) 00159 00160 /// \def VT_INIT() 00161 /// In shared memory, ITC needs to be initialized. This is done automatically with the first 00162 /// context construction. Use this only if you want to see things in the trace before the first 00163 /// context is created. Don't use it for distributed memory. 00164 # define VT_INIT() 00165 00166 #endif //CNC_WITH_ITAC 00167 00168 /// @} 00169 00170 #endif // _CNC_ITAC_H_