00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <algorithm>
00015
00016 #include "charm++.h"
00017
00018
00019 #include "ckgraph.h"
00020 #include "cklists.h"
00021 #include "GreedyLB.h"
00022
00023 using namespace std;
00024
00025 extern int quietModeRequested;
00026
00027 CreateLBFunc_Def(GreedyLB, "always assign the heaviest obj onto lightest loaded processor.")
00028
00029 GreedyLB::GreedyLB(const CkLBOptions &opt): CBase_GreedyLB(opt)
00030 {
00031 lbname = "GreedyLB";
00032 if (CkMyPe()==0 && !quietModeRequested)
00033 CkPrintf("CharmLB> GreedyLB created.\n");
00034 }
00035
00036 bool GreedyLB::QueryBalanceNow(int _step)
00037 {
00038
00039 return true;
00040 }
00041
00042 class GreedyLB::ProcLoadGreater {
00043 public:
00044 bool operator()(const ProcInfo &p1, const ProcInfo &p2) {
00045 return (p1.getTotalLoad() > p2.getTotalLoad());
00046 }
00047 };
00048
00049 class GreedyLB::ObjLoadGreater {
00050 public:
00051 bool operator()(const Vertex &v1, const Vertex &v2) {
00052 return (v1.getVertexLoad() > v2.getVertexLoad());
00053 }
00054 };
00055
00056 void GreedyLB::work(LDStats* stats)
00057 {
00058 int obj, objCount, pe;
00059 int n_pes = stats->nprocs();
00060 int *map = new int[n_pes];
00061
00062 std::vector<ProcInfo> procs;
00063 for(pe = 0; pe < n_pes; pe++) {
00064 map[pe] = -1;
00065 if (stats->procs[pe].available) {
00066 map[pe] = procs.size();
00067 procs.push_back(ProcInfo(pe, stats->procs[pe].bg_walltime, 0.0, stats->procs[pe].pe_speed, true));
00068 }
00069 }
00070
00071
00072 for (obj = 0; obj < stats->n_objs; obj++)
00073 {
00074 LDObjData &oData = stats->objData[obj];
00075 if (!oData.migratable) {
00076 int pe = stats->from_proc[obj];
00077 pe = map[pe];
00078 if (pe==-1)
00079 CmiAbort("GreedyLB: nonmigratable object on an unavail processor!\n");
00080 procs[pe].totalLoad() += oData.wallTime;
00081 }
00082 }
00083 delete [] map;
00084
00085
00086 for (pe = 0; pe<procs.size(); pe++) {
00087 procs[pe].totalLoad() += procs[pe].overhead();
00088 }
00089
00090
00091 std::vector<Vertex> objs;
00092
00093 for(int obj = 0; obj < stats->n_objs; obj++) {
00094 LDObjData &oData = stats->objData[obj];
00095 int pe = stats->from_proc[obj];
00096 if (!oData.migratable) {
00097 if (!stats->procs[pe].available)
00098 CmiAbort("GreedyLB cannot handle nonmigratable object on an unavial processor!\n");
00099 continue;
00100 }
00101 double load = oData.wallTime * stats->procs[pe].pe_speed;
00102 objs.push_back(Vertex(obj, load, stats->objData[obj].migratable, stats->from_proc[obj]));
00103 }
00104
00105
00106 sort(objs.begin(), objs.end(), GreedyLB::ObjLoadGreater());
00107
00108 make_heap(procs.begin(), procs.end(), GreedyLB::ProcLoadGreater());
00109
00110 if (_lb_args.debug()>1)
00111 CkPrintf("[%d] In GreedyLB strategy\n",CkMyPe());
00112
00113
00114
00115 int nmoves = 0;
00116 for (obj=0; obj < objs.size(); obj++) {
00117 ProcInfo p = procs.front();
00118 pop_heap(procs.begin(), procs.end(), GreedyLB::ProcLoadGreater());
00119 procs.pop_back();
00120
00121
00122
00123 p.totalLoad() += objs[obj].getVertexLoad() / p.pe_speed();
00124
00125
00126 const int dest = p.getProcId();
00127 const int pe = objs[obj].getCurrentPe();
00128 const int id = objs[obj].getVertexId();
00129 if (dest != pe) {
00130 stats->to_proc[id] = dest;
00131 nmoves ++;
00132 if (_lb_args.debug()>2)
00133 CkPrintf("[%d] Obj %d migrating from %d to %d\n", CkMyPe(),objs[obj].getVertexId(),pe,dest);
00134 }
00135
00136
00137 procs.push_back(p);
00138 push_heap(procs.begin(), procs.end(), GreedyLB::ProcLoadGreater());
00139 }
00140
00141 if (_lb_args.debug()>0)
00142 CkPrintf("[%d] %d objects migrating.\n", CkMyPe(), nmoves);
00143
00144 if (_lb_args.debug()>1) {
00145 CkPrintf("CharmLB> Min obj: %f Max obj: %f\n", objs[objs.size()-1].getVertexLoad(), objs[0].getVertexLoad());
00146 CkPrintf("CharmLB> PE speed:\n");
00147 for (pe = 0; pe<procs.size(); pe++)
00148 CkPrintf("%f ", procs[pe].pe_speed());
00149 CkPrintf("\n");
00150 CkPrintf("CharmLB> PE Load:\n");
00151 for (pe = 0; pe<procs.size(); pe++)
00152 CkPrintf("%f (%f) ", procs[pe].totalLoad(), procs[pe].overhead());
00153 CkPrintf("\n");
00154 }
00155
00156 if (_lb_args.metaLbOn()) {
00157 double max_load = 0;
00158 double avg_load = 0;
00159 for (pe = 0; pe<procs.size(); pe++) {
00160 if (procs[pe].totalLoad() > max_load) {
00161 max_load = procs[pe].totalLoad();
00162 }
00163 avg_load += procs[pe].totalLoad();
00164 }
00165
00166 stats->after_lb_max = max_load;
00167 stats->after_lb_avg = avg_load/procs.size();
00168 stats->is_prev_lb_refine = 0;
00169 if (_lb_args.debug() > 0)
00170 CkPrintf("GreedyLB> After lb max load: %lf avg load: %lf\n", max_load, avg_load/procs.size());
00171 }
00172 }
00173
00174 #include "GreedyLB.def.h"
00175