00001 
00005 
00006 #include "converse.h"
00007 
00008 
00009 
00010 
00011 
00012 #include "LBDatabase.h"
00013 #include "LBSimulation.h"
00014 #include "topology.h"
00015 #include "DistributedLB.h"
00016 
00017 #include "NullLB.h"
00018 
00019 CkGroupID _lbdb;
00020 
00021 CkpvDeclare(LBUserDataLayout, lbobjdatalayout);
00022 CkpvDeclare(int, _lb_obj_index);
00023 
00024 CkpvDeclare(int, numLoadBalancers);  
00025 CkpvDeclare(bool, hasNullLB);         
00026 CkpvDeclare(bool, lbdatabaseInited);  
00028 
00029 CkLBArgs _lb_args;
00030 int _lb_predict=0;
00031 int _lb_predict_delay=10;
00032 int _lb_predict_window=20;
00033 bool _lb_psizer_on = false;
00034 
00035 
00036 class LBDBRegistry {
00037 friend class LBDBInit;
00038 friend class LBDatabase;
00039 private:
00040   
00041   struct LBDBEntry {
00042     const char *name;
00043     LBCreateFn  cfn;
00044     LBAllocFn   afn;
00045     const char *help;
00046     int     shown;      
00047     LBDBEntry(): name(0), cfn(0), afn(0), help(0), shown(1) {}
00048     LBDBEntry(int) {}
00049     LBDBEntry(const char *n, LBCreateFn cf, LBAllocFn af,
00050               const char *h, int show=1):
00051       name(n), cfn(cf), afn(af), help(h), shown(show) {};
00052   };
00053   CkVec<LBDBEntry> lbtables;        
00054   CkVec<const char *>   compile_lbs;    
00055   CkVec<const char *>   runtime_lbs;    
00056 public:
00057   LBDBRegistry() {}
00058   void displayLBs()
00059   {
00060     CmiPrintf("\nAvailable load balancers:\n");
00061     for (int i=0; i<lbtables.length(); i++) {
00062       LBDBEntry &entry = lbtables[i];
00063       if (entry.shown) CmiPrintf("* %s: %s\n", entry.name, entry.help);
00064     }
00065     CmiPrintf("\n");
00066   }
00067   void addEntry(const char *name, LBCreateFn fn, LBAllocFn afn, const char *help, int shown) {
00068     lbtables.push_back(LBDBEntry(name, fn, afn, help, shown));
00069   }
00070   void addCompiletimeBalancer(const char *name) {
00071     compile_lbs.push_back(name);
00072   }
00073   void addRuntimeBalancer(const char *name) {
00074     runtime_lbs.push_back(name);
00075   }
00076   LBCreateFn search(const char *name) {
00077     char *ptr = strpbrk((char *)name, ":,");
00078     int slen = ptr!=NULL?ptr-name:strlen(name);
00079     for (int i=0; i<lbtables.length(); i++)
00080       if (0==strncmp(name, lbtables[i].name, slen)) return lbtables[i].cfn;
00081     return NULL;
00082   }
00083   LBAllocFn getLBAllocFn(const char *name) {
00084     char *ptr = strpbrk((char *)name, ":,");
00085     int slen = ptr-name;
00086     for (int i=0; i<lbtables.length(); i++)
00087       if (0==strncmp(name, lbtables[i].name, slen)) return lbtables[i].afn;
00088     return NULL;
00089   }
00090 };
00091 
00092 static LBDBRegistry lbRegistry;
00093 
00094 void LBDefaultCreate(const char *lbname)
00095 {
00096   lbRegistry.addCompiletimeBalancer(lbname);
00097 }
00098 
00099 
00100 void LBRegisterBalancer(const char *name, LBCreateFn fn, LBAllocFn afn, const char *help, int shown)
00101 {
00102   lbRegistry.addEntry(name, fn, afn, help, shown);
00103 }
00104 
00105 LBAllocFn getLBAllocFn(const char *lbname) {
00106     return lbRegistry.getLBAllocFn(lbname);
00107 }
00108 
00109 
00110 static void createLoadBalancer(const char *lbname)
00111 {
00112     LBCreateFn fn = lbRegistry.search(lbname);
00113     if (!fn) {    
00114       CmiPrintf("Abort: Unknown load balancer: '%s'!\n", lbname);
00115       lbRegistry.displayLBs();    
00116       CkAbort("Abort");
00117     }
00118     
00119     fn();
00120 }
00121 
00122 
00123 LBDBInit::LBDBInit(CkArgMsg *m)
00124 {
00125 #if CMK_LBDB_ON
00126   _lbdb = CProxy_LBDatabase::ckNew();
00127 
00128   
00129   if (lbRegistry.runtime_lbs.size() > 0) {
00130     for (int i=0; i<lbRegistry.runtime_lbs.size(); i++) {
00131       const char *balancer = lbRegistry.runtime_lbs[i];
00132       createLoadBalancer(balancer);
00133     }
00134   }
00135   else if (lbRegistry.compile_lbs.size() > 0) {
00136     for (int i=0; i<lbRegistry.compile_lbs.size(); i++) {
00137       const char* balancer = lbRegistry.compile_lbs[i];
00138       createLoadBalancer(balancer);
00139     }
00140   }
00141   else {
00142     
00143     
00144     
00145     
00146     createLoadBalancer("NullLB");
00147   }
00148 
00149   
00150   if (LBSimulation::doSimulation) {
00151     CmiPrintf("Charm++> Entering Load Balancer Simulation Mode ... \n");
00152     CProxy_LBDatabase(_lbdb).ckLocalBranch()->StartLB();
00153   }
00154 #endif
00155   delete m;
00156 }
00157 
00158 
00159 void _loadbalancerInit()
00160 {
00161   CkpvInitialize(bool, lbdatabaseInited);
00162   CkpvAccess(lbdatabaseInited) = false;
00163   CkpvInitialize(int, numLoadBalancers);
00164   CkpvAccess(numLoadBalancers) = 0;
00165   CkpvInitialize(bool, hasNullLB);
00166   CkpvAccess(hasNullLB) = false;
00167 
00168   CkpvInitialize(LBUserDataLayout, lbobjdatalayout);
00169   CkpvInitialize(int, _lb_obj_index);
00170   CkpvAccess(_lb_obj_index) = -1;
00171 
00172   char **argv = CkGetArgv();
00173   char *balancer = NULL;
00174   CmiArgGroup("Charm++","Load Balancer");
00175 
00176   
00177   _lb_args.metaLbOn() = CmiGetArgFlagDesc(argv, "+MetaLB", "Turn on MetaBalancer");
00178   CmiGetArgStringDesc(argv, "+MetaLBModelDir", &_lb_args.metaLbModelDir(),
00179                       "Use this directory to read model for MetaLB");
00180 
00181   if (_lb_args.metaLbOn() && _lb_args.metaLbModelDir() != nullptr) {
00182 #if CMK_USE_ZLIB
00183     if (CkMyRank() == 0) {
00184       lbRegistry.addRuntimeBalancer("GreedyLB");
00185       lbRegistry.addRuntimeBalancer("GreedyRefineLB");
00186       lbRegistry.addRuntimeBalancer("DistributedLB");
00187       lbRegistry.addRuntimeBalancer("RefineLB");
00188       lbRegistry.addRuntimeBalancer("HybridLB");
00189       lbRegistry.addRuntimeBalancer("MetisLB");
00190       if (CkMyPe() == 0) {
00191         if (CmiGetArgStringDesc(argv, "+balancer", &balancer, "Use this load balancer"))
00192           CkPrintf(
00193               "Warning: Ignoring the +balancer option, since Meta-Balancer's model-based "
00194               "load balancer selection is enabled.\n");
00195         CkPrintf(
00196             "Warning: Automatic strategy selection in MetaLB is activated. This is an "
00197             "experimental feature.\n");
00198       }
00199       while (CmiGetArgStringDesc(argv, "+balancer", &balancer, "Use this load balancer"))
00200         ;
00201     }
00202 #else
00203     if (CkMyPe() == 0)
00204       CkAbort("MetaLB random forest model not supported because Charm++ was built without zlib support.\n");
00205 #endif
00206   } else {
00207     if (CkMyPe() == 0 && _lb_args.metaLbOn())
00208       CkPrintf(
00209           "Warning: MetaLB is activated. For Automatic strategy selection in MetaLB, "
00210           "pass directory of model files using +MetaLBModelDir.\n");
00211     while (CmiGetArgStringDesc(argv, "+balancer", &balancer, "Use this load balancer")) {
00212       if (CkMyRank() == 0)
00213         lbRegistry.addRuntimeBalancer(balancer); 
00214     }
00215   }
00216 
00217   CmiGetArgDoubleDesc(argv,"+DistLBTargetRatio", &_lb_args.targetRatio(),"The max/avg load ratio that DistributedLB will attempt to achieve");
00218   CmiGetArgIntDesc(argv,"+DistLBMaxPhases", &_lb_args.maxDistPhases(),"The maximum number of phases that DistributedLB will attempt");
00219 
00220   
00221   
00222   CmiGetArgDoubleDesc(argv,"+LBPeriod", &_lb_args.lbperiod(),"the minimum time period in seconds allowed for two consecutive automatic load balancing");
00223   _lb_args.loop() = CmiGetArgFlagDesc(argv, "+LBLoop", "Use multiple load balancing strategies in loop");
00224 
00225   
00226   
00227   CmiGetArgStringDesc(argv, "+LBTopo", &_lbtopo, "define load balancing topology");
00228   
00229   CmiGetArgIntDesc(argv, "+LBPercentMoves", &_lb_args.percentMovesAllowed() , "Percentage of chares to be moved (used by RefineKLB and GreedyRefineLB) [0-100]");
00230 
00231   
00232   _lb_predict = CmiGetArgFlagDesc(argv, "+LBPredictor", "Turn on LB future predictor");
00233   CmiGetArgIntDesc(argv, "+LBPredictorDelay", &_lb_predict_delay, "Number of balance steps before learning a model");
00234   CmiGetArgIntDesc(argv, "+LBPredictorWindow", &_lb_predict_window, "Number of steps to use to learn a model");
00235   if (_lb_predict_window < _lb_predict_delay) {
00236     CmiPrintf("LB> [%d] Argument LBPredictorWindow (%d) less than LBPredictorDelay (%d) , fixing\n", CkMyPe(), _lb_predict_window, _lb_predict_delay);
00237     _lb_predict_delay = _lb_predict_window;
00238   }
00239 
00240   
00241   
00242   CmiGetArgIntDesc(argv, "+LBVersion", &_lb_args.lbversion(), "LB database file version number");
00243   CmiGetArgIntDesc(argv, "+LBCentPE", &_lb_args.central_pe(), "CentralLB processor");
00244   bool _lb_dump_activated = false;
00245   if (CmiGetArgIntDesc(argv, "+LBDump", &LBSimulation::dumpStep, "Dump the LB state from this step"))
00246     _lb_dump_activated = true;
00247   if (_lb_dump_activated && LBSimulation::dumpStep < 0) {
00248     CmiPrintf("LB> Argument LBDump (%d) negative, setting to 0\n",LBSimulation::dumpStep);
00249     LBSimulation::dumpStep = 0;
00250   }
00251   CmiGetArgIntDesc(argv, "+LBDumpSteps", &LBSimulation::dumpStepSize, "Dump the LB state for this amount of steps");
00252   if (LBSimulation::dumpStepSize <= 0) {
00253     CmiPrintf("LB> Argument LBDumpSteps (%d) too small, setting to 1\n",LBSimulation::dumpStepSize);
00254     LBSimulation::dumpStepSize = 1;
00255   }
00256   CmiGetArgStringDesc(argv, "+LBDumpFile", &LBSimulation::dumpFile, "Set the LB state file name");
00257   
00258   LBSimulation::doSimulation = CmiGetArgIntDesc(argv, "+LBSim", &LBSimulation::simStep, "Read LB state from LBDumpFile since this step");
00259   
00260   if (LBSimulation::doSimulation && LBSimulation::simStep < 0) {
00261     CmiPrintf("LB> Argument LBSim (%d) invalid, should be >= 0\n");
00262     CkExit();
00263     return;
00264   }
00265   CmiGetArgIntDesc(argv, "+LBSimSteps", &LBSimulation::simStepSize, "Read LB state for this number of steps");
00266   if (LBSimulation::simStepSize <= 0) {
00267     CmiPrintf("LB> Argument LBSimSteps (%d) too small, setting to 1\n",LBSimulation::simStepSize);
00268     LBSimulation::simStepSize = 1;
00269   }
00270 
00271 
00272   LBSimulation::simProcs = 0;
00273   CmiGetArgIntDesc(argv, "+LBSimProcs", &LBSimulation::simProcs, "Number of target processors.");
00274 
00275   LBSimulation::showDecisionsOnly =
00276     CmiGetArgFlagDesc(argv, "+LBShowDecisions",
00277               "Write to File: Load Balancing Object to Processor Map decisions during LB Simulation");
00278 
00279   
00280   _lb_args.syncResume() = CmiGetArgFlagDesc(argv, "+LBSyncResume",
00281                   "LB performs a barrier after migration is finished");
00282 
00283   
00284   if (!CmiGetArgIntDesc(argv, "+LBDebug", &_lb_args.debug(),
00285                                           "Turn on LB debugging printouts"))
00286     _lb_args.debug() = CmiGetArgFlagDesc(argv, "+LBDebug",
00287                          "Turn on LB debugging printouts");
00288 
00289   
00290   if (!CmiGetArgIntDesc(argv, "+teamSize", &_lb_args.teamSize(),
00291                                           "Team size"))
00292     _lb_args.teamSize() = 1;
00293 
00294   
00295   _lb_args.printSummary() = CmiGetArgFlagDesc(argv, "+LBPrintSummary",
00296         "Print load balancing result summary");
00297 
00298   
00299   _lb_args.ignoreBgLoad() = CmiGetArgFlagDesc(argv, "+LBNoBackground",
00300                       "Load balancer ignores the background load.");
00301 #ifdef __BIGSIM__
00302   _lb_args.ignoreBgLoad() = 1;
00303 #endif
00304   _lb_args.migObjOnly() = CmiGetArgFlagDesc(argv, "+LBObjOnly",
00305                       "Only load balancing migratable objects, ignoring all others.");
00306   if (_lb_args.migObjOnly()) _lb_args.ignoreBgLoad() = 1;
00307 
00308   
00309   _lb_args.testPeSpeed() = CmiGetArgFlagDesc(argv, "+LBTestPESpeed",
00310                       "Load balancer test all CPUs speed.");
00311   _lb_args.samePeSpeed() = CmiGetArgFlagDesc(argv, "+LBSameCpus",
00312                       "Load balancer assumes all CPUs are of same speed.");
00313   if (!_lb_args.testPeSpeed()) _lb_args.samePeSpeed() = 1;
00314 
00315   _lb_args.useCpuTime() = CmiGetArgFlagDesc(argv, "+LBUseCpuTime",
00316                       "Load balancer uses CPU time instead of wallclock time.");
00317 
00318   
00319   _lb_args.statsOn() = !CmiGetArgFlagDesc(argv, "+LBOff",
00320             "Turn load balancer instrumentation off");
00321 
00322   
00323   _lb_args.traceComm() = !CmiGetArgFlagDesc(argv, "+LBCommOff",
00324         "Turn load balancer instrumentation of communication off");
00325 
00326   
00327   _lb_args.alpha() = PER_MESSAGE_SEND_OVERHEAD_DEFAULT;
00328   _lb_args.beta() = PER_BYTE_SEND_OVERHEAD_DEFAULT;
00329   CmiGetArgDoubleDesc(argv,"+LBAlpha", &_lb_args.alpha(),
00330                            "per message send overhead");
00331   CmiGetArgDoubleDesc(argv,"+LBBeta", &_lb_args.beta(),
00332                            "per byte send overhead");
00333 
00334   if (CkMyPe() == 0) {
00335     if (_lb_args.debug()) {
00336       CmiPrintf("CharmLB> Verbose level %d, load balancing period: %g seconds\n", _lb_args.debug(), _lb_args.lbperiod());
00337     }
00338     if (_lb_args.debug() > 1) {
00339       CmiPrintf("CharmLB> Topology %s alpha: %es beta: %es.\n", _lbtopo, _lb_args.alpha(), _lb_args.beta());
00340     }
00341     if (_lb_args.printSummary())
00342       CmiPrintf("CharmLB> Load balancer print summary of load balancing result.\n");
00343     if (_lb_args.ignoreBgLoad())
00344       CmiPrintf("CharmLB> Load balancer ignores processor background load.\n");
00345     if (_lb_args.samePeSpeed())
00346       CmiPrintf("CharmLB> Load balancer assumes all CPUs are same.\n");
00347     if (_lb_args.useCpuTime())
00348       CmiPrintf("CharmLB> Load balancer uses CPU time instead of wallclock time.\n");
00349     if (LBSimulation::doSimulation)
00350       CmiPrintf("CharmLB> Load balancer running in simulation mode on file '%s' version %d.\n", LBSimulation::dumpFile, _lb_args.lbversion());
00351     if (_lb_args.statsOn()==0)
00352       CkPrintf("CharmLB> Load balancing instrumentation is off.\n");
00353     if (_lb_args.traceComm()==0)
00354       CkPrintf("CharmLB> Load balancing instrumentation for communication is off.\n");
00355     if (_lb_args.migObjOnly())
00356       CkPrintf("LB> Load balancing strategy ignores non-migratable objects.\n");
00357   }
00358 }
00359 
00360 bool LBDatabase::manualOn = false;
00361 char *LBDatabase::avail_vector = NULL;
00362 bool LBDatabase::avail_vector_set = false;
00363 CmiNodeLock avail_vector_lock;
00364 
00365 static LBRealType * _expectedLoad = NULL;
00366 
00367 void LBDatabase::initnodeFn()
00368 {
00369   int proc;
00370   int num_proc = CkNumPes();
00371   avail_vector= new char[num_proc];
00372   for(proc = 0; proc < num_proc; proc++)
00373       avail_vector[proc] = 1;
00374   avail_vector_lock = CmiCreateLock();
00375 
00376   _expectedLoad = new LBRealType[num_proc];
00377   for (proc=0; proc<num_proc; proc++) _expectedLoad[proc]=0.0;
00378 
00379   _registerCommandLineOpt("+balancer");
00380   _registerCommandLineOpt("+LBPeriod");
00381   _registerCommandLineOpt("+LBLoop");
00382   _registerCommandLineOpt("+LBTopo");
00383   _registerCommandLineOpt("+LBPercentMoves");
00384   _registerCommandLineOpt("+LBPredictor");
00385   _registerCommandLineOpt("+LBPredictorDelay");
00386   _registerCommandLineOpt("+LBPredictorWindow");
00387   _registerCommandLineOpt("+LBVersion");
00388   _registerCommandLineOpt("+LBCentPE");
00389   _registerCommandLineOpt("+LBDump");
00390   _registerCommandLineOpt("+LBDumpSteps");
00391   _registerCommandLineOpt("+LBDumpFile");
00392   _registerCommandLineOpt("+LBSim");
00393   _registerCommandLineOpt("+LBSimSteps");
00394   _registerCommandLineOpt("+LBSimProcs");
00395   _registerCommandLineOpt("+LBShowDecisions");
00396   _registerCommandLineOpt("+LBSyncResume");
00397   _registerCommandLineOpt("+LBDebug");
00398   _registerCommandLineOpt("+teamSize");
00399   _registerCommandLineOpt("+LBPrintSummary");
00400   _registerCommandLineOpt("+LBNoBackground");
00401   _registerCommandLineOpt("+LBObjOnly");
00402   _registerCommandLineOpt("+LBTestPESpeed");
00403   _registerCommandLineOpt("+LBSameCpus");
00404   _registerCommandLineOpt("+LBUseCpuTime");
00405   _registerCommandLineOpt("+LBOff");
00406   _registerCommandLineOpt("+LBCommOff");
00407   _registerCommandLineOpt("+MetaLB");
00408   _registerCommandLineOpt("+LBAlpha");
00409   _registerCommandLineOpt("+LBBeta");
00410 }
00411 
00412 
00413 void LBDatabase::init(void)
00414 {
00415   myLDHandle = LDCreate();
00416   mystep = 0;
00417   nloadbalancers = 0;
00418   new_ld_balancer = 0;
00419     metabalancer = NULL;
00420 
00421   CkpvAccess(lbdatabaseInited) = true;
00422 #if CMK_LBDB_ON
00423   if (manualOn) TurnManualLBOn();
00424 #endif
00425 }
00426 
00427 LBDatabase::LastLBInfo::LastLBInfo()
00428 {
00429   expectedLoad = _expectedLoad;
00430 }
00431 
00432 void LBDatabase::get_avail_vector(char * bitmap) {
00433     CmiAssert(bitmap && avail_vector);
00434     const int num_proc = CkNumPes();
00435     for(int proc = 0; proc < num_proc; proc++){
00436       bitmap[proc] = avail_vector[proc];
00437     }
00438 }
00439 
00440 
00441 
00442 
00443 void LBDatabase::set_avail_vector(char * bitmap, int new_ld){
00444     int assigned = 0;
00445     const int num_proc = CkNumPes();
00446     if (new_ld == -2) assigned = 1;
00447     else if (new_ld >= 0) {
00448       CmiAssert(new_ld < num_proc);
00449       new_ld_balancer = new_ld;
00450       assigned = 1;
00451     }
00452     CmiAssert(bitmap && avail_vector);
00453     for(int count = 0; count < num_proc; count++){
00454         avail_vector[count] = bitmap[count];
00455         if((bitmap[count] == 1) && !assigned){
00456             new_ld_balancer = count;
00457             assigned = 1;
00458         }
00459     }
00460 }
00461 
00462 
00463 
00464 
00465 int LBDatabase::getLoadbalancerTicket()  {
00466   int seq = nloadbalancers;
00467   nloadbalancers ++;
00468   loadbalancers.resize(nloadbalancers);
00469   loadbalancers[seq] = NULL;
00470   return seq;
00471 }
00472 
00473 void LBDatabase::addLoadbalancer(BaseLB *lb, int seq) {
00474 
00475   if (seq == -1) return;
00476   if (CkMyPe() == 0) {
00477     CmiAssert(seq < nloadbalancers);
00478     if (loadbalancers[seq]) {
00479       CmiPrintf("Duplicate load balancer created at %d\n", seq);
00480       CmiAbort("LBDatabase");
00481     }
00482   }
00483   else
00484     nloadbalancers ++;
00485   loadbalancers.resize(seq+1);
00486   loadbalancers[seq] = lb;
00487 }
00488 
00489 
00490 void LBDatabase::nextLoadbalancer(int seq) {
00491   if (seq == -1) return;        
00492   int next = seq+1;
00493   if (_lb_args.loop()) {
00494     if (next == nloadbalancers) next = 0;
00495   }
00496   else {
00497     if (next == nloadbalancers) next --;  
00498   }
00499   if (seq != next) {
00500     loadbalancers[seq]->turnOff();
00501     CmiAssert(loadbalancers[next]);
00502     loadbalancers[next]->turnOn();
00503   }
00504 }
00505 
00506 
00507 void LBDatabase::switchLoadbalancer(int switchFrom, int switchTo) {
00508   if (switchTo != switchFrom) {
00509     if (switchFrom != -1) loadbalancers[switchFrom]->turnOff();
00510     CmiAssert(loadbalancers[switchTo]);
00511     loadbalancers[switchTo]->turnOn();
00512   }
00513 }
00514 
00515 
00516 
00517 
00518 const char *LBDatabase::loadbalancer(int seq) {
00519   if (lbRegistry.runtime_lbs.length()) {
00520     CmiAssert(seq < lbRegistry.runtime_lbs.length());
00521     return lbRegistry.runtime_lbs[seq];
00522   }
00523   else {
00524     CmiAssert(seq < lbRegistry.compile_lbs.length());
00525     return lbRegistry.compile_lbs[seq];
00526   }
00527 }
00528 
00529 void LBDatabase::pup(PUP::er& p)
00530 {
00531   IrrGroup::pup(p);
00532   
00533   int np;
00534   if (!p.isUnpacking()) np = CkNumPes();
00535   p|np;
00536   
00537   if (p.isUnpacking()) {
00538     CmiLock(avail_vector_lock);
00539     if(!avail_vector_set){
00540       avail_vector_set = true;
00541       CmiAssert(avail_vector);
00542       if(np>CkNumPes()){
00543         delete [] avail_vector;
00544         avail_vector = new char[np];
00545         for (int i=0; i<np; i++) avail_vector[i] = 1;
00546       }
00547       p(avail_vector, np);
00548     } else{
00549       char * tmp_avail_vector = new char[np];
00550       p(tmp_avail_vector, np);
00551       delete [] tmp_avail_vector;
00552     }
00553     CmiUnlock(avail_vector_lock);
00554   } else{
00555     CmiAssert(avail_vector);
00556     p(avail_vector, np);
00557   }
00558   p|mystep;
00559   if(p.isUnpacking()) {
00560     nloadbalancers = 0;
00561     if (_lb_args.metaLbOn()) {
00562       
00563       metabalancer = (MetaBalancer*)CkLocalBranch(_metalb);
00564     }
00565   }
00566 }
00567 
00568 
00569 void LBDatabase::EstObjLoad(const LDObjHandle &_h, double cputime)
00570 {
00571 #if CMK_LBDB_ON
00572   LBDB *const db = (LBDB*)(_h.omhandle.ldb.handle);
00573   LBObj *const obj = db->LbObj(_h);
00574 
00575   CmiAssert(obj != NULL);
00576   obj->setTiming(cputime);
00577 #endif
00578 }
00579 
00580 void LBDatabase::ResetAdaptive() {
00581 #if CMK_LBDB_ON
00582     if (_lb_args.metaLbOn()) {
00583         if (metabalancer == NULL) {
00584             metabalancer = CProxy_MetaBalancer(_metalb).ckLocalBranch();
00585         }
00586         if (metabalancer != NULL) {
00587             metabalancer->ResetAdaptive();
00588         }
00589     }
00590 #endif
00591 }
00592 
00593 void LBDatabase::ResumeClients() {
00594 #if CMK_LBDB_ON
00595     if (_lb_args.metaLbOn()) {
00596         if (metabalancer == NULL) {
00597             metabalancer = CProxy_MetaBalancer(_metalb).ckLocalBranch();
00598         }
00599         if (metabalancer != NULL) {
00600             metabalancer->ResumeClients();
00601         }
00602     }
00603   LDResumeClients(myLDHandle);
00604 #endif
00605 }
00606 
00607 void LBDatabase::SetMigrationCost(double cost) {
00608 #if CMK_LBDB_ON
00609     if (_lb_args.metaLbOn()) {
00610         if (metabalancer == NULL) {
00611             metabalancer = (MetaBalancer *)CkLocalBranch(_metalb);
00612         }
00613         if (metabalancer != NULL)  {
00614             metabalancer->SetMigrationCost(cost);
00615         }
00616     }
00617 #endif
00618 }
00619 
00620 void LBDatabase::SetStrategyCost(double cost) {
00621 #if CMK_LBDB_ON
00622     if (_lb_args.metaLbOn()) {
00623         if (metabalancer == NULL) {
00624             metabalancer = (MetaBalancer *)CkLocalBranch(_metalb);
00625         }
00626         if (metabalancer != NULL)  {
00627             metabalancer->SetStrategyCost(cost);
00628         }
00629     }
00630 #endif
00631 }
00632 
00633 void LBDatabase::UpdateDataAfterLB(double mLoad, double mCpuLoad, double avgLoad) {
00634 #if CMK_LBDB_ON
00635     if (_lb_args.metaLbOn()) {
00636         if (metabalancer == NULL) {
00637             metabalancer = (MetaBalancer *)CkLocalBranch(_metalb);
00638         }
00639         if (metabalancer != NULL)  {
00640             metabalancer->UpdateAfterLBData(mLoad, mCpuLoad, avgLoad);
00641         }
00642     }
00643 #endif
00644 }
00645 
00646 
00647 
00648 void TurnManualLBOn()
00649 {
00650 #if CMK_LBDB_ON
00651    LBDatabase * myLbdb = LBDatabase::Object();
00652    if (myLbdb) {
00653      myLbdb->TurnManualLBOn();
00654    }
00655    else {
00656      LBDatabase::manualOn = true;
00657    }
00658 #endif
00659 }
00660 
00661 void TurnManualLBOff()
00662 {
00663 #if CMK_LBDB_ON
00664    LBDatabase * myLbdb = LBDatabase::Object();
00665    if (myLbdb) {
00666      myLbdb->TurnManualLBOff();
00667    }
00668    else {
00669      LBDatabase::manualOn = true;
00670    }
00671 #endif
00672 }
00673 
00674 extern "C" void LBTurnInstrumentOn() {
00675 #if CMK_LBDB_ON
00676   if (CkpvAccess(lbdatabaseInited))
00677     LBDatabase::Object()->CollectStatsOn();
00678   else
00679     _lb_args.statsOn() = 1;
00680 #endif
00681 }
00682 
00683 extern "C" void LBTurnInstrumentOff() {
00684 #if CMK_LBDB_ON
00685   if (CkpvAccess(lbdatabaseInited))
00686     LBDatabase::Object()->CollectStatsOff();
00687   else
00688     _lb_args.statsOn() = 0;
00689 #endif
00690 }
00691 
00692 extern "C" void LBTurnCommOn() {
00693 #if CMK_LBDB_ON
00694   _lb_args.traceComm() = 1;
00695 #endif
00696 }
00697 
00698 extern "C" void LBTurnCommOff() {
00699 #if CMK_LBDB_ON
00700   _lb_args.traceComm() = 0;
00701 #endif
00702 }
00703 
00704 void LBClearLoads() {
00705 #if CMK_LBDB_ON
00706   LBDatabase::Object()->ClearLoads();
00707 #endif
00708 }
00709 
00710 void LBTurnPredictorOn(LBPredictorFunction *model) {
00711 #if CMK_LBDB_ON
00712   LBDatabase::Object()->PredictorOn(model);
00713 #endif
00714 }
00715 
00716 void LBTurnPredictorOn(LBPredictorFunction *model, int wind) {
00717 #if CMK_LBDB_ON
00718   LBDatabase::Object()->PredictorOn(model, wind);
00719 #endif
00720 }
00721 
00722 void LBTurnPredictorOff() {
00723 #if CMK_LBDB_ON
00724   LBDatabase::Object()->PredictorOff();
00725 #endif
00726 }
00727 
00728 void LBChangePredictor(LBPredictorFunction *model) {
00729 #if CMK_LBDB_ON
00730   LBDatabase::Object()->ChangePredictor(model);
00731 #endif
00732 }
00733 
00734 void LBSetPeriod(double second) {
00735 #if CMK_LBDB_ON
00736   if (CkpvAccess(lbdatabaseInited))
00737     LBDatabase::Object()->SetLBPeriod(second);
00738   else
00739     _lb_args.lbperiod() = second;
00740 #endif
00741 }
00742 
00743 int LBRegisterObjUserData(int size)
00744 {
00745   return CkpvAccess(lbobjdatalayout).claim(size);
00746 }
00747 
00748 #include "LBDatabase.def.h"
00749