OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Profiler.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  * This program was prepared by PSI.
22  * All rights in the program are reserved by PSI.
23  * Neither PSI nor the author(s)
24  * makes any warranty, express or implied, or assumes any liability or
25  * responsibility for the use of this software
26  *
27  * Visit www.amas.web.psi for more details
28  *
29  ***************************************************************************/
30 
31 /****************************************************************************
32 ** TAU Portable Profiling Package **
33 ** http://www.acl.lanl.gov/tau **
34 *****************************************************************************
35 ** Copyright 1997 **
36 ** Department of Computer and Information Science, University of Oregon **
37 ** Advanced Computing Laboratory, Los Alamos National Laboratory **
38 ****************************************************************************/
39 /***************************************************************************
40 ** File : Profiler.cpp **
41 ** Description : TAU Profiling Package **
42 ** Author : Sameer Shende **
43 ** Contact : sameer@cs.uoregon.edu sameer@acl.lanl.gov **
44 ** Flags : Compile with **
45 ** -DPROFILING_ON to enable profiling (ESSENTIAL) **
46 ** -DPROFILE_STATS for Std. Deviation of Excl Time **
47 ** -DSGI_HW_COUNTERS for using SGI counters **
48 ** -DPROFILE_CALLS for trace of each invocation **
49 ** -DSGI_TIMERS for SGI fast nanosecs timer **
50 ** -DDEBUG_PROF for internal debugging messages **
51 ** Documentation : See http://www.acl.lanl.gov/tau **
52 ***************************************************************************/
53 
55 // Include Files
57 
58 #include "Profile/Profiler.h"
59 
60 #include <iostream>
61 using namespace std;
62 #include <cstdio>
63 #include <fcntl.h>
64 #include <ctime>
65 #include <unistd.h>
66 #include <cstdlib>
67 #include <cstring>
68 
69 
70 #ifdef TRACING_ON
71 #define PCXX_EVENT_SRC
72 #include "pcxx_events.h"
73 #endif // TRACING_ON
74 
75 //#define PROFILE_CALLS // Generate Excl Incl data for each call
76 //#define DEBUG_PROF // For Debugging Messages from Profiler.cpp
77 
78 #ifdef DEBUG_PROF
79 #define DEBUGPROFMSG(msg) { cout<< msg; }
80 #else
81 #define DEBUGPROFMSG(msg)
82 #endif // DEBUG_PROF
83 
85 //Initialize static data
87 
88 vector<FunctionInfo*> FunctionInfo::FunctionDB[TAU_MAX_THREADS] ;
89 Profiler * Profiler::CurrentProfiler[] = {0}; // null to start with
90 // The rest of CurrentProfiler entries are initialized to null automatically
91 unsigned int RtsLayer::ProfileMask = TAU_DEFAULT;
92 
93 // Default value of Node.
94 int RtsLayer::Node = -1;
95 
96 
98 // Member Function Definitions For class FunctionInfo
100 
102 FunctionInfo::FunctionInfo(const char *name, const char *type,
103  unsigned int ProfileGroup , const char *ProfileGroupName)
104 {
105  if (ProfileGroup & RtsLayer::ProfileMask) {
106 
107  Name = name;
108  Type = type;
109 #ifdef TRACING_ON
110  GroupName = RtsLayer::PrimaryGroup(ProfileGroupName);
111 #endif //TRACING_ON
112  NumCalls = 0;
113  NumSubrs = 0;
114  ExclTime = 0;
115  InclTime = 0;
116 
117 // Since FunctionInfo constructor is called once for each function (static)
118 // we know that it couldn't be already on the call stack.
119  SetAlreadyOnStack(false);
120 
121 #ifdef PROFILE_STATS
122  SumExclSqr = 0;
123 #endif //PROFILE_STATS
124 
125 #ifdef PROFILE_CALLS
126  ExclInclCallList = new std::list<std::pair<double, double> >();
127 #endif //PROFILE_CALLS
128  // Make this a ptr to a list so that ~FunctionInfo doesn't destroy it.
129 
130  MyProfileGroup_ = ProfileGroup ;
131  FunctionDB[RtsLayer::myThread()].push_back(this);
132 #ifdef TRACING_ON
133  // Function Id is the index into the DB vector
134  FunctionId = FunctionDB[RtsLayer::myThread()].size();
135 #endif //TRACING_ON
136 
137  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
138  << " FunctionInfo::FunctionInfo(n,t) : Name : "<< GetName()
139  << " Type : " << GetType() << endl;);
140  }
141 }
142 
144 
145 FunctionInfo::FunctionInfo(string& name, const char* type,
146  unsigned int ProfileGroup , const char *ProfileGroupName)
147 {
148  if (ProfileGroup & RtsLayer::ProfileMask) {
149 
150  Name = name;
151  Type = type;
152 #ifdef TRACING_ON
153  GroupName = RtsLayer::PrimaryGroup(ProfileGroupName);
154 #endif //TRACING_ON
155  NumCalls = 0;
156  NumSubrs = 0;
157  ExclTime = 0;
158  InclTime = 0;
159 
160 // Since FunctionInfo constructor is called once for each function (static)
161 // we know that it couldn't be already on the call stack.
162  SetAlreadyOnStack(false);
163 
164 #ifdef PROFILE_STATS
165  SumExclSqr = 0;
166 #endif //PROFILE_STATS
167 
168 #ifdef PROFILE_CALLS
169  ExclInclCallList = new std::list<std::pair<double, double> >();
170 #endif //PROFILE_CALLS
171  // Make this a ptr to a list so that ~FunctionInfo doesn't destroy it.
172 
173  MyProfileGroup_ = ProfileGroup ;
174  FunctionDB[RtsLayer::myThread()].push_back(this);
175 #ifdef TRACING_ON
176  // Function Id is the index into the DB vector
177  FunctionId = FunctionDB[RtsLayer::myThread()].size();
178 #endif //TRACING_ON
179 
180  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
181  << " FunctionInfo::FunctionInfo(n,t) : Name : "<< GetName()
182  << " Type : " << GetType() << endl;);
183  }
184 }
185 
187 
188 FunctionInfo::FunctionInfo(const char *name, string& type,
189  unsigned int ProfileGroup , const char *ProfileGroupName)
190 {
191  if (ProfileGroup & RtsLayer::ProfileMask) {
192 
193  Name = name;
194  Type = type;
195 #ifdef TRACING_ON
196  GroupName = RtsLayer::PrimaryGroup(ProfileGroupName);
197 #endif //TRACING_ON
198  NumCalls = 0;
199  NumSubrs = 0;
200  ExclTime = 0;
201  InclTime = 0;
202 
203 // Since FunctionInfo constructor is called once for each function (static)
204 // we know that it couldn't be already on the call stack.
205  SetAlreadyOnStack(false);
206 
207 #ifdef PROFILE_STATS
208  SumExclSqr = 0;
209 #endif //PROFILE_STATS
210 
211 #ifdef PROFILE_CALLS
212  ExclInclCallList = new std::list<std::pair<double, double> >();
213 #endif //PROFILE_CALLS
214  // Make this a ptr to a list so that ~FunctionInfo doesn't destroy it.
215 
216  MyProfileGroup_ = ProfileGroup ;
217  FunctionDB[RtsLayer::myThread()].push_back(this);
218 #ifdef TRACING_ON
219  // Function Id is the index into the DB vector
220  FunctionId = FunctionDB[RtsLayer::myThread()].size();
221 #endif //TRACING_ON
222 
223  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
224  << " FunctionInfo::FunctionInfo(n,t) : Name : "<< GetName()
225  << " Type : " << GetType() << endl;);
226  }
227 }
228 
230 
231 FunctionInfo::FunctionInfo(string& name, string& type,
232  unsigned int ProfileGroup , const char *ProfileGroupName)
233 {
234  if (ProfileGroup & RtsLayer::ProfileMask) {
235 
236  Name = name;
237  Type = type;
238 #ifdef TRACING_ON
239  GroupName = RtsLayer::PrimaryGroup(ProfileGroupName);
240 #endif //TRACING_ON
241  NumCalls = 0;
242  NumSubrs = 0;
243  ExclTime = 0;
244  InclTime = 0;
245 
246 // Since FunctionInfo constructor is called once for each function (static)
247 // we know that it couldn't be already on the call stack.
248  SetAlreadyOnStack(false);
249 
250 #ifdef PROFILE_STATS
251  SumExclSqr = 0;
252 #endif //PROFILE_STATS
253 
254 #ifdef PROFILE_CALLS
255  ExclInclCallList = new std::list<std::pair<double, double> >();
256 #endif //PROFILE_CALLS
257  // Make this a ptr to a list so that ~FunctionInfo doesn't destroy it.
258 
259  MyProfileGroup_ = ProfileGroup ;
260  FunctionDB[RtsLayer::myThread()].push_back(this);
261 #ifdef TRACING_ON
262  // Function Id is the index into the DB vector
263  FunctionId = FunctionDB[RtsLayer::myThread()].size();
264 #endif //TRACING_ON
265 
266  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
267  << " FunctionInfo::FunctionInfo(n,t) : Name : "<< GetName()
268  << " Type : " << GetType() << endl;);
269  }
270 }
271 
273 
275 : Name(X.Name),
276  Type(X.Type),
277  NumCalls(X.NumCalls),
278  NumSubrs(X.NumSubrs),
279  ExclTime(X.ExclTime),
280  InclTime(X.InclTime),
281  MyProfileGroup_(X.MyProfileGroup_)
282 {
283  DEBUGPROFMSG("FunctionInfo::FunctionInfo (const FunctionInfo& X)"<<endl;);
284  FunctionDB[RtsLayer::myThread()].push_back(this);
285 }
287 
289 {
290  DEBUGPROFMSG("FunctionInfo::operator= (const FunctionInfo& X)" << endl;);
291  Name = X.Name;
292  Type = X.Type;
293  NumCalls = X.NumCalls;
294  NumSubrs = X.NumSubrs;
295  ExclTime = X.ExclTime;
296  InclTime = X.InclTime;
297  MyProfileGroup_ = X.MyProfileGroup_;
298  return (*this);
299 }
300 
302 
304 {
305 // Don't delete Name, Type - if dtor of static object dumps the data
306 // after all these function objects are destroyed, it can't get the
307 // name, and type.
308 // delete [] Name;
309 // delete [] Type;
310 }
311 
312 #ifdef PROFILE_CALLS
313 
315 int FunctionInfo::AppendExclInclTimeThisCall(double ex, double in)
316 {
317  ExclInclCallList->push_back(std::pair<double,double>(ex,in));
318  return 1;
319 }
320 
321 #endif //PROFILE_CALLS
322 
325 // Member Function Definitions For class Profiler
327 
329 
330 void Profiler::Start(void)
331 {
332 
333  if (MyProfileGroup_ & RtsLayer::ProfileMask) {
334 
335 #ifdef TRACING_ON
336  pcxx_Event(ThisFunction->GetFunctionId(), 1); // 1 is for entry
337 #endif /* TRACING_ON */
338 
339 #ifdef PROFILING_ON
340  // First, increment the number of calls
342 
343  // Next, if this function is not already on the call stack, put it
344  if (ThisFunction->GetAlreadyOnStack() == false) {
345  AddInclFlag = true;
346  // We need to add Inclusive time when it gets over as
347  // it is not already on callstack.
348 
349  ThisFunction->SetAlreadyOnStack(true); // it is on callstack now
350  }
351  else { // the function is already on callstack, no need to add
352  // inclusive time
353  AddInclFlag = false;
354  }
355 
356  // Initialization is over, now record the time it started
358 #endif // PROFILING_ON
360 
361  DEBUGPROFMSG("Thr " << RtsLayer::myNode() <<
362  " Profiler::Start (FunctionInfo * f) : Name : " <<
363  ThisFunction->GetName() <<" Type : " << ThisFunction->GetType()
364  << endl; );
365 
367 
368 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
369  ExclTimeThisCall = 0;
370 #endif //PROFILE_CALLS || PROFILE_STATS
371  }
372 }
373 
375 
376 Profiler::Profiler( FunctionInfo * function, unsigned int ProfileGroup, bool StartStop)
377 {
378  StartStopUsed_ = StartStop; // will need it later in ~Profiler
379  MyProfileGroup_ = ProfileGroup ;
380  ThisFunction = function ;
382 
383  if(!StartStopUsed_) { // Profiler ctor/dtor interface used
384  Start();
385  }
386 }
387 
388 
390 
392 : StartTime(X.StartTime),
393  ThisFunction(X.ThisFunction),
394  ParentProfiler(X.ParentProfiler),
395  MyProfileGroup_(X.MyProfileGroup_),
396  StartStopUsed_(X.StartStopUsed_)
397 {
398  DEBUGPROFMSG("Profiler::Profiler(const Profiler& X)"<<endl;);
399 
401 
402 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
403  ExclTimeThisCall = X.ExclTimeThisCall;
404 #endif //PROFILE_CALLS || PROFILE_STATS
405 }
406 
408 
410 {
411  StartTime = X.StartTime;
414  MyProfileGroup_ = X.MyProfileGroup_;
416 
417  DEBUGPROFMSG(" Profiler& Profiler::operator= (const Profiler& X)" <<endl;);
418 
419 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
420  ExclTimeThisCall = X.ExclTimeThisCall;
421 #endif //PROFILE_CALLS || PROFILE_STATS
422 
423  return (*this) ;
424 
425 }
426 
428 
430 {
431  if (MyProfileGroup_ & RtsLayer::ProfileMask) {
432 
433 #ifdef TRACING_ON
434  pcxx_Event(ThisFunction->GetFunctionId(), -1); // -1 is for exit
435 #endif //TRACING_ON
436 
437 #ifdef PROFILING_ON // Calculations relevent to profiling only
438  double TotalTime = RtsLayer::getUSecD() - StartTime;
439 
440  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
441  << " Profiler::Stop() : Name : "<< ThisFunction->GetName()
442  << " Start : " <<StartTime <<" TotalTime : " << TotalTime<< endl;);
443 
444  if (AddInclFlag == true) { // The first time it came on call stack
445  ThisFunction->SetAlreadyOnStack(false); // while exiting
446 
447  // And its ok to add both excl and incl times
448  ThisFunction->AddInclTime(TotalTime);
449  DEBUGPROFMSG("Thr "<< RtsLayer::myNode()
450  << " AddInclFlag true in Stop Name: "<< ThisFunction->GetName()
451  << " Type: " << ThisFunction->GetType() << endl; );
452  }
453  // If its already on call stack, don't change AlreadyOnStack
454  ThisFunction->AddExclTime(TotalTime);
455  // In either case we need to add time to the exclusive time.
456 
457 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
458  ExclTimeThisCall += TotalTime;
459  DEBUGPROFMSG("Thr "<< RtsLayer::myNode() << "Profiler::Stop() : Name "
460  << ThisFunction->GetName() << " ExclTimeThisCall = "
461  << ExclTimeThisCall << " InclTimeThisCall " << TotalTime << endl;);
462 
463 #endif //PROFILE_CALLS || PROFILE_STATS
464 
465 #ifdef PROFILE_CALLS
466  ThisFunction->AppendExclInclTimeThisCall(ExclTimeThisCall, TotalTime);
467 #endif // PROFILE_CALLS
468 
469 #ifdef PROFILE_STATS
470  ThisFunction->AddSumExclSqr(ExclTimeThisCall*ExclTimeThisCall);
471 #endif // PROFILE_STATS
472 
473  if (ParentProfiler != 0) {
474 
475  DEBUGPROFMSG("Thr " << RtsLayer::myNode()
476  << " Profiler::Stop(): ParentProfiler Function Name : "
478 
480 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
481  ParentProfiler->ExcludeTimeThisCall(TotalTime);
482 #endif //PROFILE_CALLS || PROFILE_STATS
483 
484  }
485 
486 #endif //PROFILING_ON
487  // First check if timers are overlapping.
488  if (CurrentProfiler[RtsLayer::myThread()] != this) {
489  cout <<"ERROR: Timers Overlap. Illegal operation Profiler::Stop "
490  << ThisFunction->GetName() << " " << ThisFunction->GetType() <<endl;
491  }
492  // While exiting, reset value of CurrentProfiler to reflect the parent
494 
495  } // if ProfileMask
496 }
497 
499 
501 
502  if (!StartStopUsed_) {
503  Stop();
504  } // If ctor dtor interface is used then call Stop.
505  // If the Profiler object is going out of scope without Stop being
506  // called, call it now!
507 
508  if (MyProfileGroup_ & RtsLayer::ProfileMask) {
509  if (ParentProfiler == 0) {
511  // Not a destructor of a static object - its a function like main
512  DEBUGPROFMSG("Thr " << RtsLayer::myNode()
513  << " ~Profiler() : Reached top level function - dumping data"
514  << endl;);
515 
516  StoreData();
517  }
518  // dump data here. Dump it only in the dtor of top level profiler.
519  }
520  }
521 }
522 
524 
525 void Profiler::ProfileExit(const char *message)
526 {
527  Profiler *current;
528 
529  current = CurrentProfiler[RtsLayer::myThread()];
530 
531  DEBUGPROFMSG("Thr "<< RtsLayer::myNode() << " RtsLayer::ProfileExit called :"
532  << message << endl;);
533 
534  while (current != 0) {
535  DEBUGPROFMSG("Thr "<< RtsLayer::myNode() << " ProfileExit() calling Stop :"
536  << current->ThisFunction->GetName() << " "
537  << current->ThisFunction->GetType() << endl;);
538  current->Stop(); // clean up
539 
540  if (current->ParentProfiler == 0) {
541  if (!RtsLayer::isCtorDtor(current->ThisFunction->GetName())) {
542  // Not a destructor of a static object - its a function like main
543  DEBUGPROFMSG("Thr " << RtsLayer::myNode()
544  << " ProfileExit() : Reached top level function - dumping data"
545  << endl;);
546 
547  current->StoreData();
548  }
549  }
550 
551  current = CurrentProfiler[RtsLayer::myThread()]; // Stop should set it
552  }
553 
554 }
555 
557 
559 {
560 #ifdef PROFILING_ON
562  char filename[1024], errormsg[1024];
563  char *dirname;
564  FILE* fp;
565  int numFunc;
566 #endif //PROFILING_ON
567 #ifdef PROFILE_CALLS
568  long listSize, numCalls;
569  std::list<std::pair<double,double> >::iterator iter;
570 #endif // PROFILE_CALLS
571 
572 
573 #ifdef TRACING_ON
574  pcxx_EvClose();
576 #endif // TRACING_ON
577 
578 #ifdef PROFILING_ON
579  if ((dirname = getenv("PROFILEDIR")) == NULL) {
580  // Use default directory name .
581  dirname = new char[8];
582  strcpy (dirname,".");
583  }
584 
585  sprintf(filename,"%s/profile.%d.%d.%d",dirname, RtsLayer::myNode(),
587  DEBUGPROFMSG("Creating " << filename << endl;);
588  if ((fp = fopen (filename, "w+")) == NULL) {
589  sprintf(errormsg,"Error: Could not create %s",filename);
590  perror(errormsg);
591  return 0;
592  }
593 
594  // Data format :
595  // %d templated_functions
596  // "%s %s" %ld %G %G
597  // funcname type numcalls Excl Incl
598  // %d aggregates
599  // <aggregate info>
600 
601  // Recalculate number of funcs using ProfileGroup. Static objects
602  // constructed before setting Profile Groups have entries in FuncDB
603  // (TAU_DEFAULT) even if they are not supposed to be there.
604  //numFunc = (int) FunctionInfo::FunctionDB[RtsLayer::myThread()].size();
605  numFunc = 0;
607  {
608  if ((*it)->GetProfileGroup() & RtsLayer::ProfileMask) {
609  numFunc++;
610  }
611  }
612 
613 #ifdef SGI_HW_COUNTERS
614  fprintf(fp,"%d templated_functions_hw_counters\n", numFunc);
615 #else // SGI_TIMERS, TULIP_TIMERS
616  fprintf(fp,"%d templated_functions\n", numFunc);
617 #endif // SGI_HW_COUNTERS
618 
619  // Send out the format string
620  fprintf(fp,"# Name Calls Subrs Excl Incl ");
621 #ifdef PROFILE_STATS
622  fprintf(fp,"SumExclSqr ");
623 #endif //PROFILE_STATS
624  fprintf(fp,"ProfileCalls\n");
625 
626 
628  {
629  if ((*it)->GetProfileGroup() & RtsLayer::ProfileMask) {
630 
631  DEBUGPROFMSG("Node: "<< RtsLayer::myNode() << " Dumping "
632  << (*it)->GetName()<< " " << (*it)->GetType() << " Calls : "
633  << (*it)->GetCalls() << " Subrs : "<< (*it)->GetSubrs()
634  << " Excl : " << (*it)->GetExclTime() << " Incl : "
635  << (*it)->GetInclTime() << endl;);
636 
637  fprintf(fp,"\"%s %s\" %ld %ld %.16G %.16G ", (*it)->GetName(),
638  (*it)->GetType(), (*it)->GetCalls(), (*it)->GetSubrs(),
639  (*it)->GetExclTime(), (*it)->GetInclTime());
640 
641 #ifdef PROFILE_STATS
642  fprintf(fp,"%.16G ", (*it)->GetSumExclSqr());
643 #endif //PROFILE_STATS
644 
645 #ifdef PROFILE_CALLS
646  listSize = (long) (*it)->ExclInclCallList->size();
647  numCalls = (*it)->GetCalls();
648  // Sanity check
649  if (listSize != numCalls)
650  {
651  fprintf(fp,"0 \n"); // don't write any invocation data
652  DEBUGPROFMSG("Error *** list (profileCalls) size mismatch size "
653  << listSize << " numCalls " << numCalls << endl;);
654  }
655  else { // List is maintained correctly
656  fprintf(fp,"%ld \n", listSize); // no of records to follow
657  for (iter = (*it)->ExclInclCallList->begin();
658  iter != (*it)->ExclInclCallList->end(); iter++)
659  {
660  DEBUGPROFMSG("Node: " << RtsLayer::myNode() <<" Name "
661  << (*it)->GetName() << " " << (*it)->GetType()
662  << " ExclThisCall : "<< (*iter).first <<" InclThisCall : "
663  << (*iter).second << endl; );
664  fprintf(fp,"%G %G\n", (*iter).first , (*iter).second);
665  }
666  } // sanity check
667 #else // PROFILE_CALLS
668  fprintf(fp,"0 \n"); // Indicating - profile calls is turned off
669 #endif // PROFILE_CALLS
670  } // ProfileGroup test
671  } // for loop. End of FunctionInfo data
672  fprintf(fp,"0 aggregates\n"); // For now there are no aggregates
673  // Change this when aggregate profiling in introduced in Ippl
674 
675  fclose(fp);
676 
677 #endif //PROFILING_ON
678  return 1;
679 }
680 
682 
683 #if ( defined(PROFILE_CALLS) || defined(PROFILE_STATS) )
684 int Profiler::ExcludeTimeThisCall(double t)
685 {
686  ExclTimeThisCall -= t;
687  return 1;
688 }
689 #endif //PROFILE_CALLS || PROFILE_STATS
690 
692 
694 // Member Function Definitions For class RtsLayer
695 // Important for Porting to other platforms and frameworks.
697 
699 
700 unsigned int RtsLayer::enableProfileGroup(unsigned int ProfileGroup) {
701  ProfileMask |= ProfileGroup; // Add it to the mask
702  DEBUGPROFMSG("enableProfileGroup " << ProfileGroup <<" Mask = " << ProfileMask << endl;);
703  return ProfileMask;
704 }
705 
707 
708 unsigned int RtsLayer::resetProfileGroup(void) {
709  ProfileMask = 0;
710  return ProfileMask;
711 }
712 
714 int RtsLayer::setMyNode(int NodeId) {
715  Node = NodeId;
716 // At this stage, we should create the trace file because we know the node id
717 #ifdef TRACING_ON
718  char *dirname, tracefilename[1024];
719  if ((dirname = getenv("TRACEDIR")) == NULL) {
720  // Use default directory name .
721  dirname = new char[8];
722  strcpy (dirname,".");
723  }
724  sprintf(tracefilename, "%s/tau.####.trc",dirname);
725  pcxx_EvInit(tracefilename);
726 #endif // TRACING_ON
727  return Node;
728 }
729 
731 
732 bool RtsLayer::isEnabled(unsigned int ProfileGroup) {
733 unsigned int res = ProfileGroup & ProfileMask ;
734 
735  if (res > 0)
736  return true;
737  else
738  return false;
739 }
740 
742 
743 #ifdef SGI_HW_COUNTERS
744 extern "C" {
745  int start_counters( int e0, int e1 );
746  int read_counters( int e0, long long *c0, int e1, long long *c1);
747 };
748 #endif // SGI_HW_COUNTERS
749 
751 #ifdef SGI_HW_COUNTERS
753 {
754  int e0, e1;
755  int start;
756 
757 
758  e0 = 0;
759  e1 = 0;
760 
761 
762 // int x0, x1;
763  //
764  // DO NOT remove the following two lines. Otherwise start_counters
765  // crashes with "prioctl PIOCENEVCTRS returns error: Invalid argument"
766 
767 /*
768  x0 = e0;
769  x1 = e1;
770 */
771 
772  if((start = start_counters(e0,e1)) < 0) {
773  perror("start_counters");
774  exit(0);
775  }
776  return start;
777 }
778 #endif // SGI_HW_COUNTERS
779 
781 #ifdef SGI_HW_COUNTERS
783 {
784  static int gen_start = SetEventCounter();
785  int gen_read;
786  int e0 = 0, e1 = 0;
787  long long c0 , c1 ;
788  static double accum = 0;
789 
790  if ((gen_read = read_counters(e0, &c0, e1, &c1)) < 0) {
791  perror("read_counters");
792  }
793 
794  if (gen_read != gen_start) {
795  perror("lost counter! aborting...");
796  exit(1);
797  }
798 
799  accum += c0;
800  DEBUGPROFMSG("Read counters e0 " << e0 <<" e1 "<< e1<<" gen_read "
801  << gen_read << " gen_start = " << gen_start << " accum "<< accum
802  << " c0 " << c0 << " c1 " << c1 << endl;);
803  gen_start = SetEventCounter(); // Reset the counter
804 
805  return accum;
806 }
807 #endif //SGI_HW_COUNTERS
808 
810 
812 
813 #ifdef SGI_HW_COUNTERS
814  return RtsLayer::GetEventCounter();
815 #else //SGI_HW_COUNTERS
816 
817 #ifdef SGI_TIMERS
818  struct timespec tp;
819  clock_gettime(CLOCK_SGI_CYCLE,&tp);
820  return (tp.tv_sec * 1e6 + (tp.tv_nsec * 1e-3)) ;
821 
822 #else
823 #if (defined(IPPL_TFLOP) || !defined(TULIP_TIMERS))
824  struct timeval tp;
825  gettimeofday (&tp, 0);
826  return ( tp.tv_sec * 1000000 + tp.tv_usec );
827 #else // TULIP_TIMERS by default.
828  return pcxx_GetUSecD();
829 #endif //IPPL_TFLOP
830 #endif //SGI_TIMERS
831 
832 #endif // SGI_HW_COUNTERS
833  }
834 
836 //Note: This is similar to Tulip event classes during tracing
837 int RtsLayer::setAndParseProfileGroups(char *prog, char *str)
838 {
839  char *end;
840 
841  if (str) {
842  while (str && *str) {
843  if ( ( end = strchr(str, '+') ) != NULL ) *end = '\0';
844  switch (str[0])
845  {
846  case 'a' :
847  case 'A' :
849  break;
850  case 'f' :
851  case 'F' : // Field or FFT Group
852  if (strncasecmp(str, "ff", 2) == 0) {
853  // FFT enabled
855  }
856  else {
857  // Field enabled
859  }
860  break;
861  case 'c' :
862  case 'C' : // Communication Group
864  break;
865  case 'i' :
866  case 'I' : // IO Group
868  break;
869  case 'l' :
870  case 'L' : // Field Layout Group
872  break;
873  case 'm' :
874  case 'M' : // Mesh or Message Group
875  if (strncasecmp(str,"mesh", 4) == 0) {
876  // Meshes enabled
878  }
879  else {
880  // Message Profile Group enabled
882  }
883  break;
884  case 'p' :
885  case 'P' : // PAWS1, PAWS2, PAWS3, Particle, or PETE Group
886  if (strncasecmp(str, "paws1", 5) == 0) {
887  // PAWS1 enabled
889  }
890  else if (strncasecmp(str, "paws2", 5) == 0) {
891  // PAWS2 enabled
893  }
894  else if (strncasecmp(str, "paws3", 5) == 0) {
895  // PAWS3 enabled
897  }
898  else if (strncasecmp(str, "pa", 2) == 0) {
899  // Particle enabled
901  }
902  else {
903  // PETE Profile Group enabled
905  }
906  break;
907  case 'r' :
908  case 'R' : // Region Group
910  break;
911  case 's' :
912  case 'S' : // SubField or Sparse Index Group
913  if (strncasecmp(str, "su", 2) == 0) {
914  // SubField enabled
916  }
917  else {
918  // Sparse Index Group
920  }
921  break;
922  case 'd' :
923  case 'D' : // Descriptor or DomainMap Group
924  if (strncasecmp(str, "de", 2) == 0) {
925  // Descriptor Overhead profiling enabled
927  }
928  else {
929  // DomainMap profiling enabled
931  }
932  break;
933  case 'u' :
934  case 'U' : // User or Utility
935  if (strncasecmp(str,"ut", 2) == 0) {
936  // Utility profiling enabled
938  }
939  else {
940  // default - for u is USER
942  }
943  break;
944  case '1' : // User1
946  break;
947  case '2' : // User2
949  break;
950  case '3' : // User3
952  break;
953  case '4' : // User4
955  break;
956  default :
957  cout << prog << " : Invalid Profile Group " << str << endl;
958  break;
959  }
960  if ( (str = end) != NULL ) *str++ = '+';
961  }
962  }
963  else {
964  enableProfileGroup(TAU_DEFAULT); // Enable everything
965  }
966  return 1;
967 }
968 
970 void RtsLayer::ProfileInit(int argc, char **argv)
971 {
972  int i;
973 
974  for (i=0; i<argc; i++) {
975  if (strcmp(argv[i],"--profile") == 0) {
976  // Enable the profile groups
977  if ( (i + 1) < argc && argv[i+1][0] != '-' ) { // options follow
978  RtsLayer::resetProfileGroup(); // set it to blank
979  RtsLayer::setAndParseProfileGroups(argv[0], argv[i+1]);
980  }
981  }
982  }
983  return;
984 }
985 
986 
988 bool RtsLayer::isCtorDtor(const char *name)
989 {
990 
991  // If the destructor a static object is called, it could have a null name
992  // after main is over. Treat it like a Dtor and return true.
993  if (name[0] == 0) {
994  DEBUGPROFMSG("isCtorDtor name is NULL" << endl;);
995  return true;
996  }
997  DEBUGPROFMSG("RtsLayer::isCtorDtor("<< name <<")" <<endl;);
998  if (strchr(name,'~') == NULL) // a destructor
999  if (strchr(name,':') == NULL) // could be a constructor
1000  return false;
1001  else
1002  return true;
1003  else
1004  return true;
1005 }
1006 
1008 // PrimaryGroup returns the first group that the function belongs to.
1009 // This is needed in tracing as Vampir can handle only one group per
1010 // function. PrimaryGroup("TAU_FIELD | TAU_USER") should return "TAU_FIELD"
1012 string RtsLayer::PrimaryGroup(const char *ProfileGroupName)
1013 {
1014  string groups = ProfileGroupName;
1015  string primary;
1016  string separators = " |";
1017  int start, stop, n;
1018 
1019  start = groups.find_first_not_of(separators);
1020  n = groups.length();
1021  stop = groups.find_first_of(separators, start);
1022 
1023  if ((stop < 0) || (stop > n)) stop = n;
1024 
1025  primary = groups.substr(start, stop - start) ;
1026  return primary;
1027 
1028 }
1029 
1031 // TraceSendMsg traces the message send
1033 void RtsLayer::TraceSendMsg(int type, int destination, int length)
1034 {
1035 #ifdef TRACING_ON
1036  long int parameter, othernode;
1037 
1039  {
1040  parameter = 0L;
1041  /* for send, othernode is receiver or destination */
1042  othernode = (long int) destination;
1043  /* Format for parameter is
1044  31 ..... 24 23 ......16 15..............0
1045  other type length
1046  */
1047 
1048  parameter = (length & 0x0000FFFF) | ((type & 0x000000FF) << 16) |
1049  (othernode << 24);
1050  pcxx_Event(TAU_MESSAGE_SEND, parameter);
1051 #ifdef DEBUG_PROF
1052  printf("Node %d TraceSendMsg, type %x dest %x len %x par %lx \n",
1053  RtsLayer::myNode(), type, destination, length, parameter);
1054 #endif //DEBUG_PROF
1055  }
1056 #endif //TRACING_ON
1057 }
1058 
1059 
1061 // TraceRecvMsg traces the message recv
1063 void RtsLayer::TraceRecvMsg(int type, int source, int length)
1064 {
1065 #ifdef TRACING_ON
1066  long int parameter, othernode;
1067 
1069  {
1070  parameter = 0L;
1071  /* for recv, othernode is sender or source*/
1072  othernode = (long int) source;
1073  /* Format for parameter is
1074  31 ..... 24 23 ......16 15..............0
1075  other type length
1076  */
1077 
1078  parameter = (length & 0x0000FFFF) | ((type & 0x000000FF) << 16) |
1079  (othernode << 24);
1080  pcxx_Event(TAU_MESSAGE_RECV, parameter);
1081 
1082 #ifdef DEBUG_PROF
1083  printf("Node %d TraceRecvMsg, type %x src %x len %x par %lx \n",
1084  RtsLayer::myNode(), type, source, length, parameter);
1085 #endif //DEBUG_PROF
1086  }
1087 #endif //TRACING_ON
1088 }
1089 
1091 // DumpEDF() writes the function information in the edf.<node> file
1092 // The function info consists of functionId, group, name, type, parameters
1095 {
1096 #ifdef TRACING_ON
1098  char filename[1024], errormsg[1024];
1099  char *dirname;
1100  FILE* fp;
1101  int numEvents, numExtra;
1102 
1103 
1104  if ((dirname = getenv("TRACEDIR")) == NULL) {
1105  // Use default directory name .
1106  dirname = new char[8];
1107  strcpy (dirname,".");
1108  }
1109 
1110  sprintf(filename,"%s/events.%d.edf",dirname, RtsLayer::myNode());
1111  DEBUGPROFMSG("Creating " << filename << endl;);
1112  if ((fp = fopen (filename, "w+")) == NULL) {
1113  sprintf(errormsg,"Error: Could not create %s",filename);
1114  perror(errormsg);
1115  return 0;
1116  }
1117 
1118  // Data Format
1119  // <no.> events
1120  // # or \n ignored
1121  // %s %s %d "%s %s" %s
1122  // id group tag "name type" parameters
1123 
1124  numExtra = 9; // Number of extra events
1125  numEvents = FunctionInfo::FunctionDB[RtsLayer::myThread()].size();
1126 
1127  numEvents += numExtra;
1128 
1129  fprintf(fp,"%d dynamic_trace_events\n", numEvents);
1130 
1131  fprintf(fp,"# FunctionId Group Tag \"Name Type\" Parameters\n");
1132 
1133  for (it = FunctionInfo::FunctionDB[RtsLayer::myThread()].begin();
1134  it != FunctionInfo::FunctionDB[RtsLayer::myThread()].end(); it++)
1135  {
1136  DEBUGPROFMSG("Node: "<< RtsLayer::myNode() << " Dumping EDF Id : "
1137  << (*it)->GetFunctionId() << " " << (*it)->GetPrimaryGroup()
1138  << " 0 " << (*it)->GetName() << " " << (*it)->GetType()
1139  << " EntryExit" << endl;);
1140 
1141  fprintf(fp, "%ld %s 0 \"%s %s\" EntryExit\n", (*it)->GetFunctionId(),
1142  (*it)->GetPrimaryGroup(), (*it)->GetName(), (*it)->GetType() );
1143  }
1144  // Now add the nine extra events
1145  fprintf(fp,"%ld TRACER 0 \"EV_INIT\" none\n", (long) PCXX_EV_INIT);
1146  fprintf(fp,"%ld TRACER 0 \"FLUSH_ENTER\" none\n", (long) PCXX_EV_FLUSH_ENTER);
1147  fprintf(fp,"%ld TRACER 0 \"FLUSH_EXIT\" none\n", (long) PCXX_EV_FLUSH_EXIT);
1148  fprintf(fp,"%ld TRACER 0 \"FLUSH_CLOSE\" none\n", (long) PCXX_EV_CLOSE);
1149  fprintf(fp,"%ld TRACER 0 \"FLUSH_INITM\" none\n", (long) PCXX_EV_INITM);
1150  fprintf(fp,"%ld TRACER 0 \"WALL_CLOCK\" none\n", (long) PCXX_EV_WALL_CLOCK);
1151  fprintf(fp,"%ld TRACER 0 \"CONT_EVENT\" none\n", (long) PCXX_EV_CONT_EVENT);
1152  fprintf(fp,"%ld TAU_MESSAGE -7 \"MESSAGE_SEND\" par\n", (long) TAU_MESSAGE_SEND);
1153  fprintf(fp,"%ld TAU_MESSAGE -8 \"MESSAGE_RECV\" par\n", (long) TAU_MESSAGE_RECV);
1154 
1155 
1156  fclose(fp);
1157 #endif //TRACING_ON
1158  return 1;
1159 }
1160 
1161 
1162 /***************************************************************************
1163  * $RCSfile: Profiler.cpp,v $ $Author: adelmann $
1164  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
1165  * IPPL_VERSION_ID: $Id: Profiler.cpp,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
1166  ***************************************************************************/
1167 
1168 
1169 
static Profiler * CurrentProfiler[1024]
Definition: Profiler.h:261
#define DEBUGPROFMSG(msg)
Definition: Profiler.cpp:81
double InclTime
Definition: Profiler.h:153
#define TAU_USER1
Definition: Profiler.h:74
static unsigned int enableProfileGroup(unsigned int ProfileGroup)
Definition: Profiler.cpp:700
#define TAU_UTILITY
Definition: Profiler.h:50
static int Node
Definition: Profiler.h:291
#define TAU_USER4
Definition: Profiler.h:71
void IncrNumCalls(void)
Definition: Profiler.h:211
const char * GetName() const
Definition: Profiler.h:165
double StartTime
Definition: Profiler.h:262
constexpr double e
The value of .
Definition: Physics.h:40
unsigned int MyProfileGroup_
Definition: Profiler.h:180
static unsigned int resetProfileGroup(void)
Definition: Profiler.cpp:708
#define TAU_DEFAULT
Definition: Profiler.h:40
Definition: rbendmap.h:8
FunctionInfo * ThisFunction
Definition: Profiler.h:263
long NumCalls
Definition: Profiler.h:150
static int myContext()
Definition: Profiler.h:333
static int setAndParseProfileGroups(char *prog, char *str)
Definition: Profiler.cpp:837
#define TAU_PARTICLE
Definition: Profiler.h:52
Profiler & operator=(const Profiler &X)
Definition: Profiler.cpp:409
long NumSubrs
Definition: Profiler.h:151
void AddExclTime(double t)
Definition: Profiler.h:205
static void ProfileExit(const char *message=0)
Definition: Profiler.cpp:525
#define TAU_REGION
Definition: Profiler.h:51
void AddInclTime(double t)
Definition: Profiler.h:199
#define TAU_PAWS2
Definition: Profiler.h:66
static std::string PrimaryGroup(const char *ProfileGroupName)
Definition: Profiler.cpp:1012
void SetAlreadyOnStack(bool value)
Definition: Profiler.h:217
unsigned int MyProfileGroup_
Definition: Profiler.h:267
static bool isCtorDtor(const char *name)
Definition: Profiler.cpp:988
static std::vector< FunctionInfo * > FunctionDB[1024]
Definition: Profiler.h:135
std::string Type
Definition: Profiler.h:161
long GetFunctionId() const
Definition: Profiler.h:168
static int setMyNode(int NodeId)
Definition: Profiler.cpp:714
#define TAU_FIELD
Definition: Profiler.h:46
#define TAU_PETE
Definition: Profiler.h:42
void Start()
Definition: Profiler.cpp:330
bool AddInclFlag
Definition: Profiler.h:269
bool StartStopUsed_
Definition: Profiler.h:268
#define TAU_DOMAINMAP
Definition: Profiler.h:49
#define TAU_LAYOUT
Definition: Profiler.h:47
#define TAU_USER
Definition: Profiler.h:75
#define TAU_COMMUNICATION
Definition: Profiler.h:55
#define TAU_MESHES
Definition: Profiler.h:53
static int myThread()
Definition: Profiler.h:337
#define TAU_USER3
Definition: Profiler.h:72
static void TraceSendMsg(int type, int destination, int length)
Definition: Profiler.cpp:1033
static void TraceRecvMsg(int type, int source, int length)
Definition: Profiler.cpp:1063
static int myNode()
Definition: Profiler.h:330
static double GetEventCounter(void)
FunctionInfo & operator=(const FunctionInfo &X)
Definition: Profiler.cpp:288
#define TAU_SPARSE
Definition: Profiler.h:48
Profiler * ParentProfiler
Definition: Profiler.h:264
#define TAU_ASSIGN
Definition: Profiler.h:44
static bool isEnabled(unsigned int ProfileGroup)
Definition: Profiler.cpp:732
static int DumpEDF(void)
Definition: Profiler.cpp:1094
#define TAU_SUBFIELD
Definition: Profiler.h:54
bool GetAlreadyOnStack(void)
Definition: Profiler.h:223
#define TAU_DESCRIPTOR_OVERHEAD
Definition: Profiler.h:56
void ExcludeTime(double t)
Definition: Profiler.h:191
#define TAU_USER2
Definition: Profiler.h:73
const char * GetType() const
Definition: Profiler.h:166
const std::string name
int StoreData(void)
Definition: Profiler.cpp:558
#define TAU_MAX_THREADS
Definition: Profiler.h:77
#define TAU_MESSAGE
Definition: Profiler.h:41
void Stop()
Definition: Profiler.cpp:429
static unsigned int ProfileMask
Definition: Profiler.h:290
double ExclTime
Definition: Profiler.h:152
#define TAU_PAWS3
Definition: Profiler.h:67
std::string::iterator iterator
Definition: MSLang.h:16
std::string Name
Definition: Profiler.h:160
#define TAU_IO
Definition: Profiler.h:45
static int SetEventCounter(void)
Profiler(FunctionInfo *fi, unsigned int ProfileGroup=0xffffffff, bool StartStop=false)
Definition: Profiler.cpp:376
FunctionInfo(const char *name, const char *type, unsigned int ProfileGroup=0xffffffff, const char *ProfileGroupName="TAU_DEFAULT")
Definition: Profiler.cpp:102
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define TAU_PAWS1
Definition: Profiler.h:65
static double getUSecD(void)
Definition: Profiler.cpp:811
static void ProfileInit(int argc, char **argv)
Definition: Profiler.cpp:970
#define TAU_FFT
Definition: Profiler.h:63