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