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