fix of the MultiRingMulticast strategy
[charm.git] / src / ck-com / ComlibManager.h
1 #ifndef COMMLIBMANAGER_H
2 #define COMMLIBMANAGER_H
3
4 #include "charm++.h"
5 #include "cksection.h"
6 #include "envelope.h"
7 #include "comlib.h"
8 #include <math.h>
9
10 #include "charm++.h"
11 #include "convcomlibmanager.h"
12
13 #define USE_TREE 1            //Organizes the all to all as a tree
14 #define USE_MESH 2            //Virtual topology is a mesh here
15 #define USE_HYPERCUBE 3       //Virtual topology is a hypercube
16 #define USE_DIRECT 4          //A dummy strategy that directly forwards 
17                               //messages without any processing.
18 #define USE_GRID 5            //Virtual topology is a 3d grid
19 #define USE_LINEAR 6          //Virtual topology is a linear array
20 #define USE_PREFIX 7          //Prefix router to avoid contention
21
22 #define CHARM_MPI 0 
23 #define MAX_NSTRAT 1024
24 #define LEARNING_PERIOD 1000 //Number of iterations after which the
25                              //learning framework will discover 
26                              //the appropriate strategy, not completely 
27                              //implemented
28 PUPbytes(comID);
29
30 #include "ComlibStats.h"
31
32 #include "comlib.decl.h"
33
34 //Dummy message to be sent incase there are no messages to send. 
35 //Used by only the EachToMany strategy!
36 class ComlibDummyMsg: public CMessage_ComlibDummyMsg {
37     int dummy;
38 };
39
40 /*
41 //Priority message to call end iteration
42 class PrioMsg: public CMessage_PrioMsg {
43  public:
44     int instID;
45 };
46 */
47
48 /**
49  * Structure used to hold a count of the indeces associated to each pe in a multicast message.
50  */
51 struct ComlibMulticastIndexCount {
52   int pe;
53   int count;
54 };
55
56 ///for use of qsort
57 inline int indexCountCompare(const void *a, const void *b) {
58   ComlibMulticastIndexCount a1 = *(ComlibMulticastIndexCount*) a;
59   ComlibMulticastIndexCount b1 = *(ComlibMulticastIndexCount*) b;
60
61   if(a1.pe < b1.pe)
62     return -1;
63   
64   if(a1.pe == b1.pe)
65     return 0;
66   
67   if(a1.pe > b1.pe)
68     return 1;
69   
70   return 0;
71 }
72
73 class ComlibMulticastMsg : public CkMcastBaseMsg, 
74                public CMessage_ComlibMulticastMsg {
75     
76   public:
77     int nPes;
78     ComlibMulticastIndexCount *indicesCount;
79     CkArrayIndexMax *indices;
80     char *usrMsg;        
81 };
82
83 class ComlibManager;
84
85 //An Instance of the communication library.
86 class ComlibInstanceHandle : public CkDelegateData {
87  private:    
88     int _instid;
89     CkGroupID _dmid;
90     int _srcPe;
91     int toForward;
92
93  public:
94     ComlibInstanceHandle();
95     ComlibInstanceHandle(const ComlibInstanceHandle &h);
96     ComlibInstanceHandle(int instid, CkGroupID dmid);    
97    
98     ComlibInstanceHandle &operator=(const ComlibInstanceHandle &h);
99
100     void setForwardingOnMigration(){toForward = 1;} 
101     void beginIteration();
102     void endIteration();
103     
104     CkGroupID getComlibManagerID();
105     void setStrategy(CharmStrategy *);
106     CharmStrategy *getStrategy();        
107     int getSourcePe() {return _srcPe;}
108
109     void setSourcePe() {_srcPe = CkMyPe();}
110
111     friend class ComlibManager;
112     void pup(PUP::er &p) {
113
114         if(p.isUnpacking())
115              reset();        
116
117         p | _instid;
118         p | _dmid;
119         p | _srcPe;
120         p | toForward;
121     }
122 };
123
124 class LBMigrateMsg;
125
126 class ComlibManager: public CkDelegateMgr {
127     friend class ComlibInstanceHandle;
128
129     int *bcast_pelist;  //Pelist passed to all broadcast operations
130
131     int section_send_event;
132
133     int remotePe;
134     CmiBool isRemote;
135     CmiBool strategyCreated;
136
137     int npes;
138     int *pelist;
139
140     CkArrayIndexMax dummyArrayIndex;
141
142     //For compatibility and easier use!
143     int strategyID; //Identifier of the strategy
144
145     //Pointer to the converse comm lib strategy table
146     StrategyTable *strategyTable;
147
148     CkQ<CharmStrategy *> ListOfStrategies; //temporary list of strategies
149     
150     CkQ<CharmMessageHolder *> remoteQ;  //list of remote messages
151                                         //after the object has
152                                         //migrated
153
154     //The number of strategies created by the user
155     //int nstrats; //now part of conv comlib
156     
157     int curStratID, prevStratID;      
158     //Number of strategies created by the user.
159
160     //flags
161     int receivedTable, setupComplete, barrierReached, barrier2Reached;
162     CmiBool lbUpdateReceived;
163
164     int bcount , b2count;
165     //int totalMsgCount, totalBytes, nIterations;
166
167     ComlibArrayListener *alistener;
168     int prioEndIterationFlag;
169
170     ComlibGlobalStats clib_gstats; 
171     int    numStatsReceived;
172
173     int curComlibController;   //Processor where strategies are  recreated
174     int clibIteration;         //Number of such learning iterations,
175                                //each of which is triggered by a
176                                //loadbalancing operation
177
178     void init(); //initialization function
179
180     //charm_message for multicast for a section of that group
181     void multicast(CharmMessageHolder *cmsg); //charm message holder here
182     //void multicast(void *charm_msg, int npes, int *pelist);
183
184     //The following funtions can be accessed only from ComlibInstanceHandle
185     void beginIteration();     //Notify begining of a bracket with
186                                //strategy identifier
187
188     void endIteration();       //Notify end, endIteration must be
189                                //called if a beginIteration is
190                                //called. Otherwise end of the entry
191                                //method is assumed to be the end of
192                                //the bracket.
193     
194     void setInstance(int id); 
195
196     //void prioEndIteration(PrioMsg *pmsg);
197     void registerStrategy(int pos, CharmStrategy *s);
198
199  public:
200
201     ComlibLocalStats clib_stats;   //To store statistics of
202                                    //communication operations
203     
204     ComlibManager();  //Recommended constructor
205
206     ComlibManager(CkMigrateMessage *m) { }
207     int useDefCtor(void){ return 1; } //Use default constructor should
208     //be pupped and store all the strategies.
209     
210     void barrier(void);
211     void barrier2(void);
212     void resumeFromBarrier2(void);
213
214     //Receive table of strategies.
215     void receiveTable(StrategyWrapper &sw, 
216                       CkHashtableT <ClibGlobalArrayIndex, int>&); 
217
218     void ArraySend(CkDelegateData *pd,int ep, void *msg, 
219                    const CkArrayIndexMax &idx, CkArrayID a);
220
221     void receiveRemoteSend(CkQ<CharmMessageHolder*> &rq, int id);
222     void sendRemote();
223
224     void GroupSend(CkDelegateData *pd, int ep, void *msg, int onpe, 
225                    CkGroupID gid);
226     
227     virtual void ArrayBroadcast(CkDelegateData *pd,int ep,void *m,CkArrayID a);
228     virtual void GroupBroadcast(CkDelegateData *pd,int ep,void *m,CkGroupID g);
229     virtual void ArraySectionSend(CkDelegateData *pd, int ep ,void *m, 
230                                   CkArrayID a, CkSectionID &s, int opts);
231
232     CharmStrategy *getStrategy(int instid)
233         {return (CharmStrategy *)(* strategyTable)[instid].strategy;}
234
235     StrategyTableEntry *getStrategyTableEntry(int instid)
236         {return &((*strategyTable)[instid]);}
237
238     //To create a new strategy, returns handle to the strategy table;
239     ComlibInstanceHandle createInstance();  
240     void broadcastStrategies();             //Done creating instances
241
242     void AtSync();           //User program called loadbalancer
243     void lbUpdate(LBMigrateMsg *); //loadbalancing updates
244
245     //Learning functions
246     //void learnPattern(int totalMessageCount, int totalBytes);
247     //void switchStrategy(int strat);
248
249     void setRemote(int remotePe);
250
251     void collectStats(ComlibLocalStats &s, int src,CkVec<ClibGlobalArrayIndex>&);
252
253     //Returns the processor on which the comlib sees the array element
254     //belonging to
255     inline int getLastKnown(CkArrayID a, CkArrayIndexMax &idx) {
256         return ComlibGetLastKnown(a, idx);
257     }
258
259     CkDelegateData* ckCopyDelegateData(CkDelegateData *data); 
260     CkDelegateData *DelegatePointerPup(PUP::er &p,CkDelegateData *pd);
261 };
262
263 void ComlibDelegateProxy(CProxy *proxy);
264 void ComlibAssociateProxy(CharmStrategy *strat, CProxy &proxy); 
265 void ComlibBegin(CProxy &proxy);    
266 void ComlibEnd(CProxy &proxy);    
267
268 ComlibInstanceHandle CkCreateComlibInstance();
269 ComlibInstanceHandle CkGetComlibInstance();
270 ComlibInstanceHandle CkGetComlibInstance(int id);
271
272 void ComlibResetSectionProxy(CProxySection_ArrayBase *sproxy);
273
274 inline void ComlibResetProxy(CProxy *aproxy) {
275   ComlibInstanceHandle *handle = 
276     (ComlibInstanceHandle *) aproxy->ckDelegatedPtr();
277   handle->setSourcePe();
278 }
279
280 //Only Called when the strategies are not being created in main::main
281 void ComlibDoneCreating(); 
282
283 void ComlibInitSectionID(CkSectionID &sid);
284
285 void ComlibAtSync(void *msg);
286 void ComlibNotifyMigrationDoneHandler(void *msg);
287 void ComlibLBMigrationUpdate(LBMigrateMsg *);
288
289 #define RECORD_SEND_STATS(sid, bytes, dest) {             \
290         CProxy_ComlibManager cgproxy(CkpvAccess(cmgrID));               \
291         cgproxy.ckLocalBranch()->clib_stats.recordSend(sid, bytes, dest); \
292 }\
293
294 #define RECORD_RECV_STATS(sid, bytes, src) { \
295         CProxy_ComlibManager cgproxy(CkpvAccess(cmgrID)); \
296         cgproxy.ckLocalBranch()->clib_stats.recordRecv(sid, bytes, src); \
297 }\
298
299 #define RECORD_SENDM_STATS(sid, bytes, dest_arr, ndest) {       \
300         CProxy_ComlibManager cgproxy(CkpvAccess(cmgrID)); \
301         cgproxy.ckLocalBranch()->clib_stats.recordSendM(sid, bytes, dest_arr, ndest); \
302 }\
303
304 #define RECORD_RECVM_STATS(sid, bytes, src_arr, nsrc) {        \
305         CProxy_ComlibManager cgproxy(CkpvAccess(cmgrID)); \
306         cgproxy.ckLocalBranch()->clib_stats.recordRecvM(sid, bytes, src_arr, nsrc); \
307 }\
308
309 #endif