New comlib strategies for CPMD. Propagates faster than a ring and is largely contenti...
authorSameer Kumar <skumar2@uiuc.edu>
Thu, 21 Apr 2005 19:23:01 +0000 (19:23 +0000)
committerSameer Kumar <skumar2@uiuc.edu>
Thu, 21 Apr 2005 19:23:01 +0000 (19:23 +0000)
src/ck-com/ComlibManager.C
src/ck-com/ComlibManager.ci
src/ck-com/ComlibSectionInfo.h
src/ck-com/MultiRingMulticast.C [new file with mode: 0644]
src/ck-com/MultiRingMulticast.h [new file with mode: 0644]

index f555cb853888816075ddf0f604ec5ab0003ae764..4acc975e468e443cd1fdff0facaed842b8af8c7a 100644 (file)
@@ -8,6 +8,7 @@
 #include "NodeMulticast.h"
 #include "MsgPacker.h"
 #include "RingMulticastStrategy.h"
+#include "MultiRingMulticast.h"
 #include "PipeBroadcastStrategy.h"
 #include "BroadcastStrategy.h"
 #include "MeshStreamingStrategy.h"
index 2a17dc5565d3576b96f17d894e5a349588697e24..c98ce102899044b077b5edc150ed93af29b77cf1 100644 (file)
@@ -41,6 +41,7 @@ module comlib {
   PUPable MeshStreamingStrategy;
   PUPable PrioStreaming;
   PUPable BroadcastStrategy;
+  PUPable MultiRingMulticast;
 
   //Strategy pupable defined in the array manager code, along with the
   //array listener code
index daa1b52bb2daa8951bb3ef20df3feb713dcb08d1..1ed2fedf3509946bd534f95dbea2849b5c5a3430 100644 (file)
@@ -41,7 +41,7 @@ inline int ComlibSectionHashKey::compare(const ComlibSectionHashKey &k2) const
 }
 
 /*For calls to qsort*/
-inline int intCompare(void *a, void *b){
+inline int intCompare(const void *a, const void *b){
     int a1 = *(int *) a;
     int b1 = *(int *) b;
 
diff --git a/src/ck-com/MultiRingMulticast.C b/src/ck-com/MultiRingMulticast.C
new file mode 100644 (file)
index 0000000..b3ce303
--- /dev/null
@@ -0,0 +1,220 @@
+
+#include "MultiRingMulticast.h"
+
+//Array Constructor
+MultiRingMulticast::MultiRingMulticast(CkArrayID dest_aid, int flag)
+    : DirectMulticastStrategy(dest_aid, flag){
+}
+
+
+void MultiRingMulticast::pup(PUP::er &p){
+
+    DirectMulticastStrategy::pup(p);
+}
+
+void MultiRingMulticast::beginProcessing(int  nelements){
+
+    DirectMulticastStrategy::beginProcessing(nelements);
+}
+
+
+inline int getMyId(int *pelist, int npes, int mype) {
+    int myid = -1;
+
+    for(int count = 0; count < npes; count ++)
+        if(mype == pelist[count])
+            myid = count;
+
+    return myid;
+}
+
+
+//Assumes a sorted input. Returns the next processor greater a given
+//current pe
+inline void getNextPe(int *pelist, int npes, int mype, int &nextpe) {
+    
+    nextpe = pelist[0];
+    
+    int count= 0;
+    for(count = 0; count < npes; count++)
+        if(pelist[count] > mype)
+            break;
+    
+    if(count < npes) 
+        nextpe = pelist[count];
+    
+    return;
+}
+
+
+inline int getMidPe(int *pelist, int npes, int src_pe) {
+    
+    int my_id = 0;
+    int mid_pe = -1;
+    
+    my_id = getMyId(pelist, npes, src_pe);    
+    
+    if(my_id < npes/2)
+        mid_pe = pelist[npes/2 + my_id];        
+    else
+        mid_pe = pelist[my_id % (npes/2)];
+    
+    return mid_pe;
+}
+
+//Unlike ring the source here sends two or more messages while all
+//elements along the ring only send one.
+
+ComlibSectionHashObject *MultiRingMulticast::createObjectOnSrcPe
+(int nelements, CkArrayIndexMax *elements){
+
+    ComlibSectionHashObject *obj = new ComlibSectionHashObject;
+
+    obj->npes = 0;
+    obj->pelist = 0;
+
+    sinfo.getLocalIndices(nelements, elements, obj->indices);
+
+    int *pelist;
+    int npes;
+    sinfo.getRemotePelist(nelements, elements, npes, pelist);
+    
+    if(npes == 0)
+        return obj;
+
+    if(npes == 1) {        
+        obj->npes = 1;        
+        obj->pelist = pelist;
+
+        return obj;
+    }
+
+    if(npes == 2) {        
+        obj->npes = 2;        
+        obj->pelist = pelist;
+        
+        return obj;
+    }
+    
+    pelist[npes ++] = CkMyPe();
+    qsort(pelist, npes, sizeof(int), intCompare);
+
+    int myid = getMyId(pelist, npes, CkMyPe());    
+    int nextpe = -1;
+    
+    if(myid < npes / 2) 
+        getNextPe(pelist, npes/2, CkMyPe(), nextpe);
+    else 
+        getNextPe(pelist+npes/2, npes - npes/2, CkMyPe(), nextpe);
+    
+    int mid_pe = -1;
+    mid_pe = getMidPe(pelist, npes, CkMyPe());
+    
+    delete [] pelist;
+
+    if(nextpe != CkMyPe()) {
+        obj->pelist = new int[2];
+        obj->npes = 2;
+        
+        obj->pelist[0] = nextpe;
+        obj->pelist[1] = mid_pe;
+    }
+    else {
+        CkPrintf("Warning Should not be here !!!!!!!!!\n");
+        obj->pelist = new int[1];
+        obj->npes = 1;
+        
+        obj->pelist[0] = mid_pe;
+    }
+    
+    CkPrintf("%d Src = %d Next = %d Mid Pe =%d\n", CkMyPe(), CkMyPe(), nextpe, mid_pe);    
+    
+    return obj;
+}
+
+
+ComlibSectionHashObject *MultiRingMulticast::createObjectOnIntermediatePe
+(int nelements, CkArrayIndexMax *elements, int src_pe){
+
+    ComlibSectionHashObject *obj = new ComlibSectionHashObject;
+
+    sinfo.getLocalIndices(nelements, elements, obj->indices);
+
+    int *pelist;
+    int npes;
+    sinfo.getRemotePelist(nelements, elements, npes, pelist);
+    
+    obj->pelist = 0;
+    obj->npes = 0;   
+
+    pelist[npes ++] = CkMyPe();
+
+    if(npes <= 3)
+        return obj;
+    
+    qsort(pelist, npes, sizeof(int), intCompare);
+    
+    int myid = getMyId(pelist, npes, CkMyPe());
+    
+    int nextpe = -1;
+
+    int new_src_pe = src_pe;
+    int mid_pe = getMidPe(pelist, npes, src_pe);
+    int src_id = getMyId(pelist, npes, src_pe);
+    
+    if(myid < npes / 2) {
+        getNextPe(pelist, npes/2, CkMyPe(), nextpe);
+
+        //If source is in the other half I have to change to the
+        //middle guy
+        if(src_id >= npes/2)
+            new_src_pe = mid_pe;
+    }
+    else {
+        getNextPe(pelist + (npes/2), npes - npes/2, CkMyPe(), nextpe);
+
+        //If source is in the other half I have to change to the
+        //middle guy
+        if(src_id < npes/2)
+            new_src_pe = mid_pe;
+    }
+
+    bool end_flag = isEndOfRing(nextpe, new_src_pe);
+
+    if((nextpe != CkMyPe()) && ((CkMyPe() == mid_pe) || !end_flag)) {
+        obj->pelist = new int[1];
+        obj->npes = 1;
+        obj->pelist[0] = nextpe;
+    }
+    
+    CkPrintf("%d: Src = %d Next = %d end = %d\n", CkMyPe(), src_pe, 
+             nextpe, end_flag);    
+    
+    
+    delete [] pelist;
+
+    return obj;
+}
+
+//We need to end the ring,
+//    if next_pe is the same as the source_pe, or
+//    if next_pe is the first processor in the ring, greater than srouce_pe.
+//Both these comparisons are done in a 'cyclic' way with wraparounds.
+
+int MultiRingMulticast::isEndOfRing(int next_pe, int src_pe){
+    
+    ComlibPrintf("[%d] isEndofring %d, %d\n", CkMyPe(), next_pe, src_pe);
+    
+    if(next_pe > CkMyPe()){
+        if(src_pe <= next_pe && src_pe > CkMyPe())
+            return 1;
+        
+        return 0;
+    }
+    
+    if(src_pe > CkMyPe() || src_pe <= next_pe)
+        return 1;
+    
+    return 0;
+}
+
diff --git a/src/ck-com/MultiRingMulticast.h b/src/ck-com/MultiRingMulticast.h
new file mode 100644 (file)
index 0000000..b2150be
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef MULTIRING_MULTICAST_STRATEGY
+#define MULTIRING_MULTICAST_STRATEGY
+
+#include "DirectMulticastStrategy.h"
+
+/***************************************************************
+              Section multicast strategy that sends data along a ring 
+              with multiple start points on the ring
+
+      Sameer - 04/19/05
+*************************************************************/
+
+
+class MultiRingMulticast: public DirectMulticastStrategy {
+    
+ protected:
+    
+    int isEndOfRing(int next_pe, int src_pe);
+    
+    //Defining the two entries of the section multicast interface
+    virtual ComlibSectionHashObject *createObjectOnSrcPe(int nelements, 
+                                                         CkArrayIndexMax *elements);
+    
+    virtual ComlibSectionHashObject *createObjectOnIntermediatePe
+        (int nelements, CkArrayIndexMax *elements, int src_pe);
+    
+ public:
+    
+    //Array constructor
+    MultiRingMulticast(CkArrayID dest_id, int flag = 0);    
+    MultiRingMulticast(CkMigrateMessage *m) : DirectMulticastStrategy(m){}
+
+    //Destructor
+    ~MultiRingMulticast() {}
+    
+    void pup(PUP::er &p);    
+    void beginProcessing(int nelements);
+    
+    PUPable_decl(MultiRingMulticast);
+};
+
+#endif
+