1 /***********************************
4 ************************************/
12 #define PREF_RET_SIZE 5
14 TopologyAgent::TopologyAgent(CentralLB::LDStats* lbDB,int p): stats(lbDB), Agent(p){
18 topofn = LBTopoLookup(_lbtopo);
21 CmiPrintf("LBAgent> Fatal error: Unknown topology: %s. Choose from:\n", _lbtopo);
23 sprintf(str, "LBAgent> Fatal error: Unknown topology: %s", _lbtopo);
28 stats->makeCommHash();
29 preferred_list = new Elem[p];
30 commObjs = new int*[stats->n_objs];
31 for(i=0;i<stats->n_objs;i++){
32 commObjs[i] = new int[stats->n_objs];
33 for(int j=0;j<stats->n_objs;j++)
37 hopCount = new int*[npes];
39 hopCount[i] = new int[npes];
40 for(int j=0;j<npes;j++)
45 for(i=0;i<stats->n_comm;i++){
46 //DO I consider other comm too....i.e. to or from a processor
47 //CkPrintf("in loop..\n");
48 LDCommData &cdata = stats->commData[i];
49 if(cdata.from_proc() || cdata.receiver.get_type() != LD_OBJ_MSG)
51 int senderID = stats->getHash(cdata.sender);
52 CmiAssert(senderID < stats->n_objs);
53 int recverID = stats->getHash(cdata.receiver.get_destObj());
54 CmiAssert(recverID < stats->n_objs);
56 //Check with Gengbin if 2 different commData have the same pair of processors as role reversed
57 //for(int j=0;j<num_comm;j++)
59 commObjs[senderID][recverID] += cdata.bytes;
60 commObjs[recverID][senderID] += cdata.bytes;
64 int TopologyAgent :: compare(const void *p,const void *q){
65 return (int)(((Elem*)p)->Cost - ((Elem*)q)->Cost);
69 Agent::Elem* TopologyAgent :: my_preferred_procs(int *existing_map,int object,int *trialpes,int metric) {
74 //int *preferred_list;
75 //CkPrintf("npes:%d\n",npes);
76 for(int i=0;i<npes;i++){
77 preferred_list[i].pe = -1;
78 preferred_list[i].Cost = 0;
83 if(metric==1){ //First metric
84 //CkPrintf("in first metric\n");
85 if(trialpes == NULL) {
90 procs_list = trialpes;
92 //Before everything...construct a list of comm of this object with all the other objects
98 proc = procs_list[index];
102 if(!stats->procs[proc].available){
103 if(procs_list[0]==-1){
110 if(procs_list[index] == -1)
112 proc = procs_list[index];
117 //First metric --- hops*bytes
118 for(int i=0;i<stats->n_objs;i++){
119 if(existing_map[i]!=-1 && commObjs[object][i]!=0){
120 //CkPrintf("before calling get hop count..proc:%d,existing map:%d\n",proc,existing_map[comm[i].obj]);
121 if(hopCount[proc][existing_map[i]])
122 cost += hopCount[proc][existing_map[i]]*commObjs[object][i];
124 hopCount[proc][existing_map[i]]=topo->get_hop_count(proc,existing_map[i]);
125 hopCount[existing_map[i]][proc]=hopCount[proc][existing_map[i]];
126 cost += hopCount[proc][existing_map[i]]*commObjs[object][i];
130 preferred_list[preflistSize].pe = proc;
131 preferred_list[preflistSize].Cost = cost;
134 if(procs_list[0]==-1){
141 if(procs_list[index] == -1)
143 proc = procs_list[index];
149 //Second metric --- place the object closer to maximum comm. processor
151 int max_neighbors = topo->max_neighbors();
152 int *comProcs = new int[npes];
158 for(i=0;i<stats->n_objs;i++){
159 if(existing_map[i]!=-1 && commObjs[object][i]!=0){
160 comProcs[existing_map[i]] += commObjs[object][i];
161 if(comProcs[existing_map[i]] > max_comm){
162 max_comm = comProcs[existing_map[i]];
163 max_proc = existing_map[i];
171 while(trialpes[i]!=-1){
172 if(max_proc==trialpes[i]){
173 preferred_list[0].pe = max_proc;
174 preferred_list[0].Cost = max_comm;
180 neigh = new int[max_neighbors];
181 topo->neighbors(max_proc,neigh,num_neigh);
182 while(trialpes[i]!=-1){
183 for(j=0;j<num_neigh;j++)
184 if(trialpes[i]==neigh[j]){
185 preferred_list[preflistSize].pe = neigh[j];
186 preferred_list[preflistSize].Cost = comProcs[neigh[j]];
193 int *secondneigh = new int[max_neighbors];
198 topo->neighbors(neigh[k],secondneigh,num_neigh);
199 while(trialpes[i]!=-1){
200 for(j=0;j<num_neigh;j++)
201 if(trialpes[i]==secondneigh[j]){
202 preferred_list[preflistSize].pe = secondneigh[j];
203 preferred_list[preflistSize].Cost = comProcs[secondneigh[j]];
213 /***************************************************************************/
215 //Third metric -- as sugggested by Sanjay
217 //Sort all the elements of the preferred list in increasing order
218 Agent::Elem *prefreturnList = new Elem[PREF_RET_SIZE+1];
219 int *taken_proc = new int[preflistSize];
220 double min_cost=preferred_list[0].Cost;
221 int min_cost_index=0;
223 //prefreturnList[0].pe=preferred_list[min_cost_index].pe;
224 //prefreturnList[0].Cost=preferred_list[min_cost_index].Cost;
230 for(s=0;s<preflistSize;s++)
232 for(s=0;s<PREF_RET_SIZE;s++){
233 for(u=0;u<preflistSize;u++)
235 min_cost=preferred_list[u].Cost;
241 for(int t=u;t<preflistSize;t++){
242 if(preferred_list[t].Cost <= min_cost && !taken_proc[t]){
243 min_cost = preferred_list[t].Cost;
249 taken_proc[min_cost_index]=1;
250 prefreturnList[s].pe=preferred_list[min_cost_index].pe;
251 prefreturnList[s].Cost=preferred_list[min_cost_index].Cost;
255 prefreturnList[s].pe=-1;
256 prefreturnList[s].Cost=-1;
257 //qsort(preferred_list,preflistSize,sizeof(Elem),&compare);
258 //for(int k=0;k<preflistSize;k++)
259 //CkPrintf("pe:%d cost:%d\n",preferred_list[k].pe,preferred_list[k].Cost);
261 return prefreturnList;
262 //return preferred_list;
265 /*****************************************************************************
267 *****************************************************************************/
269 MulticastAgent::MulticastAgent(BaseLB::LDStats* stats, int p): Agent(p)
271 stats->makeCommHash();
272 // build multicast knowledge
273 nobj = stats->n_objs;
274 objmap = new CkVec<int> [nobj];
275 for (int com = 0; com < stats->n_comm;com++) {
276 LDCommData &commData = stats->commData[com];
277 if (commData.recv_type()!=LD_OBJLIST_MSG) continue;
278 // create a multicast instance
279 mcastList.push_back(MInfo(commData.bytes, commData.messages));
280 int mID = mcastList.size()-1;
281 MInfo &minfo = mcastList[mID];
282 int sender = stats->getHash(commData.sender);
283 // stores all multicast that this object (sender) participated
284 objmap[sender].push_back(mID);
285 // stores all objects that belong to this multicast
286 minfo.objs.push_back(sender);
288 LDObjKey *objs = commData.receiver.get_destObjs(nobjs);
289 for (int i=0; i<nobjs; i++) {
290 int receiver = stats->getHash(objs[i]);
291 if((sender == -1)||(receiver == -1)) {
292 if (_lb_args.migObjOnly()) continue;
293 else CkAbort("Error in search\n");
295 objmap[receiver].push_back(mID);
296 minfo.objs.push_back(receiver);
301 Agent::Elem* MulticastAgent::my_preferred_procs(int *existing_map,int object,int *trialpes,int metric){
303 // check all multicast this object participated
304 CmiAssert(object < nobj);
306 double * comcosts = new double [npes];
307 memset(comcosts, 0, sizeof(double)*npes);
308 double alpha = _lb_args.alpha();
309 double beta = _lb_args.beta();
311 // all multicast this object belongs to
312 CkVec<int> &mlist = objmap[object];
313 // traverse all multicast participated
314 // find out which processor it communicates the most
315 for (i=0; i<mlist.size(); i++) {
316 MInfo &minfo = mcastList[mlist[i]];
317 for (int obj=0; obj<minfo.objs.size(); obj++) {
318 int pe = existing_map[obj];
319 if (pe == -1) continue; // not assigned yet
320 comcosts[pe] += minfo.messages * alpha + minfo.nbytes * beta;
323 // find number of processors with non-0 cost
325 for (i=0; i<npes; i++) {
326 if (comcosts[i] != 0.0) count++;
328 Elem *prefered = new Elem[count+1];
329 for (i=0; i<count; i++) {
331 Elem maxp; // cost default -1
332 for (int j=0; j<npes; j++)
333 if (comcosts[j] != 0.0 && comcosts[j] > maxp.Cost) {
335 maxp.Cost = comcosts[j];
337 CmiAssert(maxp.pe!=-1);
339 comcosts[maxp.pe] = 0.0;