00001
00005
00006 #include "elements.h"
00007 #include "ckheap.h"
00008 #include "RefineKLB.h"
00009
00010 #define _USE_APPROX_ALGO_ 1
00011 #define _USE_RESIDUAL_MOVES_ 1
00012
00013
00014 extern int quietModeRequested;
00015
00016 CreateLBFunc_Def(RefineKLB, "Move objects away from overloaded processor to reach average")
00017
00018 RefineKLB::RefineKLB(const CkLBOptions &opt): CBase_RefineKLB(opt)
00019 {
00020 lbname = (char *)"RefineKLB";
00021 if (CkMyPe() == 0 && !quietModeRequested)
00022 CkPrintf("CharmLB> RefineKLB created.\n");
00023 }
00024
00025 void RefineKLB::work(LDStats* stats)
00026 {
00027 int obj;
00028 int n_pes = stats->nprocs();
00029
00030
00031
00032
00033
00034
00035 int* from_procs = RefinerApprox::AllocProcs(n_pes, stats);
00036 for(obj=0;obj<stats->n_objs;obj++) {
00037 int pe = stats->from_proc[obj];
00038 from_procs[obj] = pe;
00039 }
00040
00041
00042 int* to_procs = RefinerApprox::AllocProcs(n_pes, stats);
00043
00044 RefinerApprox refiner(1.003);
00045
00046 if(_lb_args.percentMovesAllowed()>0 && _USE_APPROX_ALGO_)
00047 {
00048 refiner.Refine(n_pes, stats, from_procs, to_procs, _lb_args.percentMovesAllowed());
00049 }
00050 else
00051 {
00052 for(obj=0;obj<stats->n_objs;obj++)
00053 {
00054 to_procs[obj] = stats->from_proc[obj];
00055 }
00056 }
00057
00058
00059 int numMoves=0;
00060 for(obj=0;obj<stats->n_objs;obj++)
00061 {
00062 int pe = stats->from_proc[obj];
00063 if (to_procs[obj] != pe)
00064 {
00065
00066
00067 stats->to_proc[obj] = to_procs[obj];
00068 numMoves++;
00069 }
00070 }
00071 int maxMoves=0.01*(stats->n_objs)*(_lb_args.percentMovesAllowed());
00072 int availableMoves=maxMoves-numMoves;
00073
00074
00075 if(availableMoves>0 && _USE_RESIDUAL_MOVES_)
00076 {
00077 int *to_procs2=new int[stats->n_objs];
00078 performGreedyMoves(n_pes, stats, to_procs, to_procs2, availableMoves);
00079
00080 int nmoves2=0;
00081 for(obj=0;obj<stats->n_objs;obj++)
00082 {
00083 if(to_procs2[obj]!=to_procs[obj])
00084 {
00085 stats->to_proc[obj]=to_procs2[obj];
00086 nmoves2++;
00087 }
00088 }
00089 delete[] to_procs2;
00090 }
00091
00092
00093 RefinerApprox::FreeProcs(from_procs);
00094 RefinerApprox::FreeProcs(to_procs);
00095 }
00096
00097 void RefineKLB::performGreedyMoves(int count, BaseLB::LDStats* stats,int *from_procs, int *to_procs, int numMoves)
00098 {
00099
00100 int *objPerProc=new int[count];
00101 double *loadPerProc=new double[count];
00102 int i;
00103 for(i=0;i<count;i++)
00104 {
00105 objPerProc[i]=0;
00106 loadPerProc[i]=stats->procs[i].bg_walltime;
00107 }
00108 for(i=0;i<stats->n_objs;i++)
00109 {
00110 to_procs[i]=from_procs[i];
00111 objPerProc[from_procs[i]]++;
00112 loadPerProc[from_procs[i]]+=(stats->objData[i]).wallTime;
00113 }
00114
00115
00116 maxHeap *procLoad=new maxHeap(count);
00117 for(i=0;i<count;i++)
00118 {
00119 InfoRecord *rec=new InfoRecord();
00120 rec->load=loadPerProc[i];
00121 rec->Id=i;
00122 procLoad->insert(rec);
00123 }
00124
00125
00126 maxHeap **procObjs=new maxHeap*[count];
00127 for(i=0;i<count;i++)
00128 {
00129 procObjs[i]=new maxHeap(objPerProc[i]);
00130 }
00131 for(i=0;i<stats->n_objs;i++)
00132 {
00133 if((stats->objData[i]).migratable == false)
00134 continue;
00135 InfoRecord *rec=new InfoRecord();
00136 rec->load=(stats->objData[i]).wallTime;
00137 rec->Id=i;
00138 procObjs[from_procs[i]]->insert(rec);
00139 }
00140
00141
00142
00143 maxHeap *unassignedComputes=new maxHeap(numMoves);
00144 for(i=0;i<numMoves;i++)
00145 {
00146 InfoRecord *maxProc=procLoad->deleteMax();
00147
00148 InfoRecord *maxObj=procObjs[maxProc->Id]->deleteMax();
00149 if(!maxObj)
00150 {
00151 procLoad->insert(maxProc);
00152 break;
00153 }
00154 unassignedComputes->insert(maxObj);
00155
00156 maxProc->load-=maxObj->load;
00157 loadPerProc[maxProc->Id]=maxProc->load;
00158
00159 procLoad->insert(maxProc);
00160 }
00161
00162
00163 minHeap *leastLoadedP=new minHeap(count);
00164 for(i=0;i<count;i++)
00165 {
00166 leastLoadedP->insert(procLoad->deleteMax());
00167 }
00168
00169 for(i=0;i<numMoves;i++)
00170 {
00171 InfoRecord *c=unassignedComputes->deleteMax();
00172 if(!c)
00173 break;
00174
00175 InfoRecord *proc=leastLoadedP->deleteMin();
00176 proc->load+=c->load;
00177 leastLoadedP->insert(proc);
00178
00179 to_procs[c->Id]=proc->Id;
00180 delete c;
00181 }
00182
00183
00184 delete[] objPerProc;
00185 delete[] loadPerProc;
00186 for(i=0;i<count;i++)
00187 {
00188 delete procObjs[i];
00189 }
00190 delete[] procObjs;
00191 delete unassignedComputes;
00192 delete leastLoadedP;
00193 }
00194
00195 #include "RefineKLB.def.h"
00196