Added new feature in the mpi machine layer to add user events on MPI_Barrier,
authorChee Wai Lee <cheelee@illinois.edu>
Thu, 25 Jan 2007 22:00:12 +0000 (22:00 +0000)
committerChee Wai Lee <cheelee@illinois.edu>
Thu, 25 Jan 2007 22:00:12 +0000 (22:00 +0000)
MPI_Send, MPI_Recv, MPI_Isend and MPI_Irecv calls when the trace-projections
module is active.

Fixed 2 bugs associated with this:

  1) Machine layers used to (technically incorrect) register user events
     at ConverseExit. This is no longer possible as trace-projections is
     now a charm++ module. I've created a callback framework for machine
     layers to register their user event registration function which are
     then called by the (interested) trace module at the appropriate time.
     The MPI machine layer now uses this, ELAN still does not as I cannot
     test this easily and we don't typically do perf analysis on lemieux
     anymore, so there are no immediate problems with not updating the
     ELAN layer to do this.

  2) Performance analysis modules have *never* been tested properly with
     -DCMK_OPTIMIZE. trace-summary and trace-projections registers a
     callback function at module-exit time (called at CkExit) which, if
     simple like trace-summary's, escapes notice. trace-projections, on
     the other hand makes extensive use of the trace structure on close.
     This dies horribly since those structures are never created when the
     runtime is compiled with -DCMK_OPTIMIZE. My change is to simply call
     CkExit for the callback function (required to allow other modules to
     exercise their exit-callbacks) when CMK_OPTIMIZE is defined.

A third bug is left unfixed: Not all projections options are consumed even
if CMK_OPTIMIZE is defined. This has a not-so-intuitive effect of getting
a projections option passed down to the application (which may barf on it).
The proper behavior should have all options processed by the tracing
framework and OPTIMIZE_WARNING issued if CMK_OPTIMIZE is defined.

src/arch/mpi/conv-common.h
src/arch/mpi/machine.c
src/ck-perf/trace-common.C
src/ck-perf/trace-common.h
src/ck-perf/trace-projections.C
src/ck-perf/trace-summary.C
src/ck-perf/trace.h
src/conv-core/conv-trace.h

index 885e1fb91bbab92b8b75fd0bedb4477df4a18012..dd8a9cfec218b3078b0b39de87b236b707cf271d 100644 (file)
@@ -3,6 +3,8 @@
 
 #define CMK_CMIPRINTF_IS_A_BUILTIN                         0
 
+#define CMI_MPI_TRACE_USEREVENTS                           0
+
 #define CMK_HANDLE_SIGUSR                                  1
 
 #define CMK_MSG_HEADER_EXT_    CmiUInt2 rank, root, hdl,xhdl,info, stratid; unsigned char cksum, magic;  CmiUInt2 padding;
index 8c916794583931fd0b57a7b0e38a3feb3ee84073..58c2562ffa220d9d1509e79ed7b99e6e0aab0e8f 100644 (file)
 #define MAX_QLEN 200
 #endif
 
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+CpvDeclare(double, projTraceStart);
+#endif
+#endif
+#endif
 
 /*
     To reduce the buffer used in broadcast and distribute the load from
@@ -252,6 +259,7 @@ void CmiTimerInit()
 #else
       starttimer = MPI_Wtime();
 #endif
+
       MPI_Allreduce(&starttimer, &minTimer, 1, MPI_DOUBLE, MPI_MIN,
                                   MPI_COMM_WORLD );
       starttimer = minTimer;
@@ -327,9 +335,38 @@ double CmiCpuTimer(void)
 
 void CmiBarrier()
 {
-  if (CmiMyRank() == 0)
+  if (CmiMyRank() == 0) {
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+  CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+  CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
     if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD))
         CmiAbort("Timernit: MPI_Barrier failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(10, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(10, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
+  }
 }
 
 /* CmiBarrierZero make sure node 0 is the last one exiting the barrier */
@@ -342,14 +379,68 @@ void CmiBarrierZero()
     if (CmiMyNode() == 0)  {
       for (i=0; i<CmiNumNodes()-1; i++) {
          CmiPrintf("CmiBarrierZero loop\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+        CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+        CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
           if (MPI_SUCCESS != MPI_Recv(msg,1,MPI_BYTE,MPI_ANY_SOURCE,BARRIER_ZERO_TAG, MPI_COMM_WORLD,&sts))
             printf("MPI_Recv failed!\n");
 
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(30, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(30, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
       }
     }
     else {
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+      CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+      CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
       if (MPI_SUCCESS != MPI_Send((void *)msg,1,MPI_BYTE,0,BARRIER_ZERO_TAG,MPI_COMM_WORLD))
          printf("MPI_Send failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(20, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(20, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
     }
   }
   CmiNodeAllBarrier();
@@ -595,6 +686,19 @@ int PumpMsgs(void)
         msg = (char *) CmiAlloc(nbytes);
         memcpy(msg,&(CpvAccess(CmiPostedRecvBuffers)[completed_index*MPI_POST_RECV_SIZE]),nbytes);
         /* and repost the recv */
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+       CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+       CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
         if (MPI_SUCCESS != MPI_Irecv(  &(CpvAccess(CmiPostedRecvBuffers)[completed_index*MPI_POST_RECV_SIZE])  ,
             MPI_POST_RECV_SIZE,
             MPI_BYTE,
@@ -603,6 +707,21 @@ int PumpMsgs(void)
             MPI_COMM_WORLD,
             &(CpvAccess(CmiPostedRecvRequests)[completed_index])  ))
                 CmiAbort("PumpMsgs: MPI_Irecv failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(50, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(50, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
         CpvAccess(Cmi_posted_recv_total)++;
     }
     else {
@@ -614,8 +733,35 @@ int PumpMsgs(void)
         MPI_Get_count(&sts, MPI_BYTE, &nbytes);
         msg = (char *) CmiAlloc(nbytes);
 
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+       CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+       CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
         if (MPI_SUCCESS != MPI_Recv(msg,nbytes,MPI_BYTE,sts.MPI_SOURCE,sts.MPI_TAG, MPI_COMM_WORLD,&sts))
             CmiAbort("PumpMsgs: MPI_Recv failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(30, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(30, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
         CpvAccess(Cmi_unposted_recv_total)++;
     }
 #else
@@ -629,8 +775,36 @@ int PumpMsgs(void)
     MPI_Get_count(&sts, MPI_BYTE, &nbytes);
     msg = (char *) CmiAlloc(nbytes);
 
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+    CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
     if (MPI_SUCCESS != MPI_Recv(msg,nbytes,MPI_BYTE,sts.MPI_SOURCE,sts.MPI_TAG, MPI_COMM_WORLD,&sts))
       CmiAbort("PumpMsgs: MPI_Recv failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(30, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(30, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
+
 #endif
 
 
@@ -693,10 +867,37 @@ static void PumpMsgsBlocking(void)
 #if MPI_POST_RECV_COUNT > 0
 #warning "Using MPI posted receives and PumpMsgsBlocking() will break"
 CmiAbort("Unsupported use of PumpMsgsBlocking. This call should be extended to check posted recvs, cancel them all, and then wait on any incoming message, and then re-post the recvs");
+#endif
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+ CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+ CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
 #endif
 
   if (MPI_SUCCESS != MPI_Recv(buf,maxbytes,MPI_BYTE,MPI_ANY_SOURCE,TAG, MPI_COMM_WORLD,&sts))
       CmiAbort("PumpMsgs: PMP_Recv failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(30, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(30, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
    MPI_Get_count(&sts, MPI_BYTE, &nbytes);
    msg = (char *) CmiAlloc(nbytes);
    memcpy(msg, buf, nbytes);
@@ -775,8 +976,37 @@ static void CommunicationServer(int sleepTime)
       PumpMsgs();
     }
     MACHSTATE(2, "CommunicationServer barrier begin {");
+
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+    CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
     if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD))
       CmiAbort("ConverseExit: MPI_Barrier failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(10, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(10, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
     MACHSTATE(2, "} CommunicationServer barrier end");
 #if (CMK_DEBUG_MODE || CMK_WEB_MODE || NODE_0_IS_CONVHOST)
     if (CmiMyNode() == 0){
@@ -975,18 +1205,99 @@ static int SendMsgBuf()
 
 #if MPI_POST_RECV_COUNT > 0
         if(size <= MPI_POST_RECV_SIZE){
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+    CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
             if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,node,POST_RECV_TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
                 CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
             }
         else {
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+    CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
             if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,node,TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
                 CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
         }
 #else
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+       CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+       CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
         if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,node,TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
             CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
 #endif
 
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
       MACHSTATE(3,"}MPI_send end");
       MsgQueueLen++;
       if(sent_msgs==0)
@@ -1060,16 +1371,99 @@ CmiCommHandle CmiAsyncSendFn(int destPE, int size, char *msg)
 
 #if MPI_POST_RECV_COUNT > 0
         if(size <= MPI_POST_RECV_SIZE){
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+    CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
               if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,destPE,POST_RECV_TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
                 CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
             }
         else {
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+         CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+         CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
              if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,destPE,TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
                 CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
         }
 #else
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+       CpvAccess(projTraceStart) = dclock() - starttimer;
+#else
+       CpvAccess(projTraceStart) = MPI_Wtime() - starttimer;
+#endif
+#endif
+#endif
+#endif
+
   if (MPI_SUCCESS != MPI_Isend((void *)msg,size,MPI_BYTE,destPE,TAG,MPI_COMM_WORLD,&(msg_tmp->req)))
     CmiAbort("CmiAsyncSendFn: MPI_Isend failed!\n");
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE 
+#if ! CMK_TRACE_IN_CHARM
+#if CMK_TIMER_USE_XT3_DCLOCK
+    traceUserBracketEvent(40, CpvAccess(projTraceStart), 
+                         (dclock() - starttimer));
+#else
+    traceUserBracketEvent(40, CpvAccess(projTraceStart),
+                         (MPI_Wtime() - starttimer));
+#endif
+#endif
+#endif
+#endif
+
 #endif
 
   MsgQueueLen++;
@@ -1373,6 +1767,7 @@ void ConverseExit(void)
   }
   if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD))
     CmiAbort("ConverseExit: MPI_Barrier failed!\n");
+
   ConverseCommonExit();
   MPI_Finalize();
 #if (CMK_DEBUG_MODE || CMK_WEB_MODE || NODE_0_IS_CONVHOST)
@@ -1385,6 +1780,7 @@ void ConverseExit(void)
 #endif
   exit(0);
 #else
+
   /* SMP version, communication thread will exit */
   ConverseCommonExit();
   /* atomic increment */
@@ -1395,6 +1791,21 @@ void ConverseExit(void)
 #endif
 }
 
+static void registerMPITraceEvents() {
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+    traceRegisterUserEvent("MPI_Barrier", 10);
+    traceRegisterUserEvent("MPI_Send", 20);
+    traceRegisterUserEvent("MPI_Recv", 30);
+    traceRegisterUserEvent("MPI_Isend", 40);
+    traceRegisterUserEvent("MPI_Irecv", 50);
+#endif
+#endif
+#endif
+}
+
+
 static char     **Cmi_argv;
 static char     **Cmi_argvcopy;
 static CmiStartFn Cmi_startfn;   /* The start function */
@@ -1528,6 +1939,18 @@ void ConverseInit(int argc, char **argv, CmiStartFn fn, int usched, int initret)
 #if FOR_CPLUS
   _main(argc,argv);
 #endif
+#endif
+
+#if CMI_MPI_TRACE_USEREVENTS
+#ifndef CMK_OPTIMIZE
+#if ! CMK_TRACE_IN_CHARM
+  CpvInitialize(double, projTraceStart);
+  // only PE 0 needs to care about registration (to generate sts file).
+  if (CmiMyPe() == 0) {
+    registerMachineUserEventsFunction(&registerMPITraceEvents);
+  }
+#endif
+#endif
 #endif
 
   MPI_Init(&argc, &argv);
@@ -1616,6 +2039,7 @@ void ConverseInit(int argc, char **argv, CmiStartFn fn, int usched, int initret)
 #if 0
   CthInit(argv);
   ConverseCommonInit(argv);
+
   CcdCallOnConditionKeep(CcdPROCESSOR_STILL_IDLE,CmiNotifyIdle,NULL);
   if (initret==0) {
     fn(CmiGetArgc(argv), argv);
index 41bf2117c596e4252e0e2c52b5daf3ca2612d186..59fd5c9cbaad5b2df2606bf58033714e4d85aab7 100644 (file)
@@ -38,8 +38,6 @@
 
 CpvCExtern(int, _traceCoreOn);   // projector
 
-#define DEBUGF(x)          // CmiPrintf x
-
 #ifdef CMK_OPTIMIZE
 static int warned = 0;
 #define OPTIMIZE_WARNING if (!warned) { warned=1;  CmiPrintf("\n\n!!!! Warning: tracing not available with CMK_OPTIMIZE!\n");  return;  }
@@ -47,6 +45,8 @@ static int warned = 0;
 #define OPTIMIZE_WARNING /*empty*/
 #endif
 
+#define DEBUGF(x)          // CmiPrintf x
+
 CkpvDeclare(TraceArray*, _traces);             // lists of all trace modules
 
 /* trace for bluegene */
@@ -60,6 +60,10 @@ CpvDeclare(int, traceOn);
 CkpvDeclare(int, traceOnPe);
 CkpvDeclare(char*, traceRoot);
 
+typedef void (*mTFP)();                   // function pointer for
+CpvDeclare(mTFP, machineTraceFuncPtr);    // machine user event
+                                          // registration
+
 int _threadMsg, _threadChare, _threadEP;
 int _packMsg, _packChare, _packEP;
 int _unpackMsg, _unpackChare, _unpackEP;
@@ -81,6 +85,7 @@ static void traceCommonInit(char **argv)
   CpvAccess(_traceCoreOn)=0; //projector
   CkpvInitialize(int, traceOnPe);
   CkpvAccess(traceOnPe) = 1;
+  CpvInitialize(mTFP, machineTraceFuncPtr);
   char *root;
   char *temproot;
   char *temproot2;
@@ -325,6 +330,20 @@ void traceUserBracketEvent(int e, double beginT, double endT)
 #endif
 }
 
+extern "C"
+void registerMachineUserEventsFunction(void (*eventRegistrationFunc)()) {
+  CpvAccess(machineTraceFuncPtr) = eventRegistrationFunc;
+}
+
+extern "C"
+void (*registerMachineUserEvents())() {
+  if (CpvAccess(machineTraceFuncPtr) != NULL) {
+    return CpvAccess(machineTraceFuncPtr);
+  } else {
+    return NULL;
+  }
+}
+
 extern "C"
 int traceRegisterUserEvent(const char*x, int e)
 {
index ba1d0bb6cf65e7ec435d62570b1c49c6ce8d56b4..e0c06e50f9a6c38ec48ca5e5730303b4e4a67461 100644 (file)
@@ -45,7 +45,6 @@ CkpvExtern(char*, traceRoot);
 CkpvExtern(double, traceInitTime);
 CkpvExtern(double, traceInitCpuTime);
 
-
 #if CMK_BLUEGENE_CHARM
 #define  TRACE_TIMER   BgGetTime
 #define  TRACE_CPUTIMER   BgGetTime
@@ -71,6 +70,8 @@ extern int _dummyMsg, _dummyChare, _dummyEP;
 /** Write out the common parts of the .sts file. */
 extern void traceWriteSTS(FILE *stsfp,int nUserEvents);
 
+extern "C" void (*registerMachineUserEvents())();
+
 #endif
 
 /*@}*/
index a083bd0c43bd82a897b942821b7b0c91a7f9d7f2..80903305fb17949b48131eae7f6f9ad5e1505845 100644 (file)
@@ -1132,6 +1132,16 @@ void TraceProjections::dequeue(envelope *) {}
 void TraceProjections::beginComputation(void)
 {
   computationStarted = 1;
+
+  // Executes the callback function provided by the machine
+  // layer. This is the proper method to register user events in a
+  // machine layer because projections is a charm++ module.
+  if (CkpvAccess(traceOnPe) != 0) {
+    void (*ptr)() = registerMachineUserEvents();
+    if (ptr != NULL) {
+      ptr();
+    }
+  }
 //  CkpvAccess(traceInitTime) = TRACE_TIMER();
 //  CkpvAccess(traceInitCpuTime) = TRACE_CPUTIMER();
   _logPool->add(BEGIN_COMPUTATION, 0, 0, TraceTimer(), -1, -1);
@@ -1616,9 +1626,13 @@ void TraceProjectionsBOC::closeTrace()
 // 
 extern "C" void CombineProjections()
 {
+#ifndef CMK_OPTIMIZE
   // CkPrintf("[%d] CombineProjections called!\n", CkMyPe());
   CProxy_TraceProjectionsBOC bocProxy(traceProjectionsGID);
   bocProxy.shutdownAnalysis();
+#else
+  CkExit();
+#endif
 }
 
 // This method is called by module initialization to register the exit
index 7ac132fa6a877bd6e62b06b0ce89c7301d232ff6..2f71658ae557ddbdefe792bab3b23dff9b6908d1 100644 (file)
@@ -741,6 +741,7 @@ void TraceSummaryBOC::write(void)
 
 extern "C" void CombineSummary()
 {
+#ifndef CMK_OPTIMIZE
   CmiPrintf("[%d] CombineSummary called!\n", CkMyPe());
   if (sumonly) {
     CmiPrintf("[%d] Sum Only start!\n", CkMyPe());
@@ -749,6 +750,9 @@ extern "C" void CombineSummary()
     sumProxy[0].startSumOnly();
   }
   else CkExit();
+#else
+  CkExit();
+#endif
 }
 
 void initTraceSummaryBOC()
index 6e5f93a2a2ef7a95bec315bbc83575e01eca8634..a232fc8fc6ece7ba69bc7670b2945a2c0cb10b53 100644 (file)
@@ -57,7 +57,9 @@ class Trace {
     virtual void traceBegin() {}
     virtual void traceEnd() {}
     // registers user event trace module returns int identifier 
-    virtual int traceRegisterUserEvent(const char* eventName, int e) { return 0; }
+    virtual int traceRegisterUserEvent(const char* eventName, int e) { 
+      return 0; 
+    }
     // a user event has just occured
     virtual void userEvent(int eventID) {}
     // a pair of begin/end user event has just occured
@@ -189,7 +191,9 @@ public:
     inline int traceRegisterUserEvent(const char*x, int evt) {
          int eno = 0;
          for (int i=0; i<length(); i++) {
-           if (traces[i]->traceOnPE() == 0) continue;
+           if (traces[i]->traceOnPE() == 0) {
+             continue;
+           }
            int e = traces[i]->traceRegisterUserEvent(x, evt);
            if (e) eno = e;
           }
index a11bb0fdd059142073df0c1807ab173033aeac1a..a5d8ff265b9aaf45ec5fb2d6fd1b2a71925510b8 100644 (file)
@@ -31,6 +31,9 @@ int  traceRegisterUserEvent(const char*, int e
 #endif
 );
 
+/* Support for machine layers to register their user events to projections */
+void registerMachineUserEventsFunction(void (*eventRegistrationFunc)());
+
 int traceRegisterFunction(const char*, int idx
 #ifdef __cplusplus
 =-999