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