Changing CharmStrategy and DirectMulticastStrategy to use the strategy_handler
[charm.git] / src / ck-com / ComlibStrategy.h
1 #ifndef COMMLIBSTRATEGY_H
2 #define COMMLIBSTRATEGY_H
3
4 #include "charm++.h"
5 #include "ckhashtable.h"
6 #include "convcomlibstrategy.h"
7 #include "ComlibLearner.h"
8 #include "envelope.h"
9
10 CkpvExtern(int, migrationDoneHandlerID);
11
12 //Class managing Charm++ messages in the communication library.
13 //It is aware of envelopes, arrays, etc
14 class CharmMessageHolder : public MessageHolder{
15  public:
16     CkSectionID *sec_id;
17
18     CharmMessageHolder() : MessageHolder() {sec_id = NULL;}
19     CharmMessageHolder(CkMigrateMessage *m) : MessageHolder(m) {}
20     
21     CharmMessageHolder(char * msg, int dest_proc);
22     ~CharmMessageHolder();
23
24     inline char * getCharmMessage() {
25         return (char *)EnvToUsr((envelope *) data);
26     }
27     
28     virtual void pup(PUP::er &p);
29     PUPable_decl(CharmMessageHolder);
30 };
31
32
33 //Struct to store the comlib location table info
34 struct ClibGlobalArrayIndex {
35     CkArrayID aid;
36     CkArrayIndexMax idx;
37
38     //These routines allow ClibGlobalArrayIndex to be used in
39     //  a CkHashtableT
40     CkHashCode hash(void) const;
41     static CkHashCode staticHash(const void *a,size_t);
42     int compare(const ClibGlobalArrayIndex &ind) const;
43     static int staticCompare(const void *a,const void *b,size_t);
44 };
45 PUPbytes(ClibGlobalArrayIndex);
46
47 /*********** CkHashTable functions ******************/
48 inline CkHashCode ClibGlobalArrayIndex::hash(void) const
49 {
50     register CkHashCode ret = idx.hash() | (CkGroupID(aid).idx << 16);
51     return ret;
52 }
53
54 inline int ClibGlobalArrayIndex::compare(const ClibGlobalArrayIndex &k2) const
55 {
56     if(idx == k2.idx && aid == k2.aid)
57         return 1;
58     
59     return 0;
60 }
61
62 //ClibGlobalArrayIndex CODE
63 inline int ClibGlobalArrayIndex::staticCompare(const void *k1, const void *k2, 
64                                                 size_t ){
65     return ((const ClibGlobalArrayIndex *)k1)->
66         compare(*(const ClibGlobalArrayIndex *)k2);
67 }
68
69 inline CkHashCode ClibGlobalArrayIndex::staticHash(const void *v,size_t){
70     return ((const ClibGlobalArrayIndex *)v)->hash();
71 }
72
73
74 typedef CkHashtableT<ClibGlobalArrayIndex,int> ClibLocationTableType;
75     
76 //Stores the location of many array elements used by the
77 //strategies.  Since hash table returns a reference to the object
78 //and for an int that will be 0, the actual value stored is pe +
79 //CkNumPes so 0 would mean processor -CkNumPes which is invalid.
80 CkpvExtern(ClibLocationTableType *, locationTable);
81
82 CkpvExtern(CkArrayIndexMax, cache_index);
83 CkpvExtern(int, cache_pe);
84 CkpvExtern(CkArrayID, cache_aid);
85
86 //Info classes that help bracketed streategies manage objects
87 //Each info class points to a list of source (or destination) objects
88 //ArrayInfo also access the array listener interface
89
90 class ComlibNodeGroupInfo {
91  protected:
92     CkNodeGroupID ngid;
93     int isNodeGroup;
94
95  public:
96     ComlibNodeGroupInfo();
97
98     void setSourceNodeGroup(CkNodeGroupID gid) {
99         ngid = gid;
100         isNodeGroup = 1;
101     }
102
103     int isSourceNodeGroup(){return isNodeGroup;}
104     CkNodeGroupID getSourceNodeGroup();
105
106     void pup(PUP::er &p);
107 };
108
109 class ComlibGroupInfo {
110  protected:
111     CkGroupID sgid, dgid;
112     int *srcpelist, nsrcpes; //src processors for the elements
113     int *destpelist, ndestpes;
114     int isSrcGroup;   
115     int isDestGroup;
116
117  public:
118     ComlibGroupInfo();
119     ~ComlibGroupInfo();
120
121     int isSourceGroup(){return isSrcGroup;}
122     int isDestinationGroup(){return isDestGroup;}
123
124     void setSourceGroup(CkGroupID gid, int *srcpelist=0, int nsrcpes=0);    
125     void getSourceGroup(CkGroupID &gid);
126     void getSourceGroup(CkGroupID &gid, int *&pelist, int &npes);
127
128     void setDestinationGroup(CkGroupID sgid,int *destpelist=0,int ndestpes=0);
129     void getDestinationGroup(CkGroupID &gid);
130     void getDestinationGroup(CkGroupID &dgid,int *&destpelist, int &ndestpes);
131
132     void getCombinedPeList(int *&pelist, int &npes);
133     void pup(PUP::er &p);
134 };
135
136 class ComlibMulticastMsg;
137
138 /* Array strategy helper class.
139    Stores the source and destination arrays.
140    Computes most recent processor maps of source and destinaton arrays.
141    
142    Array section helper functions, make use of sections easier for the
143    communication library.
144 */
145
146 class ComlibArrayInfo {
147  protected:
148     CkArrayID src_aid;
149     CkArrayIndexMax *src_elements; //src array elements
150     int nSrcIndices;              //number of source indices   
151     int isSrcArray;
152
153     CkArrayID dest_aid;
154     CkArrayIndexMax *dest_elements; //dest array elements
155     int nDestIndices;              //number of destintation indices   
156     int isDestArray;
157
158     CkVec<CkArrayIndexMax> localDestIndexVec;
159     
160  public:
161     ComlibArrayInfo();
162     ~ComlibArrayInfo();
163
164     void setSourceArray(CkArrayID aid, CkArrayIndexMax *e=0, int nind=0);
165     int isSourceArray(){return isSrcArray;}
166     void getSourceArray(CkArrayID &aid, CkArrayIndexMax *&e, int &nind);
167     
168     void setDestinationArray(CkArrayID aid, CkArrayIndexMax *e=0, int nind=0);
169     int isDestinationArray(){return isDestArray;}
170     void getDestinationArray(CkArrayID &aid, CkArrayIndexMax *&e, int &nind);
171
172     void localBroadcast(envelope *env);
173     static void localMulticast(CkVec<CkArrayIndexMax> *idx_vec,envelope *env);
174     static void deliver(envelope *env);
175
176     void getSourcePeList(int *&pelist, int &npes);
177     void getDestinationPeList(int *&pelist, int &npes);
178     void getCombinedPeList(int *&pelist, int &npes);
179     
180     void pup(PUP::er &p);
181 };
182
183
184 /* All Charm++ communication library strategies should inherit from
185    this strategy. They should specify their object domain by setting
186    Strategy::type. They have three helpers predefined for them for
187    node groups, groups and arrays */
188
189 class CharmStrategy : public Strategy {
190     
191  protected:
192     int forwardOnMigration;
193     ComlibLearner *learner;
194     CmiBool mflag;    //Does this strategy handle point-to-point or 
195
196  public:
197     ComlibGroupInfo ginfo;
198     ComlibNodeGroupInfo nginfo;
199
200     //The communication library array listener watches and monitors
201     //the array elements belonging to ainfo.src_aid
202     ComlibArrayInfo ainfo;
203     
204     CharmStrategy() : Strategy() {
205         setType(GROUP_STRATEGY); 
206         forwardOnMigration = 0;
207         learner = NULL;
208         mflag = CmiFalse;
209     }
210
211     CharmStrategy(CkMigrateMessage *m) : Strategy(m){
212         learner = NULL;
213     }
214
215     //Set flag to optimize strategy for 
216     inline void setMulticast(){
217         mflag = CmiTrue;
218     }
219
220     //get the multicast flag
221     CmiBool getMulticast () {
222         return mflag;
223     }
224
225     //Called for each message
226     //Function inserts a Charm++ message
227     virtual void insertMessage(CharmMessageHolder *msg) {
228         CkAbort("Bummer Should Not come here:CharmStrategy is abstract\n");
229     }
230
231     //Removed the virtual!
232     //Charm strategies should not use Message Holder
233     void insertMessage(MessageHolder *msg);
234     
235     //Added a new call that is called after the strategy had be
236     //created on every processor.
237     //DOES NOT exist in Converse Strategies
238     virtual void beginProcessing(int nelements){}
239
240     //Added a new call that is called after the strategy had be
241     //created on every processor.  DOES NOT exist in Converse
242     //Strategies. Called when the strategy is deactivated, possibly as
243     //a result of a learning decision
244     virtual void finalizeProcessing(){}
245
246     //Called when a message is received in the strategy handler
247     virtual void handleMessage(void *msg) {}
248     
249     ComlibLearner *getLearner() {return learner;}
250     void setLearner(ComlibLearner *l) {learner = l;}
251     
252     virtual void pup(PUP::er &p);
253     PUPable_decl(CharmStrategy);
254
255     void setForwardOnMigration(int f) {
256         forwardOnMigration = f;
257     }
258     
259     int getForwardOnMigration() {
260         return forwardOnMigration;
261     }
262 };
263
264 //API calls which will be valid when communication library is not linked
265 void ComlibNotifyMigrationDone();
266 int ComlibGetLastKnown(CkArrayID aid, CkArrayIndexMax idx);
267
268 #endif