A few bug fixes related to the mlogft machine.
[charm.git] / src / ck-ldb / BaseLB.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9  \defgroup CkLdb  Charm++ Load Balancing Framework 
10 */
11 /*@{*/
12
13 #ifndef BASELB_H
14 #define BASELB_H
15
16 #include "LBDatabase.h"
17
18 #define PER_MESSAGE_SEND_OVERHEAD_DEFAULT   3.5e-5
19 #define PER_BYTE_SEND_OVERHEAD_DEFAULT      8.5e-9
20 #define PER_MESSAGE_RECV_OVERHEAD           0.0
21 #define PER_BYTE_RECV_OVERHEAD              0.0
22
23 /// Base class for all LB strategies.
24 /**
25   BaseLB is the base class for all LB strategy class.
26   it does some tracking about how many lb strategies are created.
27   it also defines some common functions.
28 */
29 class BaseLB: public CBase_BaseLB
30 {
31 protected:
32   int  seqno;
33   const char *lbname;
34   LBDatabase *theLbdb;
35   LDBarrierReceiver receiver;
36   int  notifier;
37   int  startLbFnHdl;
38 private:
39   void initLB(const CkLBOptions &);
40 public:
41   struct ProcStats {  // per processor data
42     int   n_objs;
43     int   pe_speed;
44     double total_walltime;
45     double total_cputime;
46     double idletime;
47     double bg_walltime;
48     double bg_cputime;
49     //double utilization;
50     int   pe;                   // proc #
51     CmiBool available;
52     ProcStats(): n_objs(0), pe_speed(1), 
53                  total_walltime(0.0), total_cputime(0.0), idletime(0.0),
54                  bg_walltime(0.0), bg_cputime(0.0), 
55                  pe(-1), available(CmiTrue)  {}
56     inline void clearBgLoad() {
57         idletime = bg_walltime = bg_cputime = 0.0;
58     }
59     inline void pup(PUP::er &p) {
60       p|total_walltime;  p|total_cputime; p|idletime;
61       p|bg_walltime; p|bg_cputime; p|pe_speed;
62       if (_lb_args.lbversion() < 1 && p.isUnpacking()) {
63          double dummy;  p|dummy;    // for old format with utilization
64       }
65       p|available; p|n_objs;
66       if (_lb_args.lbversion()>=2) p|pe; 
67     }
68   };
69
70   struct LDStats {  // Passed to Strategy
71     ProcStats  *procs;
72     int count; 
73     
74     int   n_objs;
75     int   n_migrateobjs;
76     CkVec<LDObjData> objData;
77     int   n_comm;
78     CkVec<LDCommData> commData;
79     CkVec<int>  from_proc, to_proc;
80
81     int *objHash; 
82     int  hashSize;
83
84     int complete_flag;          // if this ocg is complete, eg in HybridLB,
85                                 // this LDStats may not be complete
86
87     LDStats(int c=0, int complete_flag=1);
88     void assign(int oid, int pe) { CmiAssert(procs[pe].available); to_proc[oid] = pe; }
89       // build hash table
90     void makeCommHash();
91     void deleteCommHash();
92     int getHash(const LDObjKey &);
93     int getHash(const LDObjid &oid, const LDOMid &mid);
94     int getSendHash(LDCommData &cData);
95     int getRecvHash(LDCommData &cData);
96     void clearCommHash();
97     void clear() {
98       n_objs = n_comm = n_migrateobjs = 0;
99       objData.free();
100       commData.free();
101       from_proc.free();
102       to_proc.free();
103       deleteCommHash();
104     }
105     void clearBgLoad() {
106       for (int i=0; i<count; i++) procs[i].clearBgLoad();
107     }
108     void computeNonlocalComm(int &nmsgs, int &nbytes);
109     double computeAverageLoad();
110     void print();
111     // edit functions
112     void removeObject(int obj);
113     void pup(PUP::er &p);
114     int useMem();
115   };
116
117   BaseLB(const CkLBOptions &opt)  { initLB(opt); }
118   BaseLB(CkMigrateMessage *m):CBase_BaseLB(m) {}
119   virtual ~BaseLB();
120
121   void unregister(); 
122   inline const char *lbName() { return lbname; }
123   inline int step() { return theLbdb->step(); }
124   virtual void turnOff() { CmiAbort("turnOff not implemented"); }
125   virtual void turnOn()  { CmiAbort("turnOn not implemented"); }
126   virtual int  useMem()  { return 0; }
127   virtual void pup(PUP::er &p);
128   virtual void flushStates();
129 };
130
131 /// migration decision for an obj.
132 struct MigrateInfo {  
133     int index;   // object index in objData array
134     LDObjHandle obj;
135     int from_pe;
136     int to_pe;
137     int async_arrival;      // if an object is available for immediate migrate
138     MigrateInfo():  async_arrival(0) {}
139 };
140
141 /**
142   message contains the migration decision from LB strategies.
143 */
144 class LBMigrateMsg : public CMessage_LBMigrateMsg {
145 public:
146   int level;                    // which level in hierarchy, used in hybridLB
147
148   int n_moves;                  // number of moves
149   MigrateInfo* moves;
150
151   char * avail_vector;          // processor bit vector
152   int next_lb;                  // next load balancer
153
154   double * expectedLoad;        // expected load for future
155
156 public:
157 #ifdef _FAULT_MLOG_
158         int step;
159         int lbDecisionCount;
160 #endif
161   LBMigrateMsg(): level(0), n_moves(0), next_lb(0) {}
162 };
163
164 struct VectorMigrateInfo {  
165     int from_pe;
166     int to_pe;
167     double load;
168     int async_arrival;      // if an object is available for immediate migrate
169     VectorMigrateInfo():  async_arrival(0) {}
170 };
171
172 class LBVectorMigrateMsg : public CMessage_LBVectorMigrateMsg {
173 public:
174   int level;                    // which level in hierarchy, used in hybridLB
175
176   int n_moves;                  // number of moves
177   VectorMigrateInfo* moves;
178
179 public:
180   LBVectorMigrateMsg(): level(0), n_moves(0) {}
181 };
182
183 // for a FooLB, the following macro defines these functions for each LB:
184 // CreateFooLB():        create BOC and register with LBDatabase with a 
185 //                       sequence ticket,
186 // AllocateFooLB():      allocate the class instead of a BOC
187 // static void lbinit(): an init call for charm module registration
188 #if CMK_LBDB_ON
189
190 #define CreateLBFunc_Def(x, str)                \
191 void Create##x(void) {  \
192   int seqno = LBDatabaseObj()->getLoadbalancerTicket(); \
193   CProxy_##x::ckNew(CkLBOptions(seqno));        \
194 }       \
195 \
196 BaseLB *Allocate##x(void) { \
197   return new x((CkMigrateMessage*)NULL);        \
198 }       \
199 \
200 static void lbinit(void) {      \
201   LBRegisterBalancer(#x,        \
202                      Create##x, \
203                      Allocate##x,       \
204                      str);      \
205 }
206
207 #else           /* CMK_LBDB_ON */
208
209 #define CreateLBFunc_Def(x, str)        \
210 void Create##x(void) {}         \
211 BaseLB *Allocate##x(void) { return NULL; }      \
212 static void lbinit(void) {}
213
214 #endif          /* CMK_LBDB_ON */
215
216 #endif
217
218 /*@}*/