00001 
00005 
00006 #include "elements.h"
00007 #include "ckheap.h"
00008 #include "NeighborLB.h"
00009 
00010 extern int quietModeRequested;
00011 
00012 CreateLBFunc_Def(NeighborLB, "The neighborhood load balancer")
00013 
00014 NeighborLB::NeighborLB(const CkLBOptions &opt):CBase_NeighborLB(opt)
00015 {
00016   lbname = "NeighborLB";
00017   if (CkMyPe() == 0 && !quietModeRequested)
00018     CkPrintf("CharmLB> NeighborLB created.\n");
00019 }
00020 
00021 LBMigrateMsg* NeighborLB::Strategy(NborBaseLB::LDStats* stats, int n_nbrs)
00022 {
00023 #if CMK_LBDB_ON
00024   
00025   
00026   
00027   double myload = myStats.total_walltime - myStats.idletime;
00028   double avgload = myload;
00029   int i;
00030   for(i=0; i < n_nbrs; i++) {
00031     
00032     const double scale =  ((double)myStats.pe_speed) 
00033       / stats[i].pe_speed;
00034 
00035     stats[i].total_walltime *= scale;
00036     stats[i].idletime *= scale;
00037 
00038     avgload += (stats[i].total_walltime - stats[i].idletime);
00039   }
00040   avgload /= (n_nbrs + 1);
00041 
00042   CkVec<MigrateInfo*> migrateInfo;
00043 
00044   if (myload > avgload) {
00045     if (_lb_args.debug()>1) 
00046       CkPrintf("[%d] OVERLOAD My load is %f, average load is %f\n", CkMyPe(),myload,avgload);
00047 
00048     
00049     
00050     
00051     
00052     
00053     
00054 
00055     
00056     minHeap procs(n_nbrs);
00057     for(i=0; i < n_nbrs; i++) {
00058       InfoRecord* item = new InfoRecord;
00059       item->load = stats[i].total_walltime - stats[i].idletime;
00060       item->Id =  stats[i].from_pe;
00061       procs.insert(item);
00062     }
00063       
00064     maxHeap objs(myStats.n_objs);
00065     for(i=0; i < myStats.n_objs; i++) {
00066       InfoRecord* item = new InfoRecord;
00067       item->load = myStats.objData[i].wallTime;
00068       item->Id = i;
00069       objs.insert(item);
00070     }
00071 
00072     int objs_here = myStats.n_objs;
00073     do {
00074       if (objs_here <= 1) break;  
00075 
00076       InfoRecord* p;
00077       InfoRecord* obj;
00078 
00079       
00080       p = procs.deleteMin();
00081       if (p == 0) {
00082     
00083     break;
00084       }
00085 
00086       
00087       bool objfound = false;
00088       do {
00089     obj = objs.deleteMax();
00090     if (obj == 0) break;
00091 
00092     double new_p_load = p->load + obj->load;
00093     double my_new_load = myload - obj->load;
00094     if (new_p_load < my_new_load) {
00095 
00096       objfound = true;
00097     } else {
00098       
00099 
00100 
00101       delete obj;
00102     }
00103       } while (!objfound);
00104 
00105       if (!objfound) {
00106         if (_lb_args.debug()>2) 
00107       CkPrintf("[%d] No suitable object found!\n",CkMyPe());
00108     break;
00109       }
00110 
00111       const int me = CkMyPe();
00112       
00113       
00114       
00115 
00116       MigrateInfo* migrateMe = new MigrateInfo;
00117       migrateMe->obj = myStats.objData[obj->Id].handle;
00118       migrateMe->from_pe = me;
00119       migrateMe->to_pe = p->Id;
00120       migrateInfo.insertAtEnd(migrateMe);
00121 
00122       objs_here--;
00123       
00124       
00125       
00126       p->load += obj->load;
00127       myload -= obj->load;
00128       procs.insert(p);
00129       
00130       
00131       delete obj;
00132 
00133     } while(myload > avgload);
00134 
00135     
00136     InfoRecord* p;
00137     while (NULL!=(p=procs.deleteMin()))
00138       delete p;
00139 
00140     InfoRecord* obj;
00141     while (NULL!=(obj=objs.deleteMax()))
00142       delete obj;
00143   }  
00144 
00145   
00146   int migrate_count=migrateInfo.length();
00147   
00148   
00149   
00150   LBMigrateMsg* msg = new(migrate_count,CkNumPes(),CkNumPes(),0) LBMigrateMsg;
00151   msg->n_moves = migrate_count;
00152   for(i=0; i < migrate_count; i++) {
00153     MigrateInfo* item = (MigrateInfo*) migrateInfo[i];
00154     msg->moves[i] = *item;
00155     delete item;
00156     migrateInfo[i] = 0;
00157   }
00158 
00159   return msg;
00160 #else
00161   return NULL;
00162 #endif
00163 }
00164 
00165 #include "NeighborLB.def.h"
00166