doc: Add serial to list of ci file reserved words
[charm.git] / src / ck-ldb / CentralLB.h
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #ifndef CENTRALLB_H
7 #define CENTRALLB_H
8
9 #include "BaseLB.h"
10 #include "CentralLB.decl.h"
11
12 extern CkGroupID loadbalancer;
13
14 void CreateCentralLB();
15
16 class CLBStatsMsg;
17 class LBSimulation;
18
19 /// for backward compatibility
20 typedef LBMigrateMsg  CLBMigrateMsg;
21
22 class LBInfo
23 {
24 public:
25   LBRealType *peLoads;  // total load: object + background
26   LBRealType *objLoads;         // total obj load
27   LBRealType *comLoads;         // total comm load
28   LBRealType *bgLoads;  // background load
29   int    numPes;
30   int    msgCount;      // total non-local communication
31   CmiUInt8  msgBytes;   // total non-local communication
32   LBRealType minObjLoad, maxObjLoad;
33   LBInfo(): peLoads(NULL), objLoads(NULL), comLoads(NULL), 
34             bgLoads(NULL), numPes(0), msgCount(0),
35             msgBytes(0), minObjLoad(0.0), maxObjLoad(0.0) {}
36   LBInfo(LBRealType *pl, int count): peLoads(pl), objLoads(NULL), 
37             comLoads(NULL), bgLoads(NULL), numPes(count), msgCount(0),
38             msgBytes(0), minObjLoad(0.0), maxObjLoad(0.0) {}
39   LBInfo(int count);
40   ~LBInfo();
41   void getInfo(BaseLB::LDStats* stats, int count, int considerComm);
42   void clear();
43   void print();
44   void getSummary(LBRealType &maxLoad, LBRealType &maxCpuLoad, LBRealType &totalLoad);
45 };
46
47 /** added by Abhinav
48  * class for computing the parent and children of a processor 
49  */
50 class SpanningTree
51 {
52         public:
53                 int arity;
54                 int parent;
55                 int numChildren;
56                 SpanningTree();
57                 void calcParent(int n);
58                 void calcNumChildren(int n);
59 };
60
61 class CentralLB : public BaseLB
62 {
63 private:
64   CLBStatsMsg *statsMsg;
65   int count_msgs;
66   void initLB(const CkLBOptions &);
67 public:
68   CkMarshalledCLBStatsMessage bufMsg;
69   SpanningTree st;
70   CentralLB(const CkLBOptions & opt):BaseLB(opt) { initLB(opt); 
71 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
72         lbDecisionCount= resumeCount=0;
73 #endif
74
75   CentralLB(CkMigrateMessage *m):BaseLB(m) {}
76   virtual ~CentralLB();
77
78   void pup(PUP::er &p);
79
80   void turnOn();
81   void turnOff();
82
83   static void staticAtSync(void*);
84   void AtSync(void); // Everything is at the PE barrier
85   void ProcessAtSync(void); // Receive a message from AtSync to avoid
86                             // making projections output look funny
87   void SendStats();
88   void ReceiveCounts(CkReductionMsg *);
89   void ReceiveStats(CkMarshalledCLBStatsMessage &msg);  // Receive stats on PE 0
90   void ReceiveStatsViaTree(CkMarshalledCLBStatsMessage &msg); // Receive stats using a tree structure  
91   
92   void depositData(CLBStatsMsg *m);
93   void LoadBalance(void); 
94   void ResumeClients(int);                      // Resuming clients needs
95
96   void ResumeClients(CkReductionMsg *); // to be resumed via message
97   void ReceiveMigration(LBMigrateMsg *);        // Receive migration data
98   void ProcessReceiveMigration(CkReductionMsg  *);
99 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
100         void ReceiveDummyMigration(int _step);
101 #endif
102   void MissMigrate(int waitForBarrier);
103
104   // manual predictor start/stop
105   static void staticPredictorOn(void* data, void* model);
106   static void staticPredictorOnWin(void* data, void* model, int wind);
107   static void staticPredictorOff(void* data);
108   static void staticChangePredictor(void* data, void* model);
109
110   // manual start load balancing
111   inline void StartLB() { thisProxy.ProcessAtSync(); }
112   static void staticStartLB(void* data);
113
114   // Migrated-element callback
115   static void staticMigrated(void* me, LDObjHandle h, int waitBarrier=1);
116   void Migrated(LDObjHandle h, int waitBarrier=1);
117
118   void MigrationDone(int balancing);  // Call when migration is complete
119   void CheckMigrationComplete();      // Call when all migration is complete
120
121   // IMPLEMENTATION FOR FUTURE PREDICTOR
122   void FuturePredictor(LDStats* stats);
123
124   struct FutureModel {
125     int n_stats;    // total number of statistics allocated
126     int cur_stats;   // number of statistics currently present
127     int start_stats; // next stat to be written
128     LDStats *collection;
129     int n_objs;     // each object has its own parameters
130     LBPredictorFunction *predictor;
131     double **parameters;
132     bool *model_valid;
133
134     FutureModel(): n_stats(0), cur_stats(0), start_stats(0), collection(NULL),
135          n_objs(0), parameters(NULL) {predictor = new DefaultFunction();}
136
137     FutureModel(int n): n_stats(n), cur_stats(0), start_stats(0), n_objs(0),
138          parameters(NULL) {
139       collection = new LDStats[n];
140       //for (int i=0;i<n;++i) collection[i].objData=NULL;
141       predictor = new DefaultFunction();
142     }
143
144     FutureModel(int n, LBPredictorFunction *myfunc): n_stats(n), cur_stats(0), start_stats(0), n_objs(0), parameters(NULL) {
145       collection = new LDStats[n];
146       //for (int i=0;i<n;++i) collection[i].objData=NULL;
147       predictor = myfunc;
148     }
149
150     ~FutureModel() {
151       delete[] collection;
152       for (int i=0;i<n_objs;++i) delete[] parameters[i];
153       delete[] parameters;
154       delete predictor;
155     }
156
157     void changePredictor(LBPredictorFunction *new_predictor) {
158       delete predictor;
159       int i;
160       // gain control of the provided predictor;
161       predictor = new_predictor;
162       for (i=0;i<n_objs;++i) delete[] parameters[i];
163       for (i=0;i<n_objs;++i) {
164         parameters[i] = new double[new_predictor->num_params];
165         model_valid[i] = false;
166       }
167     }
168   };
169
170   // create new predictor, if one already existing, delete it first
171   // if "pred" == 0 then the default function is used
172   void predictorOn(LBPredictorFunction *pred) {
173     predictorOn(pred, _lb_predict_window);
174   }
175   void predictorOn(LBPredictorFunction *pred, int window_size) {
176     if (predicted_model) {
177       PredictorPrintf("Predictor already allocated");
178     } else {
179       _lb_predict_window = window_size;
180       if (pred) predicted_model = new FutureModel(window_size, pred);
181       else predicted_model = new FutureModel(window_size);
182       _lb_predict = CmiTrue;
183     }
184     PredictorPrintf("Predictor turned on, window size %d\n",window_size);
185   }
186
187   // deallocate the predictor
188   void predictorOff() {
189     if (predicted_model) delete predicted_model;
190     predicted_model = 0;
191     _lb_predict = CmiFalse;
192     PredictorPrintf("Predictor turned off\n");
193   }
194
195   // change the function of the predictor, at runtime
196   // it will do nothing if it does not exist
197   void changePredictor(LBPredictorFunction *new_predictor) {
198     if (predicted_model) {
199       predicted_model->changePredictor(new_predictor);
200       PredictorPrintf("Predictor model changed\n");
201     }
202   }
203   // END IMPLEMENTATION FOR FUTURE PREDICTOR
204
205   LBMigrateMsg* callStrategy(LDStats* stats,int count){
206     return Strategy(stats);
207   };
208
209   int cur_ld_balancer;
210
211   void readStatsMsgs(const char* filename);
212   void writeStatsMsgs(const char* filename);
213
214   void preprocess(LDStats* stats);
215   virtual LBMigrateMsg* Strategy(LDStats* stats);
216   virtual void work(LDStats* stats);
217   virtual LBMigrateMsg * createMigrateMsg(LDStats* stats);
218   virtual LBMigrateMsg * extractMigrateMsg(LBMigrateMsg *m, int p);
219
220   // Not to be used -- maintained for legacy applications
221   virtual LBMigrateMsg* Strategy(LDStats* stats, int nprocs) {
222     return Strategy(stats);
223   }
224
225 protected:
226   virtual CmiBool QueryBalanceNow(int) { return CmiTrue; };  
227   virtual CmiBool QueryDumpData() { return CmiFalse; };  
228   virtual void LoadbalanceDone(int balancing) {}
229
230   void simulationRead();
231   void simulationWrite();
232   void findSimResults(LDStats* stats, int count, 
233                       LBMigrateMsg* msg, LBSimulation* simResults);
234   void removeNonMigratable(LDStats* statsDataList, int count);
235
236 private:  
237   CProxy_CentralLB thisProxy;
238   int myspeed;
239   int stats_msg_count;
240   CLBStatsMsg **statsMsgsList;
241   LDStats *statsData;
242   int migrates_completed;
243   int migrates_expected;
244   int future_migrates_completed;
245   int future_migrates_expected;
246   int lbdone;
247   double start_lb_time;
248   LBMigrateMsg   *storedMigrateMsg;
249   int  reduction_started;
250
251
252   FutureModel *predicted_model;
253
254   void BuildStatsMsg();
255   void buildStats();
256
257 public:
258   int useMem();
259 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
260     int savedBalancing;
261     void endMigrationDone(int balancing);
262     int lbDecisionCount ,resumeCount;
263 #endif
264 };
265
266 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_)) 
267     void resumeCentralLbAfterChkpt(void *lb);
268         void resumeAfterRestoreParallelRecovery(void *_lb);
269 #endif
270
271 // CLBStatsMsg is not directly sent in the entry function
272 // CkMarshalledCLBStatsMessage is used instead to use the pup defined here.
273 //class CLBStatsMsg: public CMessage_CLBStatsMsg {
274 class CLBStatsMsg {
275 public:
276   int from_pe;
277   int pe_speed;
278   LBRealType total_walltime;
279   LBRealType idletime;
280   LBRealType bg_walltime;
281 #if CMK_LB_CPUTIMER
282   LBRealType total_cputime;
283   LBRealType bg_cputime;
284 #endif
285   int n_objs;
286   LDObjData *objData;
287   int n_comm;
288   LDCommData *commData;
289
290   char * avail_vector;
291   int next_lb;
292 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
293         int step;
294 #endif
295
296 public:
297   CLBStatsMsg(int osz, int csz);
298   CLBStatsMsg(): from_pe(0), pe_speed(0), total_walltime(0.0), idletime(0.0),
299                  bg_walltime(0.0), n_objs(0), objData(NULL), n_comm(0),
300 #if CMK_LB_CPUTIMER
301                  total_cputime(0.0), bg_cputime(0.0),
302 #endif
303                  commData(NULL), avail_vector(NULL), next_lb(0) {}
304   ~CLBStatsMsg();
305   void pup(PUP::er &p);
306 }; 
307
308
309 // compute load distribution info
310 void getLoadInfo(BaseLB::LDStats* stats, int count, LBInfo &info, int considerComm);
311
312 #endif /* CENTRALLB_H */
313
314 /*@}*/
315
316