Adding some user events to trace the multicasts.
[charm.git] / src / ck-com / OneTimeMulticastStrategy.h
1 /**
2    @addtogroup ComlibCharmStrategy
3    @{
4    
5    @file 
6  
7 */
8
9 #ifndef ONE_TIME_MULTICAST_STRATEGY
10 #define ONE_TIME_MULTICAST_STRATEGY
11
12 #include "ComlibManager.h"
13 #include "ComlibSectionInfo.h"
14
15 /**
16    The simplest multicast strategy. This strategy extracts the array section information, and packs the section information and the user message into a single message. The original message is delivered locally, and the new message is sent using CmiSyncListSendAndFree to all other processors containing destination objects. 
17
18    This strategy is simpler than those which are derived from the MulticastStrategy class because those maintain a persistant record of previous array section information extracted from the messages, and those provide multiple implementations of the multicast tree (such as ring or multiring or all to all). Those strategies ought to be used when multiple multicasts are sent to the same array section. If an array section is not reused, then this strategy ought to be used.
19
20    A class can be created which inherits from this class, but provides its own determineNextHopPEs method to specify any type of desired spanning tree. For example, OneTimeRingMulticastStrategy forwards the multicast messages in a ring while OneTimeTreeMulticastStrategy forwards messages along a tree of specified degree. In the future, topology aware (both network and core/cpu/node) strategies should be added.
21
22    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.
23    
24    To create a new strategy:
25    <ul>
26    <li>Add a class declaration similar to the ones below, making sure they inherit from OneTimeMulticastStrategy. 
27    <li>Add a PUPable entry in ComlibManager.ci 
28    <li>Implement determineNextHopPEs in OneTimeMulticastStrategy.C. See information for OneTimeMulticastStrategy::determineNextHopPEs .
29    </ul>
30
31 @todo  Buffer messages until strategy is fully enabled. The current version might have some startup issues if the multicast is used too early.
32
33 @todo  Implement topology aware subclasses. 
34
35 */
36 class OneTimeMulticastStrategy: public Strategy, public CharmStrategy {
37  private:
38   
39   ComlibSectionInfo sinfo; // This is used to create the multicast messages themselves
40
41   void remoteMulticast(ComlibMulticastMsg * multMsg, bool rootPE);
42   void localMulticast(CharmMessageHolder *cmsg);
43   
44  public:
45
46   /** 
47       Determine the set of PEs to which the message should be forwarded from this PE.
48       Fill in pelist and npes to which the multicast message will be forwarded from this PE.
49
50       @param [in] totalDestPEs The number of destination PEs to whom the message needs to be sent. 
51       @param [in] destPEs The list of PEs that eventually will be sent the message.
52       @param [in] myIndex The index into destPEs for this PE.
53
54       @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.
55       @param [out] npes The size of pelist
56
57   */
58   virtual void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
59
60     OneTimeMulticastStrategy(CkMigrateMessage *m): Strategy(m), CharmStrategy(m){}
61   
62   OneTimeMulticastStrategy();
63   ~OneTimeMulticastStrategy();
64   
65   void insertMessage(MessageHolder *msg) {insertMessage((CharmMessageHolder*)msg);}
66   void insertMessage(CharmMessageHolder *msg);
67   
68   ///Called by the converse handler function
69   void handleMessage(void *msg);    
70
71   void pup(PUP::er &p);
72
73   PUPable_decl(OneTimeMulticastStrategy);
74
75 };
76
77
78
79
80
81 /**
82    A strategy that sends along a ring through the destination processors.
83 */
84 class OneTimeRingMulticastStrategy: public OneTimeMulticastStrategy {
85   
86  public:
87   void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
88
89  OneTimeRingMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
90  OneTimeRingMulticastStrategy(): OneTimeMulticastStrategy() {}
91   ~OneTimeRingMulticastStrategy() {}
92   
93   void pup(PUP::er &p){ OneTimeMulticastStrategy::pup(p); }
94   
95   PUPable_decl(OneTimeRingMulticastStrategy);
96
97 };
98
99
100
101 /**
102    A strategy that sends along a tree with user specified branching factor.
103 */
104 class OneTimeTreeMulticastStrategy: public OneTimeMulticastStrategy {
105  private:
106   int degree;
107   
108  public:
109   
110   void determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, int * &pelist, int &npes );
111   
112  OneTimeTreeMulticastStrategy(CkMigrateMessage *m): OneTimeMulticastStrategy(m) {}
113
114   /** Create a strategy with specified branching factor(which defaults to 4) */
115  OneTimeTreeMulticastStrategy(int treeDegree=4): OneTimeMulticastStrategy(), degree(treeDegree) {}
116
117   ~OneTimeTreeMulticastStrategy() {}
118   
119   void pup(PUP::er &p){ 
120     OneTimeMulticastStrategy::pup(p); 
121     p | degree;
122   }
123   
124   PUPable_decl(OneTimeTreeMulticastStrategy);
125 };
126
127
128
129 #endif
130
131 /*@}*/