Added doxygen documentation.
authorFilippo Gioachin <gioachin@illinois.edu>
Mon, 18 Jul 2005 05:53:55 +0000 (05:53 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Mon, 18 Jul 2005 05:53:55 +0000 (05:53 +0000)
Fixed bug for multicast when LastKnown is not coherent among all processors.
Now the information of the source processor is multicasted together with the
message, and is used by everyone.
MultiRing is not updated with this check-in, and thus broken. Nevertheless due
to the bug it was not working even before...

src/ck-com/ComlibManager.ci
src/ck-com/ComlibManager.h
src/ck-com/ComlibSectionInfo.C
src/ck-com/ComlibSectionInfo.h
src/ck-com/DirectMulticastStrategy.C
src/ck-com/DirectMulticastStrategy.h
src/ck-com/MultiRingMulticast.h
src/ck-com/RingMulticastStrategy.C
src/ck-com/RingMulticastStrategy.h

index c98ce102899044b077b5edc150ed93af29b77cf1..51024919cfaf32c7937d99f0f92aada9143b078d 100644 (file)
@@ -4,6 +4,7 @@ module comlib {
   message ComlibDummyMsg;
   //  message PrioMsg;
   message ComlibMulticastMsg {
+       ComlibMulticastIndexCount indicesCount[];
        CkArrayIndexMax indices[];
        char usrMsg[];
   };
index 832395256c5a3c5e01850dc55eeada802920ccbc..f0792b7c8ca03e208656722246ab7b0e41fb2710 100644 (file)
@@ -45,13 +45,22 @@ class PrioMsg: public CMessage_PrioMsg {
 };
 */
 
+/**
+ * Structure used to hold a count of the indeces associated to each pe in a multicast message.
+ */
+struct ComlibMulticastIndexCount {
+  int pe;
+  int count;
+};
+
 class ComlibMulticastMsg : public CkMcastBaseMsg, 
                public CMessage_ComlibMulticastMsg {
     
   public:
-    int nIndices;
-    char *usrMsg;        
+    int nPes;
+    ComlibMulticastIndexCount *indicesCount;
     CkArrayIndexMax *indices;
+    char *usrMsg;        
 };
 
 class ComlibManager;
index bb9a414bcb988dd73da0ac8537434fd81eec0838..87a3c2a4a546afc08f72547787ab9bc2d0be8451 100644 (file)
@@ -17,25 +17,44 @@ ComlibMulticastMsg * ComlibSectionInfo::getNewMulticastMessage
     initSectionID(cmsg->sec_id);   
 
     CkPackMessage(&env);
-    int sizes[2];
-    sizes[0] = cmsg->sec_id->_nElems;
-    sizes[1] = env->getTotalsize();                
+    int nRemotePes, nRemoteIndices;
+    ComlibMulticastIndexCount *indicesCount;
+    int *belongingList;
+    getRemotePeCount(cmsg->sec_id->_nElems, cmsg->sec_id->_elems, nRemotePes, nRemoteIndices, indicesCount, belongingList);
+    if (nRemotePes == 0) return NULL;
+
+    int sizes[3];
+    sizes[0] = nRemotePes;
+    sizes[1] = nRemoteIndices; // only those remote ///cmsg->sec_id->_nElems;
+    sizes[2] = env->getTotalsize();
     
-    ComlibPrintf("Creating new comlib multicast message %d, %d\n", sizes[0], sizes[1]);
+    ComlibPrintf("Creating new comlib multicast message %d, %d %d\n", sizes[0], sizes[1], sizes[2]);
     
     ComlibMulticastMsg *msg = new(sizes, 0) ComlibMulticastMsg;
-    msg->nIndices = cmsg->sec_id->_nElems;
+    msg->nPes = nRemotePes;
     msg->_cookie.sInfo.cInfo.instId = instanceID;
     msg->_cookie.sInfo.cInfo.id = MaxSectionID - 1;
     msg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_NEW_SECTION;
     msg->_cookie.type = COMLIB_MULTICAST_MESSAGE;
     msg->_cookie.pe = CkMyPe();
     
-    memcpy(msg->indices, cmsg->sec_id->_elems, 
-           sizes[0] * sizeof(CkArrayIndexMax));
-    memcpy(msg->usrMsg, env, sizes[1] * sizeof(char));         
+    // fill in the three pointers of the ComlibMulticastMsg
+    memcpy(msg->indicesCount, indicesCount, sizes[0] * sizeof(ComlibMulticastIndexCount));
+    //memcpy(msg->indices, cmsg->sec_id->_elems, sizes[1] * sizeof(CkArrayIndexMax));
+    CkArrayIndexMax *indicesPe[nRemotePes];
+    indicesPe[0] = msg->indices;
+    for (int i=1; i<nRemotePes; ++i) indicesPe[i] = indicesPe[i-1] + indicesCount[i-1].count;
+    for (int i=0; i<cmsg->sec_id->_nElems; ++i) {
+      if (belongingList[i] >= 0) {
+       *indicesPe[belongingList[i]] = cmsg->sec_id->_elems[i];
+       indicesPe[belongingList[i]]++;
+      }
+    }
+    memcpy(msg->usrMsg, env, sizes[2] * sizeof(char));
     envelope *newenv = UsrToEnv(msg);
-    
+    delete [] indicesCount;
+    delete [] belongingList;
+
     newenv->getsetArrayMgr() = env->getsetArrayMgr();
     newenv->getsetArraySrcPe() = env->getsetArraySrcPe();
     newenv->getsetArrayEp() = env->getsetArrayEp();
@@ -50,12 +69,24 @@ ComlibMulticastMsg * ComlibSectionInfo::getNewMulticastMessage
     return (ComlibMulticastMsg *)EnvToUsr(newenv);
 }
 
-void ComlibSectionInfo::unpack(envelope *cb_env, 
-                               CkVec<CkArrayIndexMax> &dest_indices, 
+void ComlibSectionInfo::unpack(envelope *cb_env,
+                              int &nLocalElems,
+                               CkArrayIndexMax *&dest_indices, 
                                envelope *&env) {
         
     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
-    
+    int i;
+
+    dest_indices = ccmsg->indices;
+    for (i=0; i<ccmsg->nPes; ++i) {
+      if (ccmsg->indicesCount[i].pe == CkMyPe()) break;
+      dest_indices += ccmsg->indicesCount[i].count;
+    }
+
+    CkAssert(i < ccmsg->nPes);
+    nLocalElems = ccmsg->indicesCount[i].count;
+
+    /*
     for(int count = 0; count < ccmsg->nIndices; count++){
         CkArrayIndexMax idx = ccmsg->indices[count];
         
@@ -66,8 +97,9 @@ void ComlibSectionInfo::unpack(envelope *cb_env,
         
         //        if(dest_proc == CkMyPe())
         dest_indices.insertAtEnd(idx);                        
-    }            
-    
+    }
+    */
+
     envelope *usrenv = (envelope *) ccmsg->usrMsg;
     env = (envelope *)CmiAlloc(usrenv->getTotalsize());
     memcpy(env, ccmsg->usrMsg, usrenv->getTotalsize());
@@ -123,6 +155,55 @@ void ComlibSectionInfo::getPeList(int _nElems,
 }
 
 
+void ComlibSectionInfo::getRemotePeCount(int nindices, CkArrayIndexMax *idxlist, 
+                     int &npes, int &nidx,
+                     ComlibMulticastIndexCount *&counts, int *&belongs) {
+  int count = 0;
+  int i;
+    
+  int length = CkNumPes();
+
+  if(length > nindices) length = nindices;
+    
+  counts = new ComlibMulticastIndexCount[length];
+  belongs = new int[nindices];
+  npes = 0;
+  nidx = 0;
+
+  for(i=0; i<nindices; ++i){
+    int p = ComlibGetLastKnown(destArrayID, idxlist[i]);
+    if(p == CkMyPe()) {
+      belongs[i] = -1;
+      continue;
+    }
+    
+    if(p == -1) CkAbort("Invalid Section\n");        
+
+    ++nidx;
+    //Collect remote processors
+    for(count = 0; count < npes; count ++)
+      if(counts[count].pe == p)
+       break;
+    
+    if(count == npes) {
+      counts[npes].pe = p;
+      counts[npes].count = 0;
+      ++npes;
+    }
+
+    counts[count].count++;
+    belongs[i] = count;
+  }
+  
+  if(npes == 0) {
+    delete [] counts;
+    delete [] belongs;
+    counts = NULL;
+    belongs = NULL;
+  }
+}
+
+
 void ComlibSectionInfo::getRemotePelist(int nindices, 
                                         CkArrayIndexMax *idxlist, 
                                         int &npes, int *&pelist) {
@@ -130,6 +211,18 @@ void ComlibSectionInfo::getRemotePelist(int nindices,
     int count = 0, acount = 0;
     
     int length = CkNumPes();
+
+    // HACK FOR DEBUGGING
+    /*pelist = new int[length-1];
+    npes = length-1;
+    for (acount=0; acount<length; acount++) {
+      if (acount == CkMyPe()) continue;
+      pelist[count]=acount;
+      count++;
+    }
+    return;*/
+    // END HACK
+
     if(length > nindices)
         length = nindices;
     
index 1ed2fedf3509946bd534f95dbea2849b5c5a3430..27029a8f66281542ce7e3c50d55b7ee966b4f234 100644 (file)
@@ -132,13 +132,43 @@ class ComlibSectionInfo {
     
     void processOldSectionMessage(CharmMessageHolder *cmsg);
 
+    /**
+     * Starting from a message to be sent, it generates a new message containing
+     * the information about the multicast, together with the message itself.
+     * The info about the multicast is contained in the field sec_id of cmsg.
+     */
     ComlibMulticastMsg *getNewMulticastMessage(CharmMessageHolder *cmsg);
 
-    void unpack(envelope *cb_env, CkVec<CkArrayIndexMax> &destIndices, 
+    /**
+     * Given a ComlibMulticastMsg arrived through the network as input (cb_env),
+     * separate it into its basic components.
+
+     * destIndeces is the pointer to the first element in this processor (as by
+     * the knowledge of the sender); nLocalElems is the count of how many
+     * elements are local. env is a new allocated memory containing the user
+     * message.
+     */
+    void unpack(envelope *cb_env, int &nLocalElems, CkArrayIndexMax *&destIndices, 
                 envelope *&env);
 
     void localMulticast(envelope *env);
 
+    /**
+     * Returns the number of remote procs involved in the array index list, the
+     * number of elements each proc has, and the mapping between indices and
+     * procs.
+     
+     * @param nindices size of the array idxlist (input)
+     * @param idxlist array of indeces of the section (input)
+     * @param npes number of processors involved (output)
+     * @param nidx number of indices that are remote (output)
+     * @param counts array of associations pe-count: number of elements in proc pe (output, new'ed(CkNumPes()))
+     * @param belongs array of integers expressing association of elements with pes: belongs[i] = index in counts of the processor having index i (output, new'ed(nidx))
+    */
+    void getRemotePeCount(int nindices, CkArrayIndexMax *idxlist, 
+                         int &npes, int &nidx,
+                         ComlibMulticastIndexCount *&counts, int *&belongs);
+
     void getRemotePelist(int nindices, CkArrayIndexMax *idxlist, 
                          int &npes, int *&pelist);
 
index ba4e77541f28167c4e2ecf5b97c364db82428687..ccbad98dc1e22f959ac422aaa4b58aef1bde768a 100644 (file)
@@ -105,7 +105,7 @@ void DirectMulticastStrategy::insertMessage(CharmMessageHolder *cmsg){
             localMulticast(UsrToEnv(msg), obj);
             CkFreeMsg(msg);
             
-            remoteMulticast(UsrToEnv(newmsg), obj);
+            if (newmsg != NULL) remoteMulticast(UsrToEnv(newmsg), obj);
         }        
     }
     else 
@@ -130,8 +130,8 @@ void DirectMulticastStrategy::insertSectionID(CkSectionID *sid) {
 }
 
 
-ComlibSectionHashObject *DirectMulticastStrategy::createObjectOnSrcPe
-(int nindices, CkArrayIndexMax *idxlist) {
+ComlibSectionHashObject *
+DirectMulticastStrategy::createObjectOnSrcPe(int nindices, CkArrayIndexMax *idxlist) {
 
     ComlibSectionHashObject *obj = new ComlibSectionHashObject();
     
@@ -142,16 +142,21 @@ ComlibSectionHashObject *DirectMulticastStrategy::createObjectOnSrcPe
 }
 
 
-ComlibSectionHashObject *DirectMulticastStrategy::
-createObjectOnIntermediatePe(int nindices, CkArrayIndexMax *idxlist, 
-                             int srcpe){
+ComlibSectionHashObject *
+DirectMulticastStrategy::createObjectOnIntermediatePe(int nindices,
+                                                     CkArrayIndexMax *idxlist,
+                                                     int npes,
+                                                     ComlibMulticastIndexCount *counts,
+                                                     int srcpe) {
 
     ComlibSectionHashObject *obj = new ComlibSectionHashObject();
         
     obj->pelist = 0;
     obj->npes = 0;
-    
-    sinfo.getLocalIndices(nindices, idxlist, obj->indices);
+
+    obj->indices.resize(0);
+    for (int i=0; i<nindices; ++i) obj->indices.insertAtEnd(idxlist[i]);
+    //sinfo.getLocalIndices(nindices, idxlist, obj->indices);
 
     return obj;
 }
@@ -220,6 +225,7 @@ void DirectMulticastStrategy::remoteMulticast(envelope *env,
     CkPackMessage(&env);
     //Sending a remote multicast
     CmiSyncListSendAndFree(npes, pelist, env->getTotalsize(), (char*)env);
+    //CmiSyncBroadcastAndFree(env->getTotalsize(), (char*)env);
 }
 
 void DirectMulticastStrategy::pup(PUP::er &p){
@@ -271,17 +277,19 @@ void DirectMulticastStrategy::handleMessage(void *msg){
     }
 }
 
+#include <string>
 
 void DirectMulticastStrategy::handleNewMulticastMessage(envelope *env) {
     
     ComlibPrintf("%d : In handleNewMulticastMessage\n", CkMyPe());
 
     CkUnpackMessage(&env);    
-    
+
+    int localElems;
     envelope *newenv;
-    CkVec<CkArrayIndexMax> idx_list;    
+    CkArrayIndexMax *local_idx_list;    
     
-    sinfo.unpack(env, idx_list, newenv);
+    sinfo.unpack(env, localElems, local_idx_list, newenv);
 
     ComlibMulticastMsg *cbmsg = (ComlibMulticastMsg *)EnvToUsr(env);
     ComlibSectionHashKey key(cbmsg->_cookie.pe, 
@@ -290,18 +298,34 @@ void DirectMulticastStrategy::handleNewMulticastMessage(envelope *env) {
     ComlibSectionHashObject *old_obj = NULL;
     
     old_obj = sec_ht.get(key);
-    if(old_obj != NULL)
+    if(old_obj != NULL) {
         delete old_obj;
+    }
 
-    
+    /*
     CkArrayIndexMax *idx_list_array = new CkArrayIndexMax[idx_list.size()];
     for(int count = 0; count < idx_list.size(); count++)
         idx_list_array[count] = idx_list[count];
+    */
 
-    ComlibSectionHashObject *new_obj = createObjectOnIntermediatePe
-        (idx_list.size(), idx_list_array, cbmsg->_cookie.pe);
+    ComlibSectionHashObject *new_obj = createObjectOnIntermediatePe(localElems, local_idx_list, cbmsg->nPes, cbmsg->indicesCount, cbmsg->_cookie.pe);
 
-    delete [] idx_list_array;
+    /*
+    char buf[100];
+    std::string tmp = "";
+    for (int i=0; i<idx_list.size(); i++) {
+      sprintf(buf, " (%d-%d-%d-%d)",((short*)&idx_list_array[i])[2],((short*)&idx_list_array[i])[3],((short*)&idx_list_array[i])[4],((short*)&idx_list_array[i])[5]);
+      tmp+=buf;
+    }
+    ComlibPrintf("[%d] LOCAL MULTICAST: %s\n",key.hash(),tmp.data());
+    tmp=""+new_obj->npes;
+    for (int i=0; i<new_obj->npes; i++) {
+      sprintf(buf, " %d",new_obj->pelist[i]);
+      tmp+=buf;
+    }
+    ComlibPrintf("[%d] REMOTE MULTICAST: %s\n",key.hash(),tmp.data());
+    */
+    //delete [] idx_list_array;
     
     sec_ht.put(key) = new_obj;
 
index 10634b1f2368d6b5f9cfe25369902b5cff8eb1d6..52554d377144085aaf9481827a6e1290b41e617f 100644 (file)
@@ -5,7 +5,14 @@
 #include "ComlibSectionInfo.h"
 
 void *DMHandler(void *msg);
+/**
+ * Main class for multicast strategies. It defaults to sending a direct message
+ * to all the processors involved in the multicast.
 
+ * The definition of the section, as well as the location of all the elements in
+ * the processors is determined by the sending processor. The other will obey to
+ * it, even some elements have already migrated elsewhere.
+ */
 class DirectMulticastStrategy: public CharmStrategy {
  protected:
     //   int handlerId;    
@@ -13,39 +20,48 @@ class DirectMulticastStrategy: public CharmStrategy {
 
     int isPersistent; 
     
-    //Array section support
+    ///Array section support.
     CkHashtableT<ComlibSectionHashKey, ComlibSectionHashObject *> sec_ht; 
     
-    //Add this section to the hash table locally
+    ///Add this section to the hash table locally.
     void insertSectionID(CkSectionID *sid);
 
-    //Called when a new section multicast is called by the user locally.
-    //The strategy should then create a topology for it and 
-    //return a hash object to store that topology
-    virtual ComlibSectionHashObject *createObjectOnSrcPe
-        (int nindices, CkArrayIndexMax *idx_list);
-   
-    //Similar to createHashObjectOnSrcPe, but that this call 
-    //is made on the destination or intermediate processor
-    virtual ComlibSectionHashObject *createObjectOnIntermediatePe
-        (int nindices, CkArrayIndexMax *idx_list, int srcpe);
+    ///Called when a new section multicast is called by the user locally.
+    ///The strategy should then create a topology for it and return a hash
+    ///object to store that topology.
+    virtual ComlibSectionHashObject *createObjectOnSrcPe(int nindices, CkArrayIndexMax *idx_list);
+
+    /**   
+     * Similar to createHashObjectOnSrcPe, but that this call is made on the
+     * destination or intermediate processor. I receives all the information in
+     * the parameters, and it does not use ComlibLastKnown, since in some cases
+     * it can be incoherent.
+
+     * @param nindices number of local elements to multicast
+     * @param idxlist list of local elements
+     * @param npes number of processors involved in the multicast
+     * @param counts list of all the processors involved int the multicast
+     * @param srcpe processor which started the multicast
+     * @return a hash object describing the section
+     */
+    virtual ComlibSectionHashObject *createObjectOnIntermediatePe(int nindices, CkArrayIndexMax *idxlist, int npes, ComlibMulticastIndexCount *counts, int srcpe);
         
-    //Called to multicast the message to local array elements
+    ///Called to multicast the message to local array elements.
     void localMulticast(envelope *env, ComlibSectionHashObject *obj);
     
-    //Called to send to message out to the remote destinations
-    //This method can be overridden to call converse level strategies 
+    ///Called to send to message out to the remote destinations.
+    ///This method can be overridden to call converse level strategies.
     virtual void remoteMulticast(envelope *env, ComlibSectionHashObject *obj);
 
-    //Process a new message by extracting the array elements 
-    //from it and creating a new hash object by calling createObjectOnIntermediatePe();
+    ///Process a new message by extracting the array elements from it and
+    ///creating a new hash object by calling createObjectOnIntermediatePe().
     void handleNewMulticastMessage(envelope *env);
 
  public:
 
     DirectMulticastStrategy(CkMigrateMessage *m): CharmStrategy(m){}
                 
-    //Array constructor
+    ///Array constructor
     DirectMulticastStrategy(CkArrayID aid, int isPersistent = 0);
         
     //Destuctor
@@ -54,7 +70,7 @@ class DirectMulticastStrategy: public CharmStrategy {
     virtual void insertMessage(CharmMessageHolder *msg);
     virtual void doneInserting();
 
-    //Called by the converse handler function
+    ///Called by the converse handler function
     virtual void handleMessage(void *msg);    
 
     virtual void pup(PUP::er &p);    
index b2150be5e47c4d5f783946185ec441d4cba53e5f..5669179febcd2e8e25d3f01c70d2908e189a7cb2 100644 (file)
       Sameer - 04/19/05
 *************************************************************/
 
-
+/**
+ * Multicast strategy that sends the data using two rings. It divides the total
+ * number of processors involved in the multicast in two (after ordering them).
+ * Then two rings are created, one starting with the source processor and its
+ * half, the other starting at (CkMyPe()+CkNumPes()/2)%CkNumPes().
+ */
 class MultiRingMulticast: public DirectMulticastStrategy {
     
  protected:
     
     int isEndOfRing(int next_pe, int src_pe);
     
-    //Defining the two entries of the section multicast interface
+    ///Defines the two entries of the section multicast interface
     virtual ComlibSectionHashObject *createObjectOnSrcPe(int nelements, 
                                                          CkArrayIndexMax *elements);
-    
+
+    ///Creates the propagation across the half ring
     virtual ComlibSectionHashObject *createObjectOnIntermediatePe
         (int nelements, CkArrayIndexMax *elements, int src_pe);
     
@@ -33,7 +39,7 @@ class MultiRingMulticast: public DirectMulticastStrategy {
     //Destructor
     ~MultiRingMulticast() {}
     
-    void pup(PUP::er &p);    
+    void pup(PUP::er &p);
     void beginProcessing(int nelements);
     
     PUPable_decl(MultiRingMulticast);
index 80acb7562c7470361dcde65e1b062fe62b4fc7cc..131000f3b79bd700f595645add79c3f58c0358cf 100644 (file)
@@ -72,21 +72,44 @@ ComlibSectionHashObject *RingMulticastStrategy::createObjectOnSrcPe
 }
 
 
-ComlibSectionHashObject *RingMulticastStrategy::createObjectOnIntermediatePe
-(int nelements, CkArrayIndexMax *elements, int src_pe){
-
-    ComlibSectionHashObject *obj;
-
-    obj = createObjectOnSrcPe(nelements, elements);
-    
-    //here we check if have reached the end of the ring
-    if(obj->npes > 0 && isEndOfRing(*obj->pelist, src_pe)) {
-        delete obj->pelist;
-        obj->pelist = NULL;
-        obj->npes =0;
+ComlibSectionHashObject *
+RingMulticastStrategy::createObjectOnIntermediatePe(int nindices,
+                                                   CkArrayIndexMax *idxlist,
+                                                   int npes,
+                                                   ComlibMulticastIndexCount *counts,
+                                                   int src_pe){
+
+  ComlibSectionHashObject *obj = new ComlibSectionHashObject;
+
+  obj->indices.resize(0);
+  for (int i=0; i<nindices; ++i) obj->indices.insertAtEnd(idxlist[i]);
+  //obj = createObjectOnSrcPe(nelements, elements);
+
+  obj->pelist = new int[1];
+  obj->npes = 1;
+  obj->pelist[0] = CkMyPe(); // this is neutral for the if inside next loop
+
+  // find the next processor in the ring
+  for (int i=0; i<npes; ++i) {
+    if (obj->pelist[0] > CkMyPe()) { // we have already found a processor greater
+                                     // than us, find the smallest among them
+      if (counts[i].pe > CkMyPe() && counts[i].pe < obj->pelist[0])
+       obj->pelist[0] = counts[i].pe;
+    } else {  // we have not yet found a processor greater than us, stick with
+             // the smallest, or one greater than us
+      if (counts[i].pe < obj->pelist[0] || counts[i].pe > CkMyPe())
+       obj->pelist[0] = counts[i].pe;
     }
-
-    return obj;
+  }
+    
+  //here we check if have reached the end of the ring
+  if(obj->npes > 0 && isEndOfRing(*obj->pelist, src_pe)) {
+    delete obj->pelist;
+    obj->pelist = NULL;
+    obj->npes = 0;
+  }
+
+  return obj;
 }
 
 //We need to end the ring, 
index 6eb24dac3c5c116ec9756eea699d28399e3156d6..67195ec45e642eab836b9934559a3b333a3f7580 100644 (file)
@@ -3,7 +3,12 @@
 
 #include "DirectMulticastStrategy.h"
 
-
+/**
+ * Multicast Strategy that sends a multicast in a ring: the source processor
+ * send a message only to its following neighbour, which propagates it forward
+ * to its neighbour, and so on. Only the processors involved in the multicast
+ * are part of the ring.
+ */
 class RingMulticastStrategy: public DirectMulticastStrategy {
     
  protected:
@@ -14,8 +19,11 @@ class RingMulticastStrategy: public DirectMulticastStrategy {
     virtual ComlibSectionHashObject *createObjectOnSrcPe(int nelements, 
                                                          CkArrayIndexMax *elements);
 
-    virtual ComlibSectionHashObject *createObjectOnIntermediatePe
-        (int nelements, CkArrayIndexMax *elements, int src_pe);
+    virtual ComlibSectionHashObject *createObjectOnIntermediatePe(int nelements,
+                                                                 CkArrayIndexMax *elements,
+                                                                 int npes,
+                                                                 ComlibMulticastIndexCount *counts,
+                                                                 int src_pe);
     
  public: