new implementation of AllToAll routines. now an option is present to enable
authorFilippo Gioachin <gioachin@illinois.edu>
Wed, 20 Apr 2005 18:29:21 +0000 (18:29 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Wed, 20 Apr 2005 18:29:21 +0000 (18:29 +0000)
the zero-copy functions: CMK_COMLIB_USE_VECTORIZE

src/conv-com/3dgridrouter.C
src/conv-com/de.C
src/conv-com/graphrouter.C
src/conv-com/gridrouter.C
src/conv-com/petable.C
src/conv-com/petable.h
src/conv-com/treerouter.C
src/conv-com/treerouter.h

index 57e87271df08d4a3ac7b18aeccfea693fee47376..e25cbe361e8c574582d74b89e147ae2af103f165 100644 (file)
 
 /**The only communication op used. Modify this to use
  ** vector send */
+#if CMK_COMMLIB_USE_VECTORIZE
 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
        {int len;\
-       char *newmsg;\
+       PTvectorlist newmsg;\
+        newmsg=PeGrid->ExtractAndVectorize(kid, u1, knpe, kpelist);\
+       if (newmsg) {\
+         CmiSetHandler(newmsg->msgs[0], khndl);\
+          CmiSyncVectorSendAndFreeSystem(knextpe, newmsg->count, newmsg->sizes, newmsg->msgs, 1);\
+        }\
+       else {\
+         SendDummyMsg(kid, knextpe, u2);\
+       }\
+}
+#else
+#define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
+       {int len;\
+       char * newmsg;\
         newmsg=PeGrid->ExtractAndPack(kid, u1, knpe, kpelist, &len);\
        if (newmsg) {\
          CmiSetHandler(newmsg, khndl);\
@@ -25,6 +39,7 @@
          SendDummyMsg(kid, knextpe, u2);\
        }\
 }
+#endif
 
 #define ROWLEN COLLEN
 
index 2cb3e8a706b1783bac3c5586b1cd2c296a13c093..905f97e9da9bd28049a7a5b76ccb7ec7f52aceba 100644 (file)
 /**The only communication op used. Modify this to use
  ** vector send */
 
+#if CMK_COMMLIB_USE_VECTORIZE
+#define HCUBESENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe, pehcube)  \
+       {int len;\
+       PTvectorlist newmsg;\
+       newmsg=pehcube->ExtractAndVectorize(kid, u1, knpe, kpelist);\
+       if (newmsg) {\
+         CmiSetHandler(newmsg->msgs[0], khndl);\
+         CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
+       }\
+       else {\
+         SendDummyMsg(kid, knextpe, u2);\
+       }\
+}
+#else
 #define HCUBESENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe, pehcube)  \
        {int len;\
        char *newmsg;\
@@ -39,6 +53,7 @@
          SendDummyMsg(kid, knextpe, u2);\
        }\
 }
+#endif
 
 inline int maxdim(int n)
 {
@@ -272,6 +287,22 @@ void DimexRouter::RecvManyMsg(comID id, char *msg)
             //Sending through prefix send to save on copying overhead   
             //of the hypercube algorithm            
             
+#if CMK_COMMLIB_USE_VECTORIZE
+            PTvectorlist newmsg;
+            newmsg=PeHcube->ExtractAndVectorizeAll(id, stage);
+            if (newmsg) {
+                CmiSetHandler(newmsg->msgs[0], CkpvAccess(ProcHandle));
+               for (int count=0; count<two_pow_ndirect; ++count) {
+                 int nextpe = count ^ MyPe;
+                 gmap(nextpe);
+                 ComlibPrintf("%d Sending to %d\n", MyPe, nextpe);
+                 CmiSyncVectorSend(nextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);
+               }
+               for(int i=0;i<newmsg->count;i++) CmiFree(newmsg->msgs[i]);
+               CmiFree(newmsg->sizes);
+               CmiFree(newmsg->msgs);
+            }
+#else
             int *pelist = (int *)CmiAlloc(two_pow_ndirect * sizeof(int));
             for(int count = 0; count < two_pow_ndirect; count ++){
                 int nextpe = count ^ MyPe;
@@ -288,7 +319,9 @@ void DimexRouter::RecvManyMsg(comID id, char *msg)
                 CmiSetHandler(newmsg, CkpvAccess(ProcHandle));
                 CmiSyncListSendAndFree(two_pow_ndirect, pelist, len, newmsg);
             }
-            
+           CmiFree(pelist);
+#endif
+
             stage -= numDirectSteps;
 
             //if(procMsgCount == two_pow_ndirect)
index c0977eb1ba069d520b6a787b005a29c4b0f9aa7b..02ede99f3e32411dbc31c03acb59ccc016bb7037 100644 (file)
@@ -74,10 +74,15 @@ void GraphRouter::sendMessages(comID id, int cur_stage){
         ComlibPrintf("%d:sending to %d for %d pes in stage %d\n", MyPe, nextpe, npestosend, cur_stage);
 
         int len;
+#if CMK_COMMLIB_USE_VECTORIZE
+       PTvectorlist newmsg;
+        newmsg=PeGraph->ExtractAndVectorize(id, cur_stage + 1, npestosend, 
+                                       pesToSend);
+#else
        char *newmsg;
         newmsg=PeGraph->ExtractAndPack(id, cur_stage + 1, npestosend, 
                                        pesToSend, &len);
-        
+#endif
 #if CMK_PERSISTENT_COMM
         if(len < PERSISTENT_BUFSIZE)
             if(currentIteration % 2)
@@ -91,8 +96,11 @@ void GraphRouter::sendMessages(comID id, int cur_stage){
                 CmiSetHandler(newmsg, CkpvAccess(RecvHandle));
             else
                 CmiSetHandler(newmsg, CkpvAccess(ProcHandle));
-
+#if CMK_COMMLIB_USE_VECTORIZE
+            CmiSyncVectorSendAndFree(nextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);
+#else
             CmiSyncSendAndFree(nextpe, len, newmsg);
+#endif
         }
        else {
             SendDummyMsg(id, nextpe, cur_stage + 1);
index 96939887d8abe1f68943fa5e6ce78d9fd74ec0e9..4ab38b0a703f0e29ea6917a7b074640f1f1b89b3 100644 (file)
 
 /**The only communication op used. Modify this to use
  ** vector send */
+#if CMK_COMMLIB_USE_VECTORIZE
+#define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
+       {int len;\
+       PTvectorlist newmsg;\
+        ComlibPrintf("Entering Gridsendfn\n");\
+        newmsg=PeMesh->ExtractAndVectorize(kid, u1, knpe, kpelist);\
+       if (newmsg) {\
+         CmiSetHandler(newmsg->msgs[0], khndl);\
+          ComlibPrintf("Sending in Gridsendfn to %d\n",knextpe);\
+          CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
+        }\
+       else {\
+         SendDummyMsg(kid, knextpe, u2);\
+       }\
+}
+#else
 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
        {int len;\
        char *newmsg;\
@@ -31,6 +47,7 @@
          SendDummyMsg(kid, knextpe, u2);\
        }\
 }
+#endif
 
 /****************************************************
  * Preallocated memory=P ints + MAXNUMMSGS msgstructs
index 632b6fc93ca58a3810f10f6022cb43518fcb85ed..cd5295e7d230ebc62304396d99425e257f841e10 100644 (file)
 #define BIGBUFFERSIZE 65536
 #define PTPREALLOC    100
 
-struct AllToAllHdr{
-    char dummy[CmiReservedHeaderSize];
-    int refno;
-    comID id;
-    int ufield;
-    int nmsgs;
+struct AllToAllHdr {
+  char dummy[CmiReservedHeaderSize];
+  int refno;
+  comID id;
+  int ufield;
+  int nmsgs;
 };
 
 
 /**************************************************************
  * Preallocated memory=P*MSGQLEN ptr + 2P ints + 1000 ptrs
  **************************************************************/
-PeTable :: PeTable(int n)
-{
+PeTable :: PeTable(int n) {
   NumPes=n;
   magic=0;
   PeList = (PTinfo ***)CmiAlloc(sizeof(PTinfo *)*NumPes);
@@ -43,10 +42,10 @@ PeTable :: PeTable(int n)
   msgnum=new int[NumPes];
   MaxSize=new int[NumPes];
   for (int i=0;i<NumPes;i++) {
-       msgnum[i]=0;
-       MaxSize[i]=MSGQLEN;
-       PeList[i]=(PTinfo **)CmiAlloc(sizeof(PTinfo *)*MSGQLEN);
-       for (int j=0;j<MSGQLEN;j++) PeList[i][j]=0;
+    msgnum[i]=0;
+    MaxSize[i]=MSGQLEN;
+    PeList[i]=(PTinfo **)CmiAlloc(sizeof(PTinfo *)*MSGQLEN);
+    for (int j=0;j<MSGQLEN;j++) PeList[i][j]=0;
   }
 
   //ptrlist=(PTinfo **)CmiAlloc(1000*sizeof(PTinfo *));
@@ -57,8 +56,7 @@ PeTable :: PeTable(int n)
   PTFreeChunks=NULL;
 }
 
-PeTable :: ~PeTable()
-{
+PeTable :: ~PeTable() {
   int i;
   for (i=0;i<NumPes;i++) CmiFree(PeList[i]);
   CmiFree(PeList);
@@ -68,46 +66,44 @@ PeTable :: ~PeTable()
   //CmiFree(ptrlist);
   PTinfo *tmp;
   while (PTFreeChunks) {
-       tmp=PTFreeChunks;
-       PTFreeChunks=PTNEXTCHUNK(tmp);
-       CmiFree(tmp);
+    tmp=PTFreeChunks;
+    PTFreeChunks=PTNEXTCHUNK(tmp);
+    CmiFree(tmp);
   }
- // delete FreeList;
 // delete FreeList;
 
 }
 
-void PeTable:: Purge()
-{
+void PeTable:: Purge() {
   for (int i=0; i<NumPes;i++) {
-       if (msgnum[i]) {
-            // ComlibPrintf("%d Warning: %d Undelivered Messages for %d\n", CkMyPe(), msgnum[i], i);
-         //msgnum[i]=0;
-       }
+    if (msgnum[i]) {
+      // ComlibPrintf("%d Warning: %d Undelivered Messages for %d\n", CkMyPe(), msgnum[i], i);
+      //msgnum[i]=0;
+    }
   }
   GarbageCollect();
   //  ComlibPrintf("combcount = %d\n", combcount);
   //combcount = 0;
 }
 
-void PeTable :: ExtractAndDeliverLocalMsgs(int index)
-{
+void PeTable :: ExtractAndDeliverLocalMsgs(int index) {
   int j;
   msgstruct m;
 
   ComlibPrintf("%d:Delivering %d local messages\n", CkMyPe(), msgnum[index]);
   for (j=msgnum[index]-1;(j>=0);j--) {
 
-       m.msgsize=PeList[index][j]->msgsize;
-       m.msg=PeList[index][j]->msg;
+    m.msgsize=PeList[index][j]->msgsize;
+    m.msg=PeList[index][j]->msg;
 
-       if (--(PeList[index][j]->refCount) <=0) {
-            CmiSyncSendAndFree(CkMyPe()/*index*/, m.msgsize, (char*)m.msg);
-            PTFREE(PeList[index][j]);
-       }
-       else {
-            CmiSyncSend(CkMyPe()/*index*/, m.msgsize, (char*)m.msg);
-        }
-       PeList[index][j]=NULL;
+    if (--(PeList[index][j]->refCount) <=0) {
+      CmiSyncSendAndFree(CkMyPe()/*index*/, m.msgsize, (char*)m.msg);
+      PTFREE(PeList[index][j]);
+    }
+    else {
+      CmiSyncSend(CkMyPe()/*index*/, m.msgsize, (char*)m.msg);
+    }
+    PeList[index][j]=NULL;
   }
   msgnum[index]=j+1;
 
@@ -121,225 +117,229 @@ void PeTable :: ExtractAndDeliverLocalMsgs(int index)
 #define PACK(type,data) {junk=(char *)&(data); memcpy(t, junk, sizeof(type)); t+=sizeof(type);}
 #define PACKMSG(data, size) { memcpy(p+msg_offset, (data), size); msg_offset += size; }
 
+/*
+  Protocol:
+  |     AllToAllHdr      |npe|ChunkHdr1|msg1|ChunkHdr2|msg2|...
+  |ref|comid|ufield|nmsgs|
+*/
+char * PeTable ::ExtractAndPack(comID id, int ufield, int npe, 
+                                int *pelist, int *length) {
+  char *junk;
+  int nummsgs, offset, num_distinctmsgs;
+        
+  int tot_msgsize=TotalMsgSize(npe, pelist, &nummsgs, &num_distinctmsgs);
+
+  ComlibPrintf("%d In ExtractAndPack %d, %d\n", CmiMyPe(), npe, nummsgs); 
+
+  if (tot_msgsize ==0) {
+    *length=0;
+        
+    ComlibPrintf("Returning NULL\n");
+    return(NULL);
+  }
+    
+  int msg_offset = sizeof(struct AllToAllHdr) + (npe + nummsgs + 1) * sizeof(int);
+  //int msg_offset = CmiReservedHeaderSize + sizeof(comID) 
+  //    + (npe + 4 + nummsgs) * sizeof(int);  
+
+  msg_offset = ALIGN8(msg_offset);
+    
+  *length = tot_msgsize;
+  *length += msg_offset;
+  char *p;
+  p=(char *)CmiAlloc(*length);
+
+  char *t = p + CmiReservedHeaderSize;
+  int i, j;
+  if (!p) CmiAbort("Big time problem\n");
+  magic++;
+
+  int refno = id.refno;    
+
+  PACK(int, refno);
+  PACK(comID, id);
+  PACK(int, ufield);
+  PACK(int, nummsgs);
+  PACK(int, npe);
+    
+  int lesspe=0;
+  int npacked = 0;
+  for (i=0;i<npe;i++) {
+    int index=pelist[i];
+
+    if (msgnum[index]<=0) {
+      lesspe++;
+            
+      ComlibPrintf("[%d] msgnum[index]<=0 !!!!!\n", CkMyPe());
+      continue;
+    }
+        
+    ComlibPrintf("%d Packing pelist[%d]\n", CkMyPe(), index);
+    register int newval=-1*pelist[i];
+    PACK(int, newval); 
+
+    for (j=0;j<msgnum[index];j++) {
+      if (PeList[index][j]->magic == magic) {
+       offset=(PeList[index][j]->offset);
+      }
+      else {
+       npacked ++;
+                
+       //offset=msg_offset;
+       offset=npacked;
+       PeList[index][j]->magic=magic;
+       PeList[index][j]->offset=offset;
+       PTinfo *tempmsg=PeList[index][j];
+               
+       CmiChunkHeader hdr;
+       hdr.size = tempmsg->msgsize;
+       hdr.ref = -1;
+       PACKMSG(&hdr, sizeof(CmiChunkHeader));
+       PACKMSG(tempmsg->msg, tempmsg->msgsize);
+
+       msg_offset = ALIGN8(msg_offset);
+      }
+            
+      //ComlibPrintf("%d Packing msg_offset=%d\n", CkMyPe(), offset);
+      PACK(int, offset); 
+
+      if (--(PeList[index][j]->refCount) <=0) {
+       CmiFree(PeList[index][j]->msg);
+                
+       PTFREE(PeList[index][j]);
+      }
+      PeList[index][j]=NULL;
+    }
+    msgnum[index]=0;
+  }
+  //offset=-1;
+  //PACK(int, offset);
+
+  /*    
+       if (lesspe) {
+        t=p+CmiReservedHeaderSize+2*sizeof(int) + sizeof(comID);
+       npe=npe-lesspe;
+       PACK(int, npe);
+       }
+  */
+
+  return(p);
+} 
+
 /*Used for all to all multicast operations.  Assumes that each message
   is destined to all the processors, to speed up all to all
   substantially --Sameer 09/03/03 
   
   Protocol:
-  |ref|comid|ufield|nmsgs|size|ref|msg1|size2|ref2|msg2|....
+  |     AllToAllHdr      |ChunkHdr1|msg1|ChunkHdr2|msg2|...
+  |ref|comid|ufield|nmsgs|
 */
 
-char * PeTable ::ExtractAndPackAll(comID id, int ufield, int *length)
-{
-    int nmsgs = 0, i, j;
-    int index = 0;
+char * PeTable ::ExtractAndPackAll(comID id, int ufield, int *length) {
+  int nmsgs = 0;
+  int i, j;
+  int index = 0;
 
-    ComlibPrintf("[%d] In Extract And Pack All\n", CkMyPe());
+  ComlibPrintf("[%d] In Extract And Pack All\n", CkMyPe());
 
-    //Increment magic to detect duplicate messages
-    magic++;
+  //Increment magic to detect duplicate messages
+  magic++;
 
-    register int total_msg_size = 0;
+  register int total_msg_size = 0;
 
-    //first compute size
-    for (i=0;i<NumPes;i++) {
-        index = i;
-        for (j=msgnum[index]-1; (j>=0); j--) {
-            if (PeList[index][j]->magic != magic) {                
-                total_msg_size += ALIGN8(PeList[index][j]->msgsize);
-                total_msg_size += 2 * sizeof(int);
-                PeList[index][j]->magic=magic;
+  //first compute size
+  for (i=0;i<NumPes;i++) {
+    index = i;
+    for (j=msgnum[index]-1; (j>=0); j--) {
+      if (PeList[index][j]->magic != magic) {                
+       total_msg_size += ALIGN8(PeList[index][j]->msgsize);
+       total_msg_size += 2 * sizeof(int);
+       PeList[index][j]->magic=magic;
 
-                nmsgs ++;
-            }            
-        }
+       nmsgs ++;
+      }            
     }
+  }
     
-    total_msg_size += ALIGN8(sizeof(AllToAllHdr));
+  total_msg_size += ALIGN8(sizeof(AllToAllHdr));
 
-    ComlibPrintf("[%d] Message Size %d, nmsgs %d **%d**\n", CkMyPe(), total_msg_size, nmsgs, sizeof(AllToAllHdr));
+  ComlibPrintf("[%d] Message Size %d, nmsgs %d **%d**\n", CkMyPe(), total_msg_size, nmsgs, sizeof(AllToAllHdr));
     
-    //poiter to the combined message, UGLY NAME
-    char *p = (char *) CmiAlloc(total_msg_size * sizeof(char));    
+  //poiter to the combined message, UGLY NAME
+  char *p = (char *) CmiAlloc(total_msg_size * sizeof(char));    
 
-    ComlibPrintf("After cmialloc\n");
+  ComlibPrintf("After cmialloc\n");
 
-    //buffer to copy stuff into
-    char *t = p; 
-    char *junk = NULL;
+  //buffer to copy stuff into
+  char *t = p; 
+  char *junk = NULL;
     
-    int dummy = 0;
+  int dummy = 0;
     
-    int refno = 0;
+  int refno = 0;
 
-    AllToAllHdr ahdr;
-    ahdr.refno = refno;
-    ahdr.id = id;
-    ahdr.ufield = ufield;
-    ahdr.nmsgs = nmsgs;
+  AllToAllHdr ahdr;
+  ahdr.refno = refno;
+  ahdr.id = id;
+  ahdr.ufield = ufield;
+  ahdr.nmsgs = nmsgs;
 
-    /*
-      PACKINT(refno);    
-      PACK(comID, id);
+  /*
+    PACKINT(refno);    
+    PACK(comID, id);
       
-      PACKINT(ufield);
-      PACKINT(nmsgs);
-      //    PACKINT(dummy); //Aligning to 8 bytes
+    PACKINT(ufield);
+    PACKINT(nmsgs);
+    //    PACKINT(dummy); //Aligning to 8 bytes
     */
 
-    PACK(AllToAllHdr, ahdr);   
+  PACK(AllToAllHdr, ahdr);   
 
-    int msg_offset = ALIGN8(sizeof(AllToAllHdr));
-    
-    //Increment magic again for creating the message
-    magic++;
-    for (i=0;i<NumPes;i++) {
-        index=i;
-        int ref = 0;
-        int size;
-
-        for (j=msgnum[index]-1; (j>=0); j--) {
-            //Check if it is a duplicate
-            if (PeList[index][j]->magic != magic) {                
-                size = PeList[index][j]->msgsize;
-                PACKMSG(&size, sizeof(int));
-                PACKMSG(&ref, sizeof(int));
-                PeList[index][j]->magic=magic;
-                PACKMSG(PeList[index][j]->msg, size);
-
-                msg_offset = ALIGN8(msg_offset);
-            }
-
-            //Free it when all the processors have gotten rid of it
-            if (--(PeList[index][j]->refCount) <=0) {
-                ComlibPrintf("before cmifree \n");
-                CmiFree(PeList[index][j]->msg);   
-                ComlibPrintf("after cmifree \n");
-
-                PTFREE(PeList[index][j]);
-            }
-            //Assign the current processors message pointer to NULL
-            PeList[index][j] = NULL;
-        }
-        msgnum[index] = 0;
-    }
+  int msg_offset = ALIGN8(sizeof(AllToAllHdr));
     
-    *length = total_msg_size;
-    return p;
-}
-
-char * PeTable ::ExtractAndPack(comID id, int ufield, int npe, 
-                                int *pelist, int *length)
-{
-    char *junk;
-    int nummsgs, offset, num_distinctmsgs;
-        
-    int tot_msgsize=TotalMsgSize(npe, pelist, &nummsgs, &num_distinctmsgs);
+  //Increment magic again for creating the message
+  magic++;
+  for (i=0;i<NumPes;i++) {
+    index=i;
+    int ref = 0;
+    int size;
+
+    for (j=msgnum[index]-1; (j>=0); j--) {
+      //Check if it is a duplicate
+      if (PeList[index][j]->magic != magic) {                
+       size = PeList[index][j]->msgsize;
+       PACKMSG(&size, sizeof(int));
+       PACKMSG(&ref, sizeof(int));
+       PeList[index][j]->magic=magic;
+       PACKMSG(PeList[index][j]->msg, size);
+
+       msg_offset = ALIGN8(msg_offset);
+      }
 
-    ComlibPrintf("%d In ExtractAndPack %d, %d\n", CmiMyPe(), npe, nummsgs); 
+      //Free it when all the processors have gotten rid of it
+      if (--(PeList[index][j]->refCount) <=0) {
+       ComlibPrintf("before cmifree \n");
+       CmiFree(PeList[index][j]->msg);   
+       ComlibPrintf("after cmifree \n");
 
-    if (tot_msgsize ==0) {
-       *length=0;
-        
-        ComlibPrintf("Returning NULL\n");
-       return(NULL);
+       PTFREE(PeList[index][j]);
+      }
+      //Assign the current processors message pointer to NULL
+      PeList[index][j] = NULL;
     }
+    msgnum[index] = 0;
+  }
     
-    int msg_offset = sizeof(struct AllToAllHdr) + (npe + nummsgs + 1) * sizeof(int);
-    //int msg_offset = CmiReservedHeaderSize + sizeof(comID) 
-    //    + (npe + 4 + nummsgs) * sizeof(int);  
-
-    msg_offset = ALIGN8(msg_offset);
-    
-    *length = tot_msgsize;
-    *length += msg_offset;
-    char *p;
-    p=(char *)CmiAlloc(*length);
-
-    char *t = p + CmiReservedHeaderSize;
-    int i, j;
-    if (!p) CmiAbort("Big time problem\n");
-    magic++;
-
-    int refno = id.refno;    
-
-    PACK(int, refno);
-    PACK(comID, id);
-    PACK(int, ufield);
-    PACK(int, nummsgs);
-    PACK(int, npe);
-    
-    int lesspe=0;
-    int npacked = 0;
-    for (i=0;i<npe;i++) {
-        int index=pelist[i];
-
-        if (msgnum[index]<=0) {
-            lesspe++;
-            
-            ComlibPrintf("[%d] msgnum[index]<=0 !!!!!\n", CkMyPe());
-            continue;
-        }
-        
-        ComlibPrintf("%d Packing pelist[%d]\n", CkMyPe(), index);
-        register int newval=-1*pelist[i];
-        PACK(int, newval); 
-
-        for (j=0;j<msgnum[index];j++) {
-            if (PeList[index][j]->magic == magic) {
-                offset=(PeList[index][j]->offset);
-            }
-            else {
-               npacked ++;
-                
-               //offset=msg_offset;
-               offset=npacked;
-               PeList[index][j]->magic=magic;
-               PeList[index][j]->offset=offset;
-               PTinfo *tempmsg=PeList[index][j];
-               
-                CmiChunkHeader hdr;
-                hdr.size = tempmsg->msgsize;
-                hdr.ref = -1;
-                PACKMSG(&hdr, sizeof(CmiChunkHeader));
-               PACKMSG(tempmsg->msg, tempmsg->msgsize);
-
-                msg_offset = ALIGN8(msg_offset);
-            }
-            
-            //ComlibPrintf("%d Packing msg_offset=%d\n", CkMyPe(), offset);
-            PACK(int, offset); 
-
-            if (--(PeList[index][j]->refCount) <=0) {
-                CmiFree(PeList[index][j]->msg);
-                
-                PTFREE(PeList[index][j]);
-            }
-            PeList[index][j]=NULL;
-        }
-        msgnum[index]=0;
-    }
-    //offset=-1;
-    //PACK(int, offset);
-
-    /*    
-    if (lesspe) {
-        t=p+CmiReservedHeaderSize+2*sizeof(int) + sizeof(comID);
-       npe=npe-lesspe;
-       PACK(int, npe);
-    }
-    */
-
-    return(p);
-} 
+  *length = total_msg_size;
+  return p;
+}
 
 #undef UNPACK
 #define UNPACK(type,data) {junk=(char *)&(data); memcpy(junk, t, sizeof(type));t+=sizeof(type);}
 #undef UNPACKMSG
 #define UNPACKMSG(dest,src, size) { memcpy(dest, src, size); offset += size;}
 
-int PeTable :: UnpackAndInsert(void *in)
-{
+int PeTable :: UnpackAndInsert(void *in) {
   char *junk;
   char *t =(char *)in + CmiReservedHeaderSize;
   int i, ufield, npe, pe, nummsgs, ptrlistindex=0;
@@ -350,7 +350,7 @@ int PeTable :: UnpackAndInsert(void *in)
   register int offset;
 
   UNPACK(int, refno);
-  //ComlibPrintf("%d UnPacking id\n", CkMyPe());
+  ComlibPrintf("%d UnPackAndInsert\n", CkMyPe());
   UNPACK(comID, id);
   UNPACK(int, ufield);
   UNPACK(int, nummsgs);
@@ -399,23 +399,23 @@ int PeTable :: UnpackAndInsert(void *in)
     msgnum[pe]++;
 
     /*
-    while (offset > 0) {
+      while (offset > 0) {
       int tempmsgsize;
       UNPACKMSG(&(tempmsgsize), (char *)in+offset, sizeof(int));
       int ptr;
       UNPACKMSG(&ptr, (char *)in+offset, sizeof(int));
 
       if (ptr >=0 )  {
-       if (msgnum[pe] >= MaxSize[pe]) {
-         REALLOC(PeList[pe], MaxSize[pe]);
-         MaxSize[pe] *= 2;
-       }
-       PeList[pe][msgnum[pe]]=ptrvec[ptr];
-       (ptrvec[ptr])->refCount++;
-       msgnum[pe]++;
+      if (msgnum[pe] >= MaxSize[pe]) {
+      REALLOC(PeList[pe], MaxSize[pe]);
+      MaxSize[pe] *= 2;
+      }
+      PeList[pe][msgnum[pe]]=ptrvec[ptr];
+      (ptrvec[ptr])->refCount++;
+      msgnum[pe]++;
 
-       UNPACK(int, offset);
-       continue;
+      UNPACK(int, offset);
+      continue;
       }
             
       PTinfo *temp;
@@ -432,17 +432,17 @@ int PeTable :: UnpackAndInsert(void *in)
       temp->msg=(void *)((char *)in+offset);
       if (msgnum[pe] >= MaxSize[pe]) {
 
-       REALLOC(PeList[pe], MaxSize[pe]);
-       MaxSize[pe] *= 2;
+      REALLOC(PeList[pe], MaxSize[pe]);
+      MaxSize[pe] *= 2;
       }
       PeList[pe][msgnum[pe]]=temp;
       msgnum[pe]++;
       UNPACK(int, offset);
       //}
-    //t -=sizeof(int);
-  }
-  *(int *)((char *)in -sizeof(int))=ptrlistindex; 
-  */
+      //t -=sizeof(int);
+      }
+      *(int *)((char *)in -sizeof(int))=ptrlistindex; 
+      */
   }
 
   REFFIELD(in) = ptrlistindex;
@@ -452,12 +452,12 @@ int PeTable :: UnpackAndInsert(void *in)
   }
 
   /*  
-  for (i=0;i<ptrlistindex;i++) {
-    char * actualmsg=(char *)(ptrvec[i]->msg);
-    int *rc=(int *)(actualmsg-sizeof(int));
-    *rc=(int)((char *)in-actualmsg);
-    //ComlibPrintf("I am inserting %d\n", *rc);
-  }
+      for (i=0;i<ptrlistindex;i++) {
+      char * actualmsg=(char *)(ptrvec[i]->msg);
+      int *rc=(int *)(actualmsg-sizeof(int));
+      *rc=(int)((char *)in-actualmsg);
+      //ComlibPrintf("I am inserting %d\n", *rc);
+      }
   */
 
   ptrvec.removeAll();
@@ -470,14 +470,14 @@ int PeTable :: UnpackAndInsert(void *in)
    Same protocol as mentioned earlier.
 */
 
-int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist){
+int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist) {
   char *junk;
   char *t =(char *)in /*+CmiReservedHeaderSize*/;
   int i,  
-      ufield,   // user field or ths stage of the iteration 
-      nmsgs,    // number of messages in combo message
-      refno,    // reference number
-      dummy;    // alignment dummy
+    ufield,   // user field or ths stage of the iteration 
+    nmsgs,    // number of messages in combo message
+    refno,    // reference number
+    dummy;    // alignment dummy
   
   comID id;
 
@@ -497,7 +497,7 @@ int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist){
   UNPACK(AllToAllHdr, ahdr);
 
   if(sizeof(AllToAllHdr) & 7 != 0)
-      t += 8 - sizeof(AllToAllHdr) & 7;
+    t += 8 - sizeof(AllToAllHdr) & 7;
 
   refno = ahdr.refno;
   id = ahdr.id;
@@ -527,17 +527,17 @@ int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist){
     chdr->ref++;
 
     /*
-    UNPACK(int, size);
-    ref = (int *)t;
-    t += sizeof(int);
+      UNPACK(int, size);
+      ref = (int *)t;
+      t += sizeof(int);
     
-    *ref = (int)((char *)(&chdr->ref) - (char *)ref);
-    chdr->ref ++;
+      *ref = (int)((char *)(&chdr->ref) - (char *)ref);
+      chdr->ref ++;
 
-    ComlibPrintf("ref = %d, global_ref = %d\n", *ref, chdr->ref);
+      ComlibPrintf("ref = %d, global_ref = %d\n", *ref, chdr->ref);
     
-    msg = t;
-    t += ALIGN8(size);
+      msg = t;
+      t += ALIGN8(size);
     */
     InsertMsgs(npes, pelist, size, msg);
   }  
@@ -546,15 +546,274 @@ int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist){
   return ufield;
 }
 
+/*
+ * Added by Filippo, 2005/04/18 to allow a zero-copy sending, through the
+ * CmiVectorSend functions.
+ */
 PTvectorlist PeTable :: ExtractAndVectorize(comID id, int ufield, int npe, int *pelist) {
-  return NULL;
+  char *junk;
+  int nummsgs = 0;
+  int offset, num_distinctmsgs;
+  int i, j;
+
+  for (i=0; i<npe; ++i) nummsgs += msgnum[pelist[i]];
+
+  ComlibPrintf("%d In ExtractAndVectorize %d, %d\n", CmiMyPe(), npe, nummsgs); 
+
+  if (nummsgs ==0) {
+    ComlibPrintf("Returning NULL\n");
+    return(NULL);
+  }
+    
+  int headersize = sizeof(struct AllToAllHdr) + (npe + nummsgs + 1) * sizeof(int);
+  //int msg_offset = CmiReservedHeaderSize + sizeof(comID) 
+  //    + (npe + 4 + nummsgs) * sizeof(int);  
+
+  char *p;
+  p=(char *)CmiAlloc(headersize);
+
+  char *t = p + CmiReservedHeaderSize;
+  if (!p) CmiAbort("Big time problem\n");
+  magic++;
+
+  int refno = id.refno;    
+
+  PACK(int, refno);
+  PACK(comID, id);
+  PACK(int, ufield);
+  PACK(int, nummsgs);
+  PACK(int, npe);
+    
+  int lesspe=0;
+  int npacked = 0;
+  for (i=0;i<npe;i++) {
+    int index=pelist[i];
+
+    if (msgnum[index]<=0) {
+      lesspe++;
+            
+      ComlibPrintf("[%d] msgnum[index]<=0 !!!!!\n", CkMyPe());
+      continue;
+    }
+        
+    ComlibPrintf("%d Packing pelist[%d]\n", CkMyPe(), index);
+    register int newval=-1*pelist[i];
+    PACK(int, newval); 
+
+    for (j=0;j<msgnum[index];j++) {
+      if (PeList[index][j]->magic == magic) {
+       offset=(PeList[index][j]->offset);
+      }
+      else {
+       npacked ++;
+                
+       //offset=msg_offset;
+       offset=npacked;
+       PeList[index][j]->magic=magic;
+       PeList[index][j]->offset=offset;
+       PTinfo *tempmsg=PeList[index][j];
+
+       ptrvec.insert(npacked, tempmsg);
+      }
+      
+      //ComlibPrintf("%d Packing msg_offset=%d\n", CkMyPe(), offset);
+      PACK(int, offset); 
+
+      --(PeList[index][j]->refCount);
+      /*
+       if (--(PeList[index][j]->refCount) <=0) {
+       CmiFree(PeList[index][j]->msg);
+                
+       PTFREE(PeList[index][j]);
+       }
+      */
+      PeList[index][j]=NULL;
+    }
+    msgnum[index]=0;
+  }
+  //offset=-1;
+  //PACK(int, offset);
+
+  // See petable.h for a description of this structure
+  PTvectorlist result = (PTvectorlist)CmiAlloc(sizeof(struct ptvectorlist) +
+                                              (npacked+1)*2*sizeof(char*) +
+                                              2*sizeof(CmiChunkHeader));
+  result->count = npacked + 1;
+  result->sizes = (int*)((char*)result + sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
+  result->msgs  = (char**)((char*)result->sizes + (npacked+1)*sizeof(int) + sizeof(CmiChunkHeader));
+
+  SIZEFIELD(result->sizes) = (npacked+1)*sizeof(int);
+  REFFIELD(result->sizes) = - (sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
+  SIZEFIELD(result->msgs) = (npacked+1)*sizeof(int);
+  REFFIELD(result->msgs) = - (sizeof(struct ptvectorlist) + (npacked+1)*sizeof(int) + 2*sizeof(CmiChunkHeader));
+  CmiReference(result);
+
+  result->sizes[0] = headersize;
+  result->msgs[0] = p;
+  PTinfo *temp;
+  for (i=1; i<=npacked; ++i) {
+    temp = ptrvec[i];
+    result->sizes[i] = temp->msgsize;
+    result->msgs[i] = (char*)temp->msg;
+    // if there is still reference we CmiReference the message so it does not get deleted
+    // otherwise we free also the PTinfo struct use to hold it
+    if (temp->refCount > 0) CmiReference(result->msgs[i]);
+    else PTFREE(temp);
+  }
+
+  ptrvec.removeAll();
+
+  /*    
+       if (lesspe) {
+       t=p+CmiReservedHeaderSize+2*sizeof(int) + sizeof(comID);
+       npe=npe-lesspe;
+       PACK(int, npe);
+       }
+  */
+
+  //return(p);
+
+  return result;
 }
 
+/*
+ * Added by Filippo, 2005/04/18 to allow a zero-copy sending, through the
+ * CmiVectorSend functions.
+ */
 PTvectorlist PeTable :: ExtractAndVectorizeAll(comID id, int ufield) {
-  return NULL;
+  int nmsgs = 0, i, j;
+  int index = 0;
+
+  ComlibPrintf("[%d] In Extract And Vectorize All\n", CkMyPe());
+
+  //Increment magic to detect duplicate messages
+  magic++;
+
+  //register int total_msg_size = 0;
+
+  //first compute size
+  for (i=0;i<NumPes;i++) {
+    index = i;
+    for (j=msgnum[index]-1; (j>=0); j--) {
+      if (PeList[index][j]->magic != magic) {                
+       //total_msg_size += ALIGN8(PeList[index][j]->msgsize);
+       //total_msg_size += 2 * sizeof(int);
+       PeList[index][j]->magic=magic;
+       ptrvec.insert(nmsgs, PeList[index][j]);
+       PeList[index][j] = NULL;
+       nmsgs ++;
+      }
+      --(PeList[index][j]->refCount);
+    }
+  }
+
+  //total_msg_size += ALIGN8(sizeof(AllToAllHdr));
+
+  ComlibPrintf("[%d] nmsgs %d **%d**\n", CkMyPe(), nmsgs, sizeof(AllToAllHdr));
+    
+  //poiter to the message header
+  AllToAllHdr *ahdr = (AllToAllHdr *) CmiAlloc(sizeof(struct AllToAllHdr));
+
+  ComlibPrintf("After cmialloc\n");
+
+  /*
+  //buffer to copy stuff into
+  char *t = p; 
+  char *junk = NULL;
+    
+  int dummy = 0;
+  */
+
+  int refno = 0;
+
+  ahdr->refno = refno;
+  ahdr->id = id;
+  ahdr->ufield = ufield;
+  ahdr->nmsgs = nmsgs;
+
+  /*
+    PACKINT(refno);    
+    PACK(comID, id);
+      
+    PACKINT(ufield);
+    PACKINT(nmsgs);
+    //    PACKINT(dummy); //Aligning to 8 bytes
+    */
+
+  // See petable.h for a description of this structure
+  PTvectorlist result = (PTvectorlist)CmiAlloc(sizeof(struct ptvectorlist) +
+                                              (nmsgs+1)*2*sizeof(char*) +
+                                              2*sizeof(CmiChunkHeader));
+  result->count = nmsgs + 1;
+  result->sizes = (int*)((char*)result + sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
+  result->msgs  = (char**)((char*)result->sizes + (nmsgs+1)*sizeof(int) + sizeof(CmiChunkHeader));
+
+  SIZEFIELD(result->sizes) = (nmsgs+1)*sizeof(int);
+  REFFIELD(result->sizes) = - (sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
+  SIZEFIELD(result->msgs) = (nmsgs+1)*sizeof(int);
+  REFFIELD(result->msgs) = - (sizeof(struct ptvectorlist) + (nmsgs+1)*sizeof(int) + 2*sizeof(CmiChunkHeader));
+  CmiReference(result);
+
+  result->sizes[0] = sizeof(ahdr);
+  result->msgs[0] = (char*)ahdr;
+  PTinfo *temp;
+  for (i=1; i<nmsgs; ++i) {
+    temp = ptrvec[i];
+    result->sizes[i] = temp->msgsize;
+    result->msgs[i] = (char*)temp->msg;
+    // if there is still reference we CmiReference the message so it does not get deleted
+    // otherwise we free also the PTinfo struct use to hold it
+    if (temp->refCount > 0) CmiReference(result->msgs[i]);
+    else PTFREE(temp);
+  }
+
+  ptrvec.removeAll();
+
+  return result;
+
+  /*
+  PACK(AllToAllHdr, ahdr);   
+
+  int msg_offset = ALIGN8(sizeof(AllToAllHdr));
+    
+  //Increment magic again for creating the message
+  magic++;
+  for (i=0;i<NumPes;i++) {
+    index=i;
+    int ref = 0;
+    int size;
+
+    for (j=msgnum[index]-1; (j>=0); j--) {
+      //Check if it is a duplicate
+      if (PeList[index][j]->magic != magic) {                
+       size = PeList[index][j]->msgsize;
+       PACKMSG(&size, sizeof(int));
+       PACKMSG(&ref, sizeof(int));
+       PeList[index][j]->magic=magic;
+       PACKMSG(PeList[index][j]->msg, size);
+
+       msg_offset = ALIGN8(msg_offset);
+      }
+
+      //Free it when all the processors have gotten rid of it
+      if (--(PeList[index][j]->refCount) <=0) {
+       ComlibPrintf("before cmifree \n");
+       CmiFree(PeList[index][j]->msg);   
+       ComlibPrintf("after cmifree \n");
+
+       PTFREE(PeList[index][j]);
+      }
+      //Assign the current processors message pointer to NULL
+      PeList[index][j] = NULL;
+    }
+    msgnum[index] = 0;
+  }
+    
+  *length = total_msg_size;
+  return p;
+  */
 }
 
-void PeTable :: GarbageCollect()
-{
+void PeTable :: GarbageCollect() {
 }
 
index 2e913470a2d15d8eddd7cdb5ffd8d06bb517adec..ac461fe0410723f61b9e0ab35898c3f797ae1489 100644 (file)
@@ -12,6 +12,8 @@
 #define NULL 0
 #endif
 
+#define CMK_COMMLIB_USE_VECTORIZE 1
+
 #define MSGQLEN 32
 
 typedef struct ptinfo {
@@ -24,10 +26,21 @@ typedef struct ptinfo {
   struct ptinfo * next;
 } PTinfo;
 
+/*
+ * This header is meant for usage with ExtractAndVectorize and
+ * ExtractAndVectorizeAll. It will contain a list of messages with its sizes.
+ * The parent class will later call a CmiFree to sizes and msgs. This will
+ * delete this two arrays, and also the containint ptvectorlist struct. This is
+ * done (in the two functions) by allocating a single message containing both
+ * the ptvectorlist struct, and the two arrays. Throught CmiReference
+ * (incremented only once), when both the arrays are deleted, the struct will
+ * also dirappear.
+ */
+
 typedef struct ptvectorlist {
   int count;
   int *sizes;
-  char *msgs;
+  char **msgs;
 }* PTvectorlist;
 
 /*
index 8ca73f1990c8657d9eb6640e5d4ac1848a667e8c..ab39dce163b05aca983efc00fddc793087acf2be 100644 (file)
 
 /**The only communication op used. Modify this to use
  ** vector send */
+#if CMK_COMMLIB_USE_VECTORIZE
+#define TREESENDFN(kid, u, knewmsg, khndl, knextpe)  \
+       {if (knewmsg) {\
+         CmiSetHandler(knewmsg->msgs[0], khndl);\
+         CmiSyncVectorSendAndFree(knextpe, -knewmsg->count, knewmsg->sizes, knewmsg->msgs);\
+       }\
+       else {\
+         SendDummyMsg(kid, knextpe, u);\
+       }\
+}
+#else
 #define TREESENDFN(kid, u, knewmsg, klen, khndl, knextpe)  \
        {if (knewmsg) {\
          CmiSetHandler(knewmsg, khndl);\
@@ -28,6 +39,7 @@
          SendDummyMsg(kid, knextpe, u);\
        }\
 }
+#endif
 
 /************************************************
  ************************************************/
@@ -97,9 +109,13 @@ void TreeRouter :: RecvManyMsg(comID id, char *msg)
                int len;
                int parent=(MyPe-1)/DEGREE;
                parent=gmap(parent);
+#if CMK_COMMLIB_USE_VECTORIZE
+               PTvectorlist newmsg=SortBufferUp(id, 0);
+               TREESENDFN(id, 0, newmsg, CkpvAccess(RecvHandle), parent);
+#else
                char *newmsg=SortBufferUp(id, 0, &len);
                TREESENDFN(id, 0, newmsg, len, CkpvAccess(RecvHandle), parent);
-
+#endif
        }
        else {
                DownStreamMsg(id);
@@ -108,7 +124,11 @@ void TreeRouter :: RecvManyMsg(comID id, char *msg)
   if (recvCount > recvExpected) DownStreamMsg(id);
 }
 
+#if CMK_COMMLIB_USE_VECTORIZE
+PTvectorlist TreeRouter :: SortBufferUp(comID id, int ufield)
+#else
 char * TreeRouter :: SortBufferUp(comID id, int ufield, int *len)
+#endif
 {
   int np=0, i;
   int * pelst=(int *)CmiAlloc(sizeof(int)*NumPes);
@@ -122,12 +142,20 @@ char * TreeRouter :: SortBufferUp(comID id, int ufield, int *len)
 
        pelst[np++]=i;
   }
+#if CMK_COMMLIB_USE_VECTORIZE
+  PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, pelst); 
+#else
   char *newmsg=PeTree->ExtractAndPack(id, ufield, np, pelst, len); 
+#endif
   CmiFree(pelst);
   return(newmsg);
 }
   
+#if CMK_COMMLIB_USE_VECTORIZE
+PTvectorlist TreeRouter :: SortBufferDown(comID id, int ufield, int s)
+#else
 char * TreeRouter :: SortBufferDown(comID id, int ufield, int *len, int s)
+#endif
 {
   int np=0, i;
   int * plist=(int *)CmiAlloc(sizeof(int)*NumPes);
@@ -140,7 +168,11 @@ char * TreeRouter :: SortBufferDown(comID id, int ufield, int *len, int s)
        if (pe == rep) plist[np++]=i;
   }
 
+#if CMK_COMMLIB_USE_VECTORIZE
+  PTvectorlist newmsg=PeTree->ExtractAndVectorize(id, ufield, np, plist); 
+#else
   char * newmsg=PeTree->ExtractAndPack(id, ufield, np, plist, len); 
+#endif
   CmiFree(plist);
   return(newmsg);
 }
@@ -152,11 +184,19 @@ void TreeRouter :: DownStreamMsg(comID id)
 
   for (int i=0;i<deg;i++) {
     int len;
+#if CMK_COMMLIB_USE_VECTORIZE
+    PTvectorlist newmsg=SortBufferDown(id, 0, i+1);
+#else
     char *newmsg=SortBufferDown(id, 0, &len, i+1);
+#endif
     int child=MyPe*DEGREE+i+1;
     if (child >=NumPes || child==MyPe) break;
     child=gmap(child);
+#if CMK_COMMLIB_USE_VECTORIZE
+    TREESENDFN(id, 0, newmsg, CkpvAccess(RecvHandle), child);
+#else
     TREESENDFN(id, 0, newmsg, len, CkpvAccess(RecvHandle), child);
+#endif
   }
 
   LocalProcMsg(id);
index 620e4dc81bbd0e2c307dfedd5dbe91656314d0ca..d306b08cb36452d711c5417b923bef7ca01a2297 100644 (file)
@@ -21,8 +21,13 @@ class TreeRouter : public Router
        void InitVars();
        void DownStreamMsg(comID id);
        void LocalProcMsg(comID);
+#if CMK_COMMLIB_USE_VECTORIZE
+       PTvectorlist SortBufferUp(comID, int);
+       PTvectorlist SortBufferDown(comID, int, int);
+#else
        char * SortBufferUp(comID, int, int *);
        char * SortBufferDown(comID, int, int *, int);
+#endif
   public:
        TreeRouter(int, int);
        ~TreeRouter();