Added support to trace communication thread in SMP mode. To enable this, compile...
authorChao Mei <chaomei2@illinois.edu>
Fri, 9 Oct 2009 23:04:34 +0000 (23:04 +0000)
committerChao Mei <chaomei2@illinois.edu>
Fri, 9 Oct 2009 23:04:34 +0000 (23:04 +0000)
src/ck-core/init.C
src/ck-perf/trace-common.C
src/ck-perf/trace-projections.C
src/ck-perf/trace-projections.h
src/ck-perf/trace.h

index 17afa9a8073b0b8e80da20b2b9d00729c265367e..7be61abdfe530c78ca0a657c56446a8ff3bb89a7 100644 (file)
@@ -913,10 +913,13 @@ void _initCharm(int unused_argc, char **argv)
        CkpvAccess(_msgPool) = new MsgPool();
 
        CmiNodeAllBarrier();
-
+#if CMK_SMP_TRACE_COMMTHREAD
+       _TRACE_BEGIN_COMPUTATION();     
+#else
        if (!inCommThread) {
          _TRACE_BEGIN_COMPUTATION();
        }
+#endif
 
 #ifdef ADAPT_SCHED_MEM
     if(CkMyRank()==0){
index c055541043af55f41f55756500b7c8d8cf4d0811..3a49d89e4adee27f7b7f4f529fdcb96488347af0 100644 (file)
@@ -189,7 +189,12 @@ static void traceCommonInit(char **argv)
 /** Write out the common parts of the .sts file. */
 extern void traceWriteSTS(FILE *stsfp,int nUserEvents) {
   fprintf(stsfp, "MACHINE %s\n",CMK_MACHINE_NAME);
+#if CMK_SMP_TRACE_COMMTHREAD
+  //considering the extra comm thread per node
+  fprintf(stsfp, "PROCESSORS %d\n", CkNumPes()+CkNumNodes());
+#else  
   fprintf(stsfp, "PROCESSORS %d\n", CkNumPes());
+#endif 
   fprintf(stsfp, "TOTAL_CHARES %d\n", _chareTable.size());
   fprintf(stsfp, "TOTAL_EPS %d\n", _entryTable.size());
   fprintf(stsfp, "TOTAL_MSGS %d\n", _msgTable.size());
@@ -226,6 +231,17 @@ void TraceArray::traceBegin() {
   ALLDO(traceBegin());
 }
 
+#if CMK_SMP_TRACE_COMMTHREAD
+void TraceArray::traceBeginOnCommThread() {
+  if (n==0) return; // No tracing modules registered.
+/*#if ! CMK_TRACE_IN_CHARM     
+  cancel_beginIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)traceCommonBeginIdle,this);
+  cancel_endIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,(CcdVoidFn)traceCommonEndIdle,this);
+#endif*/
+  ALLDO(traceBeginOnCommThread());
+}
+#endif
+
 void TraceArray::traceEnd() {
   if (n==0) return; // No tracing modules registered.
   ALLDO(traceEnd());
@@ -235,10 +251,32 @@ void TraceArray::traceEnd() {
 #endif
 }
 
+#if CMK_SMP_TRACE_COMMTHREAD
+void TraceArray::traceEndOnCommThread() {
+  if (n==0) return; // No tracing modules registered.
+  ALLDO(traceEndOnCommThread());
+/*#if ! CMK_TRACE_IN_CHARM
+  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE, cancel_beginIdle);
+  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY, cancel_endIdle);
+#endif*/
+}
+#endif
+
+
 /*Install the beginIdle/endIdle condition handlers.*/
 extern "C" void traceBegin(void) {
 #ifndef CMK_OPTIMIZE
   DEBUGF(("[%d] traceBegin called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
+  
+#if CMK_SMP_TRACE_COMMTHREAD
+  //the first core of this node controls the condition of comm thread
+  if(CmiMyRank()==0){
+       if(CkpvAccessOther(traceOn, CmiMyNodeSize())!=1){
+               CkpvAccessOther(_traces, CmiMyNodeSize())->traceBeginOnCommThread();            
+               CkpvAccessOther(traceOn, CmiMyNodeSize()) = 1;
+       }
+  }
+#endif
   if (CpvAccess(traceOn)==1) return;
   CkpvAccess(_traces)->traceBegin();
   CpvAccess(traceOn) = 1;
@@ -249,6 +287,18 @@ extern "C" void traceBegin(void) {
 extern "C" void traceEnd(void) {
 #ifndef CMK_OPTIMIZE
   DEBUGF(("[%d] traceEnd called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
+
+#if CMK_SMP_TRACE_COMMTHREAD
+//the first core of this node controls the condition of comm thread
+if(CmiMyRank()==0){
+       if(CkpvAccessOther(traceOn, CmiMyNodeSize())!=0){
+               CkpvAccessOther(_traces, CmiMyNodeSize())->traceEndOnCommThread();
+               CkpvAccessOther(traceOn, CmiMyNodeSize()) = 0;
+       }
+}
+#endif
+       
+       
   if (CpvAccess(traceOn)==0) return;
   if (CkpvAccess(_traces) == NULL) {
     CmiPrintf("Warning: did you mix compilation with and without -DCMK_OPTIMIZE? \n");
@@ -275,8 +325,10 @@ static int checkTraceOnPe(char **argv)
   // must include pe 0, otherwise sts file is not generated
   if (CkMyPe()==0) traceOnPE = 1;
 #if !CMK_TRACE_IN_CHARM
+#if !CMK_SMP_TRACE_COMMTHREAD
   /* skip communication thread */
   traceOnPE = traceOnPE && (CkMyRank() != CkMyNodeSize());
+#endif
 #endif
   return traceOnPE;
 }
index 4ab10b269ad2ce67009657ad8b7401ed0318d286..27e989aab6b65c1405e7ddda9ca6cdfce33efd91 100644 (file)
@@ -625,8 +625,25 @@ void LogPool::addUserSuppliedNote(char *note){
 void LogPool::addUserSuppliedBracketedNote(char *note, int eventID, double bt, double et){
   //CkPrintf("LogPool::addUserSuppliedBracketedNote eventID=%d\n", eventID);
 #ifndef CMK_BLUEGENE_CHARM
+#if CMK_SMP_TRACE_COMMTHREAD && MPI_SMP_TRACE_COMMTHREAD_HACK  
+//This part of code is used  to combine the contiguous
+//MPI_Test and MPI_Iprobe events to reduce the number of
+//entries
+#define MPI_TEST_EVENT_ID 60
+#define MPI_IPROBE_EVENT_ID 70 
+int lastEvent = pool[numEntries-1].event;
+if((eventID==MPI_TEST_EVENT_ID || eventID==MPI_IPROBE_EVENT_ID) && (eventID==lastEvent)){
+    //just replace the endtime of last event
+    //CkPrintf("addUserSuppliedBracketNote: for event %d\n", lastEvent);
+    pool[numEntries].endTime = et;
+}else{
   new (&pool[numEntries++])
        LogEntry(bt, et, USER_SUPPLIED_BRACKETED_NOTE, note, eventID);
+}
+#else
+  new (&pool[numEntries++])
+       LogEntry(bt, et, USER_SUPPLIED_BRACKETED_NOTE, note, eventID);
+#endif
   if(poolSize == numEntries){
     flushLogBuffer();
   }
@@ -1048,6 +1065,19 @@ void TraceProjections::traceEnd(void)
   _logPool->add(END_TRACE, 0, 0, TraceTimer(), curevent++, CkMyPe());
 }
 
+#if CMK_SMP_TRACE_COMMTHREAD
+void TraceProjections::traceBeginOnCommThread()
+{
+  if (!computationStarted) return;
+  _logPool->add(BEGIN_TRACE, 0, 0, TraceTimer(), curevent++, CmiNumPes()+CmiMyNode());
+}
+
+void TraceProjections::traceEndOnCommThread()
+{
+  _logPool->add(END_TRACE, 0, 0, TraceTimer(), curevent++, CmiNumPes()+CmiMyNode());
+}
+#endif
+
 void TraceProjections::userEvent(int e)
 {
   if (!computationStarted) return;
index 46712fe93920f422247a28f670e49911a06ac9c8..e3baf0c00a6962b7355eb83e8bb590ced02e8159 100644 (file)
@@ -417,7 +417,7 @@ class TraceProjections : public Trace {
     LONG_LONG_PAPI *papiValues;
 #endif
 
 public:
+ public:
     int converseExit; // used for exits that bypass CkExit.
     double endTime;
 
@@ -454,8 +454,12 @@ class TraceProjections : public Trace {
     void traceClearEps();
     void traceWriteSts();
     void traceClose();
-    void traceBegin();
+    void traceBegin();    
     void traceEnd();
+ #if CMK_SMP_TRACE_COMMTHREAD          
+    void traceBeginOnCommThread();
+    void traceEndOnCommThread();
+#endif         
     void traceFlushLog() { _logPool->flushLogBuffer(); }
 
     //functions that perform function tracing
index d5de47863a9fb62e1bac36dcf0c76c1dc8559203..82189e0d33201ccd9e773f4d7017bcb8433bd54d 100644 (file)
@@ -56,6 +56,7 @@ typedef CMK_TYPEDEF_INT8 LONG_LONG_PAPI;
 class Trace {
   protected:
     int _traceOn;
+  
   public:
     Trace(): _traceOn(0) {}
     virtual void setTraceOnPE(int flag) { _traceOn = flag; }
@@ -65,6 +66,11 @@ class Trace {
     // is specified
     virtual void traceBegin() {}
     virtual void traceEnd() {}
+#if CMK_SMP_TRACE_COMMTHREAD           
+    virtual void traceBeginOnCommThread() {}   
+    virtual void traceEndOnCommThread() {}
+#endif 
+               
     // registers user event trace module returns int identifier 
     virtual int traceRegisterUserEvent(const char* eventName, int e) { 
       return 0; 
@@ -246,9 +252,14 @@ public:
     // Tracing module registers *itself* for begin/end idle callbacks:
     inline void beginIdle(double curWallTime) {ALLDO(beginIdle(curWallTime));}
     inline void endIdle(double curWallTime) {ALLDO(endIdle(curWallTime));}
-    void traceBegin();
+    void traceBegin();    
     void traceEnd();
 
+#if CMK_SMP_TRACE_COMMTHREAD
+    void traceBeginOnCommThread();
+    void traceEndOnCommThread();
+#endif
+       
     /*Calls for tracing function begins and ends*/
     inline void regFunc(const char *name, int &idx, int idxSpecifiedByUser=0){ ALLDO(regFunc(name, idx, idxSpecifiedByUser)); }
     inline void beginFunc(char *name,char *file,int line){ ALLDO(beginFunc(name,file,line)); };