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