00001 
00005 
00006 #ifndef BASELB_H
00007 #define BASELB_H
00008 
00009 #include "LBDatabase.h"
00010 
00011 #define PER_MESSAGE_SEND_OVERHEAD_DEFAULT   3.5e-5
00012 #define PER_BYTE_SEND_OVERHEAD_DEFAULT      8.5e-9
00013 #define PER_MESSAGE_RECV_OVERHEAD       0.0
00014 #define PER_BYTE_RECV_OVERHEAD              0.0
00015 
00017 
00022 class BaseLB: public CBase_BaseLB
00023 {
00024 protected:
00025   int  seqno;
00026   const char *lbname;
00027   LBDatabase *theLbdb;
00028   LDBarrierReceiver receiver;
00029   int  notifier;
00030   int  startLbFnHdl;
00031 private:
00032   void initLB(const CkLBOptions &);
00033 public:
00034   struct ProcStats {        
00035     int n_objs;         
00036     double pe_speed;        
00037 #if defined(TEMP_LDB)
00038     float pe_temp;
00039 #endif
00040 
00045     double total_walltime;
00047     double idletime;
00050     double bg_walltime;
00051 #if CMK_LB_CPUTIMER
00052     double total_cputime;
00053     double bg_cputime;
00054 #endif
00055     
00056     int pe;         
00057     bool available;
00058     ProcStats(): n_objs(0), pe_speed(1), total_walltime(0.0), idletime(0.0),
00059 #if CMK_LB_CPUTIMER
00060          total_cputime(0.0), bg_cputime(0.0),
00061 #endif
00062          bg_walltime(0.0), pe(-1), available(true) {}
00063     inline void clearBgLoad() {
00064       idletime = bg_walltime = 
00065 #if CMK_LB_CPUTIMER
00066       bg_cputime = 
00067 #endif
00068       0.0;
00069     }
00070     inline void pup(PUP::er &p) {
00071       p|total_walltime;
00072       p|idletime;
00073       p|bg_walltime;
00074 #if CMK_LB_CPUTIMER
00075       p|total_cputime;
00076       p|bg_cputime;
00077 #endif
00078       p|pe_speed;
00079       if (_lb_args.lbversion() < 1 && p.isUnpacking()) {
00080          double dummy;  p|dummy;    
00081       }
00082       p|available; p|n_objs;
00083       if (_lb_args.lbversion()>=2) p|pe; 
00084     }
00085   };
00086 
00088   struct LDStats {
00089     int count;          
00090     ProcStats *procs;       
00091 
00092     int n_objs;         
00093     int n_migrateobjs;      
00094     CkVec<LDObjData> objData;   
00095     CkVec<int> from_proc;   
00096     CkVec<int> to_proc;     
00097 
00098     int n_comm;         
00099     CkVec<LDCommData> commData; 
00100                 
00101 
00102     int *objHash;       
00103                 
00104     int  hashSize;
00105 
00106     int complete_flag;      
00107     
00108 
00109     int is_prev_lb_refine;
00110     double after_lb_max;
00111     double after_lb_avg;
00112 
00113     LDStats(int c=0, int complete_flag=1);
00116     inline int nprocs() const { return count; }
00117     inline int &nprocs() { return count; }
00118 
00119     void assign(int oid, int pe) { CmiAssert(procs[pe].available); to_proc[oid] = pe; }
00121     void makeCommHash();
00122     void deleteCommHash();
00125     int getHash(const LDObjKey &);
00126     int getHash(const CmiUInt8 &oid, const LDOMid &mid);
00127     int getSendHash(LDCommData &cData);
00128     int getRecvHash(LDCommData &cData);
00129     void clearCommHash();
00130     void clear() {
00131       n_objs = n_migrateobjs = n_comm = 0;
00132       objData.free();
00133       commData.free();
00134       from_proc.free();
00135       to_proc.free();
00136       deleteCommHash();
00137     }
00138     void clearBgLoad() {
00139       for (int i=0; i<nprocs(); i++) procs[i].clearBgLoad();
00140     }
00141     void computeNonlocalComm(int &nmsgs, int &nbytes);
00142     double computeAverageLoad();
00143     void normalize_speed();
00144     void print();
00145     
00146     void removeObject(int obj);
00147     void pup(PUP::er &p);
00148     int useMem();
00149   };
00150 
00151   BaseLB(const CkLBOptions &opt)  { initLB(opt); }
00152   BaseLB(CkMigrateMessage *m):CBase_BaseLB(m) {
00153     theLbdb = CProxy_LBDatabase(_lbdb).ckLocalBranch();
00154   }
00155   virtual ~BaseLB();
00156 
00157   void unregister(); 
00158   inline const char *lbName() { return lbname; }
00159   inline int step() { return theLbdb->step(); }
00160   virtual void turnOff() { CmiAbort("turnOff not implemented"); }
00161   virtual void turnOn()  { CmiAbort("turnOn not implemented"); }
00162   virtual int  useMem()  { return 0; }
00163   virtual void pup(PUP::er &p);
00164   virtual void flushStates();
00165 
00166   CkGroupID getGroupID() {return thisgroup;}
00167 };
00168 
00170 struct MigrateInfo {  
00171     int index;   
00172     LDObjHandle obj;
00173     int from_pe;
00174     int to_pe;
00175     int async_arrival;      
00176     MigrateInfo():  async_arrival(0) {
00177     }
00178 
00179     void pup(PUP::er &p) {
00180       p | index;
00181       p | obj;
00182       p | from_pe;
00183       p | to_pe;
00184       p | async_arrival;
00185     }
00186 };
00187 
00188 struct MigrateDecision {
00189   LDObjIndex dbIndex;
00190   int fromPe;
00191   int toPe;
00192 
00193   MigrateDecision &operator=(const MigrateInfo &mInfo) {
00194     dbIndex = mInfo.obj.handle;
00195     fromPe = mInfo.from_pe;
00196     toPe = mInfo.to_pe;
00197 
00198     return *this;
00199   }
00200 
00201 };
00202 
00203 class LBScatterMsg : public CMessage_LBScatterMsg {
00204 public:
00205   int numMigrates;
00206   int firstPeInSpan;
00207   int lastPeInSpan;
00208   int *numMigratesPerPe;
00209   MigrateDecision *moves;
00210 
00211   LBScatterMsg(int firstPe, int lastPe) {
00212     numMigrates = 0;
00213     firstPeInSpan = firstPe;
00214     lastPeInSpan = lastPe;
00215   }
00216 };
00217 
00218 
00219 
00223 class LBMigrateMsg : public CMessage_LBMigrateMsg {
00224 public:
00225   int level;            
00226 
00227   int n_moves;          
00228   MigrateInfo* moves;
00229 
00230   char * avail_vector;      
00231   int next_lb;          
00232 
00233   double * expectedLoad;    
00234 
00235 public:
00236 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00237     int step;
00238     int lbDecisionCount;
00239 #endif
00240   LBMigrateMsg(): level(0), n_moves(0), next_lb(0) {}
00241   void pup(PUP::er &p) {
00242     int i;
00243     p | level;
00244     p | n_moves;
00245     
00246     
00247     p | next_lb;
00248     int numPes = CkNumPes();
00249     p | numPes;
00250     CkAssert(numPes == CkNumPes());
00251     for (i=0; i<n_moves; ++i) p | moves[i];
00252     p(avail_vector, numPes);
00253     for (i=0; i<numPes; ++i) p | expectedLoad[i];
00254   }
00255 };
00256 
00257 struct VectorMigrateInfo {  
00258     int from_pe;
00259     int to_pe;
00260     double load;
00261     int async_arrival;      
00262     VectorMigrateInfo():  async_arrival(0) {}
00263 };
00264 
00265 class LBVectorMigrateMsg : public CMessage_LBVectorMigrateMsg {
00266 public:
00267   int level;            
00268 
00269   int n_moves;          
00270   VectorMigrateInfo* moves;
00271 
00272 public:
00273   LBVectorMigrateMsg(): level(0), n_moves(0) {}
00274 };
00275 
00276 
00277 
00278 
00279 
00280 
00281 #if CMK_LBDB_ON
00282 
00283 #define CreateLBFunc_Def(x, str)        \
00284 void Create##x(void) {  \
00285   int seqno = LBDatabaseObj()->getLoadbalancerTicket(); \
00286   CProxy_##x::ckNew(CkLBOptions(seqno));    \
00287 }   \
00288 \
00289 BaseLB *Allocate##x(void) { \
00290   return new x((CkMigrateMessage*)NULL);    \
00291 }   \
00292 \
00293 static void lbinit(void) {  \
00294   LBRegisterBalancer(#x,    \
00295                      Create##x, \
00296                      Allocate##x,   \
00297                      str);  \
00298 }
00299 
00300 #else       
00301 
00302 #define CreateLBFunc_Def(x, str)    \
00303 void Create##x(void) {}     \
00304 BaseLB *Allocate##x(void) { return NULL; }  \
00305 static void lbinit(void) {}
00306 
00307 #endif      
00308 
00309 #endif
00310