00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "elements.h"
00018 #include "ckheap.h"
00019 #include "GreedyCommLB.h"
00020 #include "manager.h"
00021
00022 CreateLBFunc_Def(GreedyCommLB, "Greedy algorithm which takes communication graph into account")
00023
00024 void GreedyCommLB::init()
00025 {
00026 lbname = (char*)"GreedyCommLB";
00027 alpha = _lb_args.alpha();
00028 beeta = _lb_args.beeta();
00029 manager_init();
00030 }
00031
00032 GreedyCommLB::GreedyCommLB(const CkLBOptions &opt): CentralLB(opt)
00033 {
00034 init();
00035 if (CkMyPe() == 0)
00036 CkPrintf("[%d] GreedyCommLB created\n",CkMyPe());
00037 }
00038
00039 GreedyCommLB::GreedyCommLB(CkMigrateMessage *m):CentralLB(m) {
00040 init();
00041 }
00042
00043 CmiBool GreedyCommLB::QueryBalanceNow(int _step)
00044 {
00045
00046 return CmiTrue;
00047 }
00048
00049
00050 void GreedyCommLB::alloc(int pe,int id,double load){
00051
00052 assigned_array[id] = 1;
00053 processors[pe].load += load;
00054 }
00055
00056
00057 double GreedyCommLB::compute_com(LDStats* stats, int id, int pe){
00058 int j,com_data=0,com_msg=0;
00059 double total_time;
00060 graph * ptr;
00061
00062 ptr = object_graph[id].next;
00063
00064 for(j=0;(j<2*nobj)&&(ptr != NULL);j++,ptr=ptr->next){
00065 int destObj = ptr->id;
00066 if(assigned_array[destObj] == 0)
00067 continue;
00068 if (stats->to_proc[destObj] == pe)
00069 continue;
00070 com_data += ptr->data;
00071 com_msg += ptr->nmsg;
00072 }
00073
00074 total_time = alpha*com_msg + beeta*com_data;
00075 return total_time;
00076 }
00077
00078
00079 void GreedyCommLB::update(LDStats* stats, int id, int pe){
00080 graph * ptr = object_graph[id].next;
00081
00082 for(int j=0;(j<2*nobj)&&(ptr != NULL);j++,ptr=ptr->next){
00083 int destObj = ptr->id;
00084 if(assigned_array[destObj] == 0)
00085 continue;
00086 int destPe = stats->to_proc[destObj];
00087 if (destPe == pe)
00088 continue;
00089 int com_data = ptr->data;
00090 int com_msg = ptr->nmsg;
00091 double com_time = alpha*com_msg + beeta*com_data;
00092 processors[destPe].load += com_time;
00093 }
00094 }
00095
00096
00097
00098 void GreedyCommLB::add_graph(int x, int y, int data, int nmsg){
00099 graph * ptr, *temp;
00100
00101 ptr = &(object_graph[x]);
00102
00103 temp = new graph;
00104
00105 temp->id = y;
00106 temp->data = data;
00107 temp->nmsg = nmsg;
00108 temp->next = ptr->next;
00109
00110 ptr->next = temp;
00111
00112 ptr = &(object_graph[y]);
00113
00114 temp = new graph;
00115
00116 temp->id = x;
00117 temp->data = data;
00118 temp->nmsg = nmsg;
00119 temp->next = ptr->next;
00120
00121 ptr->next = temp;
00122 }
00123
00124 static void init_data(int *assign, graph * object_graph, int l, int b){
00125 for(int obj=0;obj < b;obj++)
00126 assign[obj] = 0;
00127
00128 for(int j=0;j<b;j++){
00129 object_graph[j].data = 0;
00130 object_graph[j].nmsg = 0;
00131 object_graph[j].next = NULL;
00132 }
00133 }
00134
00135 void GreedyCommLB::work(LDStats* stats)
00136 {
00137 int pe,obj,com;
00138 ObjectRecord *x;
00139 int i;
00140
00141 if (_lb_args.debug()) CkPrintf("In GreedyCommLB strategy\n",CkMyPe());
00142 npe = stats->nprocs();
00143 nobj = stats->n_objs;
00144
00145
00146
00147 nmigobj = stats->n_migrateobjs;
00148
00149 stats->makeCommHash();
00150
00151 assigned_array = new int[nobj];
00152
00153 object_graph = new graph[nobj];
00154
00155 init_data(assigned_array,object_graph,npe,nobj);
00156
00157 #define MAXDOUBLE 1e10;
00158
00159
00160 processors = new processorInfo[npe];
00161 for (int p=0; p<npe; p++) {
00162 processors[p].Id = p;
00163 processors[p].backgroundLoad = stats->procs[p].bg_walltime;
00164 processors[p].computeLoad = 0;
00165 processors[p].pe_speed = stats->procs[p].pe_speed;
00166 if (!stats->procs[p].available) {
00167 processors[p].load = MAXDOUBLE;
00168 }
00169 else {
00170 processors[p].load = 0;
00171 if (!_lb_args.ignoreBgLoad())
00172 processors[p].load = processors[p].backgroundLoad;
00173 }
00174 }
00175
00176
00177
00178 for(com =0; com< stats->n_comm;com++) {
00179 int xcoord=0,ycoord=0;
00180 LDCommData &commData = stats->commData[com];
00181 if((!commData.from_proc())&&(commData.recv_type()==LD_OBJ_MSG))
00182 {
00183 xcoord = stats->getHash(commData.sender);
00184 ycoord = stats->getHash(commData.receiver.get_destObj());
00185 if((xcoord == -1)||(ycoord == -1))
00186 if (_lb_args.ignoreBgLoad() || stats->complete_flag==0) continue;
00187 else CkAbort("Error in search\n");
00188 add_graph(xcoord,ycoord,commData.bytes, commData.messages);
00189 }
00190 else if (commData.recv_type()==LD_OBJLIST_MSG) {
00191 int nobjs;
00192 LDObjKey *objs = commData.receiver.get_destObjs(nobjs);
00193 xcoord = stats->getHash(commData.sender);
00194 for (int i=0; i<nobjs; i++) {
00195 ycoord = stats->getHash(objs[i]);
00196 if((xcoord == -1)||(ycoord == -1))
00197 if (_lb_args.migObjOnly()) continue;
00198 else CkAbort("Error in search\n");
00199
00200 add_graph(xcoord,ycoord,commData.bytes, commData.messages);
00201 }
00202 }
00203 }
00204
00205
00206
00207 ObjectHeap maxh(nmigobj+1);
00208 for(obj=0; obj < stats->n_objs; obj++) {
00209 LDObjData &objData = stats->objData[obj];
00210 int onpe = stats->from_proc[obj];
00211 if (!objData.migratable) {
00212 if (!stats->procs[onpe].available) {
00213 CmiAbort("Load balancer is not be able to move a nonmigratable object out of an unavailable processor.\n");
00214 }
00215 alloc(onpe, obj, objData.wallTime);
00216 update(stats, obj, onpe);
00217 }
00218 else {
00219 x = new ObjectRecord;
00220 x->id = obj;
00221 x->pos = obj;
00222 x->val = objData.wallTime;
00223 x->pe = onpe;
00224 maxh.insert(x);
00225 }
00226 }
00227
00228 minHeap *lightProcessors = new minHeap(npe);
00229 for (i=0; i<npe; i++)
00230 if (stats->procs[i].available)
00231 lightProcessors->insert((InfoRecord *) &(processors[i]));
00232
00233 int id,maxid,minpe=0;
00234 double temp,total_time,min_temp;
00235
00236
00237
00238 double *pe_comm = new double[npe];
00239 for (int i=0; i<npe; i++) pe_comm[i] = 0.0;
00240
00241 for(id = 0;id<nmigobj;id++){
00242 x = maxh.deleteMax();
00243
00244 maxid = x->id;
00245
00246 processorInfo *donor = (processorInfo *) lightProcessors->deleteMin();
00247 CmiAssert(donor);
00248 int first_avail_pe = donor->Id;
00249 temp = compute_com(stats, maxid, first_avail_pe);
00250 min_temp = temp;
00251
00252 total_time = temp + donor->load;
00253 minpe = first_avail_pe;
00254
00255
00256
00257
00258 CkVec<int> commPes;
00259 graph * ptr = object_graph[maxid].next;
00260
00261
00262 double commload = 0.0;
00263 for(int com=0;(com<2*nobj)&&(ptr != NULL);com++,ptr=ptr->next){
00264 int destObj = ptr->id;
00265 if(assigned_array[destObj] == 0)
00266 continue;
00267 int destPe = stats->to_proc[destObj];
00268 if(stats->procs[destPe].available == 0) continue;
00269
00270 double cload = alpha*ptr->nmsg + beeta*ptr->data;
00271 pe_comm[destPe] += cload;
00272 commload += cload;
00273
00274 int exist = 0;
00275 for (int pp=0; pp<commPes.size(); pp++)
00276 if (destPe == commPes[pp]) { exist=1; break; }
00277 if (!exist) commPes.push_back(destPe);
00278 }
00279
00280 int k;
00281 for(k = 0; k < commPes.size(); k++){
00282 pe = commPes[k];
00283 processorInfo *commpe = (processorInfo *) &processors[pe];
00284
00285 temp = commload - pe_comm[pe];
00286
00287
00288 if(total_time > (temp + commpe->load)){
00289 minpe = pe;
00290 total_time = temp + commpe->load;
00291 min_temp = temp;
00292 }
00293 }
00294
00295
00296
00297 stats->assign(maxid, minpe);
00298
00299 alloc(minpe, maxid, x->val + min_temp);
00300
00301
00302 update(stats, maxid, minpe);
00303
00304
00305 lightProcessors->insert(donor);
00306 for(k = 0; k < commPes.size(); k++) {
00307 pe = commPes[k];
00308 processorInfo *commpe = (processorInfo *) &processors[pe];
00309 lightProcessors->update(commpe);
00310 pe_comm[pe] = 0.0;
00311 }
00312
00313 delete x;
00314 }
00315
00316
00317 delete [] pe_comm;
00318
00319 delete [] processors;
00320 delete [] assigned_array;
00321
00322 delete lightProcessors;
00323
00324 for(int oindex= 0; oindex < nobj; oindex++){
00325 graph * ptr = &object_graph[oindex];
00326 ptr = ptr->next;
00327
00328 while(ptr != NULL){
00329 graph *cur = ptr;
00330 ptr = ptr->next;
00331 delete cur;
00332 }
00333 }
00334 delete [] object_graph;
00335
00336 }
00337
00338 #include "GreedyCommLB.def.h"
00339