src/Profile/Profiler.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 /****************************************************************************
00017 **                      TAU Portable Profiling Package                     **
00018 **                      http://www.acl.lanl.gov/tau                        **
00019 *****************************************************************************
00020 **    Copyright 1997                                                       **
00021 **    Department of Computer and Information Science, University of Oregon **
00022 **    Advanced Computing Laboratory, Los Alamos National Laboratory        **
00023 ****************************************************************************/
00024 /***************************************************************************
00025 **      File            : Profiler.h                                      **
00026 **      Description     : TAU Profiling Package                           **
00027 **      Author          : Sameer Shende                                   **
00028 **      Contact         : sameer@cs.uoregon.edu sameer@acl.lanl.gov       **
00029 **      Flags           : Compile with                                    **
00030 **                        -DPROFILING_ON to enable profiling (ESSENTIAL)  **
00031 **                        -DPROFILE_STATS for Std. Deviation of Excl Time **
00032 **                        -DSGI_HW_COUNTERS for using SGI counters        **
00033 **                        -DPROFILE_CALLS  for trace of each invocation   **
00034 **                        -DSGI_TIMERS  for SGI fast nanosecs timer       **
00035 **                        -DTULIP_TIMERS for non-sgi Platform             **
00036 **                        -DIPPL_STDSTL for using STD STL in IPPL src   **
00037 **                        -DIPPL_TFLOP for Intel Teraflop at SNL/NM       **
00038 **                        -DIPPL_KAI for KCC compiler                     **
00039 **                        -DDEBUG_PROF  for internal debugging messages   **
00040 **      Documentation   : See http://www.acl.lanl.gov/tau                 **
00041 ***************************************************************************/
00042 #ifndef PROFILER_H
00043 #define PROFILER_H
00044 
00045 /* TAU PROFILING GROUPS. More will be added later.  */
00046 #define TAU_DEFAULT             0xffffffff   /* All profiling groups enabled*/
00047 #define TAU_MESSAGE             0x00000001   /* Message 'm'*/
00048 #define TAU_PETE                0x00000002   /* PETE    'p' */
00049 #define TAU_VIZ                 0x00000004   /* ACLVIZ  'v' */
00050 #define TAU_ASSIGN              0x00000008   /* ASSIGN Expression Evaluation 'a' */
00051 #define TAU_IO                  0x00000010   /* IO routines 'i' */
00052 #define TAU_FIELD               0x00000020   /* Field Classes 'f' */
00053 #define TAU_LAYOUT              0x00000040   /* Field Layout  'l' */
00054 #define TAU_SPARSE              0x00000080   /* Sparse Index  's' */
00055 #define TAU_DOMAINMAP           0x00000100   /* Domain Map    'd' */
00056 #define TAU_UTILITY             0x00000200   /* Utility       'Ut' */
00057 #define TAU_REGION              0x00000400   /* Region        'r' */
00058 #define TAU_PARTICLE            0x00000800   /* Particle      'pa' */
00059 #define TAU_MESHES              0x00001000   /* Meshes        'mesh' */
00060 #define TAU_SUBFIELD            0x00002000   /* SubField      'su' */
00061 #define TAU_COMMUNICATION       0x00004000   /* A++ Commm     'c' */
00062 #define TAU_DESCRIPTOR_OVERHEAD 0x00008000   /* A++ Descriptor Overhead   'de' */
00063 /*
00064 SPACE for                       0x00010000
00065 SPACE for                       0x00020000
00066 SPACE for                       0x00040000
00067 SPACE for                       0x00080000
00068 */
00069 #define TAU_FFT                 0x00100000   /* FFT 'ff' */
00070 #define TAU_ACLMPL              0x00200000   /* ACLMPL 'ac' */
00071 #define TAU_PAWS1               0x00400000   /* PAWS1  'paws1' */
00072 #define TAU_PAWS2               0x00800000   /* PAWS2  'paws2' */
00073 #define TAU_PAWS3               0x01000000   /* PAWS3  'paws3' */
00074 /* SPACE for                    0x02000000
00075    SPACE for                    0x04000000
00076 */
00077 #define TAU_USER4               0x08000000   /* User4         '4' */
00078 #define TAU_USER3               0x10000000   /* User3         '3' */     
00079 #define TAU_USER2               0x20000000   /* User2         '2' */
00080 #define TAU_USER1               0x40000000   /* User1         '1' */
00081 #define TAU_USER                0x80000000   /* User          'u' */
00082 
00083 #define TAU_MAX_THREADS 1024
00084 
00085 #if (defined(PROFILING_ON) || defined(TRACING_ON))
00086 
00087 
00088 #include "Utility/Pstring.h"
00089 
00090 #ifndef NO_RTTI /* RTTI is present  */
00091 
00092 #ifdef IPPL_USE_STANDARD_HEADERS
00093 #include <typeinfo>
00094 using namespace std;
00095 #else
00096 #include <typeinfo.h>
00097 #endif
00098 
00099 #endif /* NO_RTTI  */
00100 
00101 #ifdef IPPL_STDSTL
00102 
00103 #include <vector>
00104 using std::vector;
00105 // Standard STL has pair class in Utility header
00106 #include <utility>
00107 using std::pair;
00108 #include <list>
00109 using std::list;
00110 
00111 #else
00112 
00113 #include <vector.h>
00114 #include <pair.h>
00115 #include <list.h>
00116 
00117 #endif // IPPL_STDSTL
00118 
00119 
00121 //
00122 // class FunctionInfo
00123 //
00124 // This class is intended to be instantiated once per function
00125 // (or other code block to be timed) as a static variable.
00126 //
00127 // It will be constructed the first time the function is called,
00128 // and that constructor registers this object (and therefore the
00129 // function) with the timer system.
00130 //
00132 
00133 class FunctionInfo
00134 {
00135 public:
00136         // Construct with the name of the function and its type.
00137         FunctionInfo(const char* name, const char * type, 
00138           unsigned int ProfileGroup = TAU_DEFAULT, 
00139           const char *ProfileGroupName = "TAU_DEFAULT");
00140         FunctionInfo(string& name, const char* type, 
00141           unsigned int ProfileGroup = TAU_DEFAULT,
00142           const char *ProfileGroupName = "TAU_DEFAULT");
00143         FunctionInfo(const char* name, string& type, 
00144           unsigned int ProfileGroup = TAU_DEFAULT,
00145           const char *ProfileGroupName = "TAU_DEFAULT");
00146         FunctionInfo(string& name, string& type, 
00147           unsigned int ProfileGroup = TAU_DEFAULT,
00148           const char *ProfileGroupName = "TAU_DEFAULT");
00149 
00150         FunctionInfo(const FunctionInfo& X) ;
00151         // When we exit, we have to clean up.
00152         ~FunctionInfo();
00153         FunctionInfo& operator= (const FunctionInfo& X) ;
00154         
00155 
00156         // Tell it about a function call finishing.
00157         void ExcludeTime(double t);
00158         // Removing void IncludeTime(double t);
00159         // and replacing with 
00160         void AddInclTime(double t);
00161         void AddExclTime(double t);
00162         void IncrNumCalls(void);
00163 
00164         bool GetAlreadyOnStack(void);
00165         void SetAlreadyOnStack(bool value);  
00166 
00167         // A container of all of these.
00168         // The ctor registers with this.
00169         
00170         static vector<FunctionInfo*> FunctionDB[TAU_MAX_THREADS];
00171 
00172 #ifdef PROFILE_CALLS
00173         list < pair<double,double> > *ExclInclCallList; 
00174         // Make this a ptr to a list so that ~FunctionInfo doesn't destroy it.
00175         // time spent in each call
00176 
00177         int AppendExclInclTimeThisCall(double ex, double in); 
00178         // to ExclInclCallList
00179 #endif // PROFILE_CALLS
00180 
00181 private:
00182 
00183         // A record of the information unique to this function.
00184         // Statistics about calling this function.
00185         long NumCalls;
00186         long NumSubrs;
00187         double ExclTime;
00188         double InclTime;
00189         bool AlreadyOnStack; 
00190 #ifdef PROFILE_STATS
00191         double SumExclSqr;
00192 #endif // PROFILE_STATS
00193 
00194 public:
00195         string Name;
00196         string Type;
00197         string GroupName;
00198         long   FunctionId;
00199         // Cough up the information about this function.
00200         const char* GetName() const { return Name.c_str(); }
00201         const char* GetType() const { return Type.c_str(); }
00202         const char* GetPrimaryGroup() const { return GroupName.c_str(); }
00203         long GetFunctionId() const { return FunctionId; }
00204         long GetCalls() const { return NumCalls; }
00205         long GetSubrs() const { return NumSubrs; }
00206         double GetExclTime() const { return ExclTime; }
00207         double GetInclTime() const { return InclTime; }
00208         unsigned int GetProfileGroup() const {return MyProfileGroup_; }
00209 #ifdef PROFILE_STATS 
00210         double GetSumExclSqr() const { return SumExclSqr; }
00211         void AddSumExclSqr(double ExclSqr) { SumExclSqr += ExclSqr; }
00212 #endif // PROFILE_STATS 
00213 
00214 private:
00215         unsigned int MyProfileGroup_;
00216         // There is a class that will do some initialization
00217         // of FunctionStack that can't be done with
00218         // just the constructor.
00219         //friend class ProfilerInitializer;
00220 };
00221 
00222 //
00223 // For efficiency, make the timing updates inline.
00224 //
00225 inline void 
00226 FunctionInfo::ExcludeTime(double t)
00227 { // called by a function to decrease its parent functions time
00228         ++NumSubrs;
00229         ExclTime -= t; // exclude from it the time spent in child function
00230 }
00231         
00232 
00233 inline void 
00234 FunctionInfo::AddInclTime(double t)
00235 {
00236         InclTime += t; // Add Inclusive time
00237 }
00238 
00239 inline void
00240 FunctionInfo::AddExclTime(double t)
00241 {
00242         ExclTime += t; // Add Total Time to Exclusive time (-ve)
00243 }
00244 
00245 inline void
00246 FunctionInfo::IncrNumCalls(void)
00247 {
00248         NumCalls++; // Increment number of calls
00249 } 
00250 
00251 inline void
00252 FunctionInfo::SetAlreadyOnStack(bool value)
00253 {
00254         AlreadyOnStack = value;
00255 }
00256 
00257 inline bool
00258 FunctionInfo::GetAlreadyOnStack(void)
00259 {
00260         return AlreadyOnStack;
00261 }
00262 
00263 
00265 //
00266 // class Profiler
00267 //
00268 // This class is intended to be instantiated once per function
00269 // (or other code block to be timed) as an auto variable.
00270 //
00271 // It will be constructed each time the block is entered
00272 // and destroyed when the block is exited.  The constructor
00273 // turns on the timer, and the destructor turns it off.
00274 //
00276 class Profiler
00277 {
00278 public:
00279         Profiler(FunctionInfo * fi, unsigned int ProfileGroup = TAU_DEFAULT, 
00280           bool StartStop = false);
00281 
00282         void Start();
00283         Profiler(const Profiler& X);
00284         Profiler& operator= (const Profiler& X);
00285         // Clean up data from this invocation.
00286         void Stop();
00287         ~Profiler();
00288         static void ProfileExit(const char *message=0);
00289         int StoreData(void); 
00290 
00291 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) ) 
00292         int ExcludeTimeThisCall(double t);
00293         double ExclTimeThisCall; // for this invocation of the function
00294 #endif // PROFILE_CALLS || PROFILE_STATS
00295 
00296         static Profiler * CurrentProfiler[TAU_MAX_THREADS];
00297         double StartTime;
00298         FunctionInfo * ThisFunction;
00299         Profiler * ParentProfiler; 
00300 
00301 private:
00302         unsigned int MyProfileGroup_;
00303         bool    StartStopUsed_;
00304         bool    AddInclFlag; 
00305         // There is a class that will do some initialization
00306         // of FunctionStack that can't be done with
00307         // just the constructor.
00308         //friend class ProfilerInitializer;
00309 };
00310 
00312 //
00313 // class RtsLayer
00314 //
00315 // This class is used for porting the TAU Profiling package to other
00316 // platforms and software frameworks. It contains functions to get
00317 // the node id, thread id etc. When Threads are implemented, myThread()
00318 // method should return the thread id in {0..N-1} where N is the total
00319 // number of threads. All interaction with the outside world should be
00320 // restrained to this class. 
00322 class RtsLayer 
00323 { // Layer for Profiler to interact with the Runtime System
00324   public:
00325         static unsigned int ProfileMask;
00326         static int Node;
00327         RtsLayer () { }  // defaults
00328         ~RtsLayer () { } 
00329 
00330         static unsigned int enableProfileGroup(unsigned int ProfileGroup) ;
00331 
00332         static unsigned int resetProfileGroup(void) ;
00333 
00334         static int setAndParseProfileGroups (char *prog, char *str) ;
00335 
00336         static bool isEnabled(unsigned int ProfileGroup) ; 
00337 
00338         static void ProfileInit(int argc, char **argv);
00339 
00340         static string PrimaryGroup(const char *ProfileGroupName);
00341 
00342         static bool isCtorDtor(const char *name);
00343         
00344         static void TraceSendMsg(int type, int destination, int length);
00345         static void TraceRecvMsg(int type, int source, int length);
00346 
00347         inline
00348         static const char * CheckNotNull(const char * str) {
00349           if (str == 0) return "  ";
00350           else return str;
00351         }
00352 
00353 
00354         static int      SetEventCounter(void);
00355         static double   GetEventCounter(void);
00356 
00357         static double   getUSecD(void); 
00358 
00359         static int      setMyNode(int NodeId);
00360 
00361         // For tracing 
00362         static int      DumpEDF(void); 
00363 
00364         // Return the number of the 'current' node.
00365         static int myNode()  { return Node;}
00366 
00367         // Return the number of the 'current' context.
00368         static int myContext() { return 0; }
00369 
00370         // Return the number of the 'current' thread. 0..TAU_MAX_THREADS-1
00371         inline
00372         static int myThread() { return 0; }
00373 
00374 }; 
00375 
00377 // TAU PROFILING API MACROS. 
00378 // To ensure that Profiling does not add any runtime overhead when it 
00379 // is turned off, these macros expand to null.
00381 
00382 #define TAU_TYPE_STRING(profileString, str) static string profileString(str);
00383 #define TAU_PROFILE(name, type, group) \
00384         static FunctionInfo tauFI(name, type, group, #group); \
00385         Profiler tauFP(&tauFI, group); 
00386 #define TAU_PROFILE_TIMER(var, name, type, group) \
00387         static FunctionInfo var##fi(name, type, group, #group); \
00388         Profiler var(&var##fi, group, true); 
00389 
00390 // Construct a Profiler obj and a FunctionInfo obj with an extended name
00391 // e.g., FunctionInfo loop1fi(); Profiler loop1(); 
00392 #define TAU_PROFILE_START(var) var.Start();
00393 #define TAU_PROFILE_STOP(var)  var.Stop();
00394 #define TAU_PROFILE_STMT(stmt) stmt;
00395 #define TAU_PROFILE_EXIT(msg)  Profiler::ProfileExit(msg); 
00396 #define TAU_PROFILE_INIT(argc, argv) RtsLayer::ProfileInit(argc, argv);
00397 #define TAU_PROFILE_SET_NODE(node) RtsLayer::setMyNode(node);
00398 
00399 #ifdef NO_RTTI
00400 #define CT(obj) string(#obj)
00401 #else // RTTI is present
00402 #define CT(obj) string(RtsLayer::CheckNotNull(typeid(obj).name())) 
00403 #endif //NO_RTTI
00404 
00405 // Use DEBUGPROFMSG macro as in 
00406 // DEBUGPROF("Node" << RtsLayer::myNode() << " Message " << endl;);
00407 // We're deliberately not using *IpplInfo::Debug because some profiling
00408 // debug messages come from the destructor of Profiler in main and by then
00409 // IpplInfo object may have been destroyed.
00410 
00411 #else /* PROFILING_ON */
00412 /* In the absence of profiling, define the functions as null */
00413 #define TYPE_STRING(profileString, str)
00414 #define PROFILED_BLOCK(name, type) 
00415 
00416 #define TAU_TYPE_STRING(profileString, str) 
00417 #define TAU_PROFILE(name, type, group) 
00418 #define TAU_PROFILE_TIMER(var, name, type, group)
00419 #define TAU_PROFILE_START(var)
00420 #define TAU_PROFILE_STOP(var)
00421 #define TAU_PROFILE_STMT(stmt) 
00422 #define TAU_PROFILE_EXIT(msg)
00423 #define TAU_PROFILE_INIT(argc, argv)
00424 #define TAU_PROFILE_SET_NODE(node)
00425 #define CT(obj)
00426 
00427 #endif /* PROFILING_ON */
00428 
00429 #ifdef TRACING_ON
00430 #define TAU_TRACE_SENDMSG(type, destination, length) RtsLayer::TraceSendMsg(type, destination, length); 
00431 #define TAU_TRACE_RECVMSG(type, source, length) RtsLayer::TraceRecvMsg(type, source, length); 
00432 
00433 #else /* TRACING_ON */
00434 #define TAU_TRACE_SENDMSG(type, destination, length) 
00435 #define TAU_TRACE_RECVMSG(type, source, length)
00436 #endif /* TRACING_ON */
00437 
00438 #endif /* PROFILER_H */
00439 /***************************************************************************
00440  * $RCSfile: Profiler.h,v $   $Author: adelmann $
00441  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:32 $
00442  * IPPL_VERSION_ID: $Id: Profiler.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $ 
00443  ***************************************************************************/

Generated on Mon Jan 16 13:23:55 2006 for IPPL by  doxygen 1.4.6