00001 
00010 
00011 #include "TeamLB.h"
00012 #include "ckgraph.h"
00013 #include <metis.h>
00014 
00015 extern int quietModeRequested;
00016 
00017 CreateLBFunc_Def(TeamLB, "Use Metis(tm) to partition object graph at two levels: team level and processor level")
00018 
00019 TeamLB::TeamLB(const CkLBOptions &opt): CBase_TeamLB(opt)
00020 {
00021   lbname = "TeamLB";
00022   if (CkMyPe() == 0 && !quietModeRequested)
00023     CkPrintf("CharmLB> TeamLB created.\n");
00024 
00025   
00026   teamSize = _lb_args.teamSize();
00027   numberTeams = CkNumPes() / teamSize;
00028 }
00029 
00047 void TeamLB::work(LDStats* stats)
00048 {
00050   ProcArray *parr = new ProcArray(stats);
00051   ObjGraph *ogr = new ObjGraph(stats);
00052 
00054   if (_lb_args.debug() >= 2) {
00055     CkPrintf("[%d] In TeamLB Strategy...\n", CkMyPe());
00056   }
00057 
00058   
00059   idx_t numVertices = ogr->vertices.size();       
00060   int numEdges = 0;                             
00061 
00062   double maxLoad = 0.0;
00063   int maxBytes = 0, i, j, k;
00064 
00067   for(i = 0; i < numVertices; i++) {
00068     if(ogr->vertices[i].getVertexLoad() > maxLoad)
00069       maxLoad = ogr->vertices[i].getVertexLoad();
00070     numEdges += ogr->vertices[i].sendToList.size();
00071     for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00072       if(ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes)
00073         maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
00074     }
00075   }
00076 
00077   
00078   idx_t *xadj = new idx_t[numVertices + 1];
00079   
00080   idx_t *adjncy = new idx_t[numEdges];
00081   
00082   idx_t *vwgt = new idx_t[numVertices];
00083   
00084   idx_t *adjwgt = new idx_t[numEdges];
00085 
00086   int edgeNum = 0;
00087 
00088   for(i = 0; i < numVertices; i++) {
00089     xadj[i] = edgeNum;
00090     vwgt[i] = (int)( (ogr->vertices[i].getVertexLoad() * 128) /maxLoad );
00091     for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00092       adjncy[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
00093       adjwgt[edgeNum] = (int)( (ogr->vertices[i].sendToList[j].getNumBytes() * 128) / maxBytes );
00094       edgeNum++;
00095     }
00096   }
00097   xadj[i] = edgeNum;
00098   CkAssert(edgeNum == numEdges);
00099 
00100   idx_t options[METIS_NOPTIONS];
00101   METIS_SetDefaultOptions(options);
00102   
00103   
00104   options[METIS_OPTION_NUMBERING] = 0;
00105 
00106   idx_t edgecut;          
00107   
00108   idx_t *pemap = new idx_t[numVertices];
00109 
00110   
00111   idx_t ncon = 1;
00112   real_t ubvec[ncon];
00113   
00114   ubvec[0] = 1.1;
00115 
00116   
00117   idx_t *vsize = NULL;
00118   
00119   
00120   
00121   real_t *tpwgts = NULL;
00122 
00123   if (_lb_args.debug() >= 1)
00124   CkPrintf("[%d] calling METIS_PartGraphRecursive.\n", CkMyPe());
00125 
00126   METIS_PartGraphRecursive(&numVertices, &ncon, xadj, adjncy, vwgt, vsize,
00127       adjwgt, &numberTeams, tpwgts, ubvec, options, &edgecut, pemap);
00128 
00129   idx_t *global_pemap = new idx_t[numVertices];
00130 
00131   
00132   if(teamSize > 1) {
00133     idx_t *team_xadj = new idx_t[numVertices + 1];
00134     idx_t *team_adjncy = new idx_t[numEdges];
00135     idx_t *team_vwgt = new idx_t[numVertices];
00136     idx_t *team_adjwgt = new idx_t[numEdges];
00137     idx_t *team_pemap = new idx_t[numVertices];
00138     idx_t *team_vsize = NULL;
00139     real_t *team_tpwgts = NULL;
00140 
00141     idx_t teamEdgecut, node;
00142     int *mapping = new int[numVertices];
00143     int *invMapping = new int[numVertices];
00144 
00145     
00146     for(i=0; i<numberTeams; i++) {
00147       idx_t teamMembers = 0;    
00148 
00149       
00150       
00151       
00152       for(j = 0; j < numVertices; j++) {
00153     if(pemap[j] == i) {
00154       mapping[teamMembers] = j;
00155       invMapping[j] = teamMembers;
00156       team_vwgt[teamMembers] = vwgt[j];
00157       teamMembers++;
00158     }
00159       }
00160 
00161       
00162       int teamIndex = 0;
00163       for(j = 0; j < teamMembers; j++) {
00164     team_xadj[j] = teamIndex;
00165     for(k = xadj[mapping[j]]; k < xadj[mapping[j]+1]; k++) {
00166       node = adjncy[k];
00167       if(pemap[node] == i) {
00168         team_adjncy[teamIndex] = invMapping[node];
00169         team_adjwgt[teamIndex] = adjwgt[k];
00170         teamIndex++;
00171       }
00172     }
00173       }
00174       team_xadj[teamMembers] = teamIndex;
00175 
00176       
00177       METIS_PartGraphRecursive(&teamMembers, &ncon, team_xadj, team_adjncy,
00178         team_vwgt, team_vsize, team_adjwgt, &teamSize, team_tpwgts, ubvec,
00179         options, &teamEdgecut, team_pemap);
00180 
00181       
00182       for(j = 0; j < teamMembers; j++) {
00183     global_pemap[mapping[j]] = i*teamSize + team_pemap[j];
00184       }
00185             
00186     } 
00187 
00188     delete[] team_xadj;
00189     delete[] team_adjncy;
00190     delete[] team_vwgt;
00191     delete[] team_adjwgt;
00192     delete[] team_pemap;
00193     delete[] team_vsize;
00194     delete[] team_tpwgts;
00195 
00196     delete[] mapping;
00197     delete[] invMapping;
00198   } else {
00199     delete[] global_pemap;
00200     global_pemap = pemap;
00201   }
00202 
00203   delete[] xadj;
00204   delete[] adjncy;
00205   delete[] vwgt;
00206   delete[] adjwgt;
00207   delete[] vsize;
00208   delete[] tpwgts;
00209 
00210 
00211   if (_lb_args.debug() >= 1) {
00212    CkPrintf("[%d] TeamLB done! \n", CkMyPe());
00213   }
00214 
00215   for(i = 0; i < numVertices; i++) {
00216     if(pemap[i] != ogr->vertices[i].getCurrentPe())
00217       ogr->vertices[i].setNewPe(pemap[i]);
00218   }
00219 
00220   delete[] pemap;
00221 
00223   ogr->convertDecisions(stats);
00224 }
00225 
00226 #include "TeamLB.def.h"
00227