8 * support processor avail bitvector
9 * support nonmigratable attrib
10 nonmigratable object load is added to its processor's background load
11 and the nonmigratable object is not taken in the objData array
25 CreateLBFunc_Def(GreedyLB, "always assign the heaviest obj onto lightest loaded processor.")
27 GreedyLB::GreedyLB(const CkLBOptions &opt): CBase_GreedyLB(opt)
31 CkPrintf("[%d] GreedyLB created\n",CkMyPe());
34 bool GreedyLB::QueryBalanceNow(int _step)
36 // CkPrintf("[%d] Balancing on step %d\n",CkMyPe(),_step);
40 class ProcLoadGreater {
42 bool operator()(const ProcInfo &p1, const ProcInfo &p2) {
43 return (p1.getTotalLoad() > p2.getTotalLoad());
47 class ObjLoadGreater {
49 bool operator()(const Vertex &v1, const Vertex &v2) {
50 return (v1.getVertexLoad() > v2.getVertexLoad());
54 void GreedyLB::work(LDStats* stats)
56 int obj, objCount, pe;
57 int n_pes = stats->nprocs();
58 int *map = new int[n_pes];
60 std::vector<ProcInfo> procs;
61 for(pe = 0; pe < n_pes; pe++) {
63 if (stats->procs[pe].available) {
64 map[pe] = procs.size();
65 procs.push_back(ProcInfo(pe, stats->procs[pe].bg_walltime, 0.0, stats->procs[pe].pe_speed, true));
69 // take non migratbale object load as background load
70 for (obj = 0; obj < stats->n_objs; obj++)
72 LDObjData &oData = stats->objData[obj];
73 if (!oData.migratable) {
74 int pe = stats->from_proc[obj];
77 CmiAbort("GreedyLB: nonmigratable object on an unavail processor!\n");
78 procs[pe].totalLoad() += oData.wallTime;
83 // Add the overhead to the total load
84 for (pe = 0; pe<procs.size(); pe++) {
85 procs[pe].totalLoad() += procs[pe].overhead();
89 std::vector<Vertex> objs;
91 for(int obj = 0; obj < stats->n_objs; obj++) {
92 LDObjData &oData = stats->objData[obj];
93 int pe = stats->from_proc[obj];
94 if (!oData.migratable) {
95 if (!stats->procs[pe].available)
96 CmiAbort("GreedyLB cannot handle nonmigratable object on an unavial processor!\n");
99 double load = oData.wallTime * stats->procs[pe].pe_speed;
100 objs.push_back(Vertex(obj, load, stats->objData[obj].migratable, stats->from_proc[obj]));
103 // max heap of objects
104 sort(objs.begin(), objs.end(), ObjLoadGreater());
105 // min heap of processors
106 make_heap(procs.begin(), procs.end(), ProcLoadGreater());
108 if (_lb_args.debug()>1)
109 CkPrintf("[%d] In GreedyLB strategy\n",CkMyPe());
114 for (obj=0; obj < objs.size(); obj++) {
115 ProcInfo p = procs.front();
116 pop_heap(procs.begin(), procs.end(), ProcLoadGreater());
119 // Increment the time of the least loaded processor by the cpuTime of
120 // the `heaviest' object
121 p.totalLoad() += objs[obj].getVertexLoad() / p.pe_speed();
123 //Insert object into migration queue if necessary
124 const int dest = p.getProcId();
125 const int pe = objs[obj].getCurrentPe();
126 const int id = objs[obj].getVertexId();
128 stats->to_proc[id] = dest;
130 if (_lb_args.debug()>2)
131 CkPrintf("[%d] Obj %d migrating from %d to %d\n", CkMyPe(),objs[obj].getVertexId(),pe,dest);
134 //Insert the least loaded processor with load updated back into the heap
136 push_heap(procs.begin(), procs.end(), ProcLoadGreater());
139 if (_lb_args.debug()>0)
140 CkPrintf("[%d] %d objects migrating.\n", CkMyPe(), nmoves);
142 if (_lb_args.debug()>1) {
143 CkPrintf("CharmLB> Min obj: %f Max obj: %f\n", objs[objs.size()-1].getVertexLoad(), objs[0].getVertexLoad());
144 CkPrintf("CharmLB> PE speed:\n");
145 for (pe = 0; pe<procs.size(); pe++)
146 CkPrintf("%f ", procs[pe].pe_speed());
148 CkPrintf("CharmLB> PE Load:\n");
149 for (pe = 0; pe<procs.size(); pe++)
150 CkPrintf("%f (%f) ", procs[pe].totalLoad(), procs[pe].overhead());
154 if (_lb_args.metaLbOn()) {
157 for (pe = 0; pe<procs.size(); pe++) {
158 if (procs[pe].totalLoad() > max_load) {
159 max_load = procs[pe].totalLoad();
161 avg_load += procs[pe].totalLoad();
164 stats->after_lb_max = max_load;
165 stats->after_lb_avg = avg_load/procs.size();
166 stats->is_prev_lb_refine = 0;
167 if (_lb_args.debug() > 0)
168 CkPrintf("GreedyLB> After lb max load: %lf avg load: %lf\n", max_load, avg_load/procs.size());
172 #include "GreedyLB.def.h"