Adding a new node aware multicast strategy that sends to PEs within a node along...
[charm.git] / src / ck-com / OneTimeMulticastStrategy.h
index 46c8be78bbbe7ca4d2a04545fc8a6c91a6b01d7f..8cbf6a344d447a33c3887320e563842197270f4c 100644 (file)
 
    The local messages are delivered through the array manager using the CharmStrategy::deliverToIndices methods. If a destination chare is remote, the array manager will forward it on to the pe that contains the chare.
    
+   To create a new strategy:
+   <ul>
+   <li>Add a class declaration similar to the ones below, making sure they inherit from OneTimeMulticastStrategy. 
+   <li>Add a PUPable entry in ComlibManager.ci 
+   <li>Implement determineNextHopPEs in OneTimeMulticastStrategy.C. See information for OneTimeMulticastStrategy::determineNextHopPEs .
+   </ul>
+
+@todo  Buffer messages until strategy is fully enabled. The current version might have some startup issues if the multicast is used too early.
+
+@todo  Implement topology aware subclasses. 
+
 */
 class OneTimeMulticastStrategy: public Strategy, public CharmStrategy {
  private:
@@ -32,9 +43,21 @@ class OneTimeMulticastStrategy: public Strategy, public CharmStrategy {
   
  public:
 
-  virtual void determineNextHopPEs(ComlibMulticastMsg * multMsg, int myIndex, int * &pelist, int &npes );
-  
- OneTimeMulticastStrategy(CkMigrateMessage *m): Strategy(m), CharmStrategy(m){}
+  /** 
+      Determine the set of PEs to which the message should be forwarded from this PE.
+      Fill in pelist and npes to which the multicast message will be forwarded from this PE.
+
+      @param [in] totalDestPEs The number of destination PEs to whom the message needs to be sent. This will always be > 0.
+      @param [in] destPEs The list of PEs that eventually will be sent the message.
+      @param [in] myIndex The index into destPEs for this PE.
+
+      @param [out] pelist A list of PEs to which the message will be sent after this function returns. This function allocates the array with new. The caller will free it with delete[] if npes>0.
+      @param [out] npes The size of pelist
+
+  */
+  virtual void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
+
+    OneTimeMulticastStrategy(CkMigrateMessage *m): Strategy(m), CharmStrategy(m){}
   
   OneTimeMulticastStrategy();
   ~OneTimeMulticastStrategy();
@@ -56,12 +79,12 @@ class OneTimeMulticastStrategy: public Strategy, public CharmStrategy {
 
 
 /**
-   A OneTimeMulticastStrategy that sends along a ring
+   A strategy that sends along a ring through the destination processors.
 */
 class OneTimeRingMulticastStrategy: public OneTimeMulticastStrategy {
   
  public:
-  void determineNextHopPEs(ComlibMulticastMsg * multMsg, int myIndex, int * &pelist, int &npes );
+  void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
 
  OneTimeRingMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
  OneTimeRingMulticastStrategy(): OneTimeMulticastStrategy() {}
@@ -76,7 +99,7 @@ class OneTimeRingMulticastStrategy: public OneTimeMulticastStrategy {
 
 
 /**
-   A OneTimeMulticastStrategy that sends along a tree of arbitrary degree
+   A strategy that sends along a tree with user specified branching factor.
 */
 class OneTimeTreeMulticastStrategy: public OneTimeMulticastStrategy {
  private:
@@ -84,10 +107,13 @@ class OneTimeTreeMulticastStrategy: public OneTimeMulticastStrategy {
   
  public:
   
-  void determineNextHopPEs(ComlibMulticastMsg * multMsg, int myIndex, int * &pelist, int &npes );
+  void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
   
  OneTimeTreeMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
+
+  /** Create a strategy with specified branching factor(which defaults to 4) */
  OneTimeTreeMulticastStrategy(int treeDegree=4): OneTimeMulticastStrategy(), degree(treeDegree) {}
+
   ~OneTimeTreeMulticastStrategy() {}
   
   void pup(PUP::er &p){ 
@@ -96,11 +122,71 @@ class OneTimeTreeMulticastStrategy: public OneTimeMulticastStrategy {
   }
   
   PUPable_decl(OneTimeTreeMulticastStrategy);
+};
+
+
+
+
+
+
+/**
+   A node-aware strategy that sends along a node-based tree with user specified branching factor. Once the message reaches the PE representative for each node, it is forwarded from the PE to all other destination PEs on the node. This strategy can result in imbalanced loads. The PEs along the tree have higher load than the other PEs.
+*/
+class OneTimeNodeTreeMulticastStrategy: public OneTimeMulticastStrategy {
+ private:
+  int degree;
+  
+ public:
+  
+  void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
+  
+ OneTimeNodeTreeMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
+  
+  /** Create a strategy with specified branching factor(which defaults to 4) */
+ OneTimeNodeTreeMulticastStrategy(int treeDegree=4): OneTimeMulticastStrategy(), degree(treeDegree) {}
+  
+  ~OneTimeNodeTreeMulticastStrategy() {}
   
+  void pup(PUP::er &p){ 
+    OneTimeMulticastStrategy::pup(p); 
+    p | degree;
+  }
+  
+  PUPable_decl(OneTimeNodeTreeMulticastStrategy);
 };
 
 
 
+/**
+   A node-aware strategy that sends along a node-based tree with user specified branching factor. Once the message arrives at the first PE on the node, it is forwarded to the other PEs on the node through a ring.
+*/
+class OneTimeNodeTreeRingMulticastStrategy: public OneTimeMulticastStrategy {
+ private:
+  int degree;
+  
+ public:
+  
+  void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
+  
+ OneTimeNodeTreeRingMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
+  
+  /** Create a strategy with specified branching factor(which defaults to 4) */
+ OneTimeNodeTreeRingMulticastStrategy(int treeDegree=4): OneTimeMulticastStrategy(), degree(treeDegree) {}
+  
+  ~OneTimeNodeTreeRingMulticastStrategy() {}
+  
+  void pup(PUP::er &p){ 
+    OneTimeMulticastStrategy::pup(p); 
+    p | degree;
+  }
+  
+  PUPable_decl(OneTimeNodeTreeRingMulticastStrategy);
+};
+
+
+
+
+
 #endif
 
 /*@}*/