added a callback functionality at the end of an iteration
[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     CkCallback onFinish;
196
197  public:
198     ComlibGroupInfo ginfo;
199     ComlibNodeGroupInfo nginfo;
200
201     //The communication library array listener watches and monitors
202     //the array elements belonging to ainfo.src_aid
203     ComlibArrayInfo ainfo;
204     
205     CharmStrategy() : Strategy() {
206         setType(GROUP_STRATEGY); 
207         forwardOnMigration = 0;
208         learner = NULL;
209         mflag = CmiFalse;
210     }
211
212     CharmStrategy(CkMigrateMessage *m) : Strategy(m){
213         learner = NULL;
214     }
215
216     //Set flag to optimize strategy for 
217     inline void setMulticast(){
218         mflag = CmiTrue;
219     }
220
221     //get the multicast flag
222     CmiBool getMulticast () {
223         return mflag;
224     }
225
226     inline void setOnFinish (CkCallback of) {
227       onFinish = of;
228     }
229
230     inline CkCallback getOnFinish () {
231       return onFinish;
232     }
233
234     //Called for each message
235     //Function inserts a Charm++ message
236     virtual void insertMessage(CharmMessageHolder *msg) {
237         CkAbort("Bummer Should Not come here:CharmStrategy is abstract\n");
238     }
239
240     //Removed the virtual!
241     //Charm strategies should not use Message Holder
242     void insertMessage(MessageHolder *msg);
243     
244     //Added a new call that is called after the strategy had be
245     //created on every processor.
246     //DOES NOT exist in Converse Strategies
247     virtual void beginProcessing(int nelements){}
248
249     //Added a new call that is called after the strategy had be
250     //created on every processor.  DOES NOT exist in Converse
251     //Strategies. Called when the strategy is deactivated, possibly as
252     //a result of a learning decision
253     virtual void finalizeProcessing(){}
254
255     //Called when a message is received in the strategy handler
256     virtual void handleMessage(void *msg) {
257         CkPrintf("Warning: In CharmStrategy::handleMessage\n");
258         CkPrintf("Did you corrupt the message ????\n");
259     }
260     
261     ComlibLearner *getLearner() {return learner;}
262     void setLearner(ComlibLearner *l) {learner = l;}
263     
264     virtual void pup(PUP::er &p);
265     PUPable_decl(CharmStrategy);
266
267     void setForwardOnMigration(int f) {
268         forwardOnMigration = f;
269     }
270     
271     int getForwardOnMigration() {
272         return forwardOnMigration;
273     }
274 };
275
276 //API calls which will be valid when communication library is not linked
277 void ComlibNotifyMigrationDone();
278 int ComlibGetLastKnown(CkArrayID aid, CkArrayIndexMax idx);
279
280 #endif