00001
00010
00011 #include "MetisLB.h"
00012 #include "ckgraph.h"
00013 #include "metis.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 CreateLBFunc_Def(MetisLB, "Use Metis(tm) to partition object graph")
00037
00038 MetisLB::MetisLB(const CkLBOptions &opt): CentralLB(opt)
00039 {
00040 lbname = "MetisLB";
00041 if (CkMyPe() == 0)
00042 CkPrintf("[%d] MetisLB created\n",CkMyPe());
00043 }
00044
00045 void MetisLB::work(LDStats* stats)
00046 {
00048 ProcArray *parr = new ProcArray(stats);
00049 ObjGraph *ogr = new ObjGraph(stats);
00050
00052 if (_lb_args.debug() >= 2) {
00053 CkPrintf("[%d] In MetisLB Strategy...\n", CkMyPe());
00054 }
00055
00056
00057 int numVertices = ogr->vertices.size();
00058 int numEdges = 0;
00059
00060 double maxLoad = 0.0;
00061 int i, j, k, vert;
00062
00064 for(i = 0; i < numVertices; i++) {
00065 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00066 vert = ogr->vertices[i].sendToList[j].getNeighborId();
00067 for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
00068 if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
00069 ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
00070 ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
00071 }
00072 }
00073 }
00074 }
00075
00077 for(i = 0; i < numVertices; i++) {
00078 if(ogr->vertices[i].getVertexLoad() > maxLoad)
00079 maxLoad = ogr->vertices[i].getVertexLoad();
00080 numEdges = numEdges + ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
00081 }
00082
00083
00084 idxtype *xadj = new idxtype[numVertices + 1];
00085
00086 idxtype *adjncy = new idxtype[numEdges];
00087
00088 idxtype *vwgt = new idxtype[numVertices];
00089
00090 idxtype *adjwgt = new idxtype[numEdges];
00091
00092 int edgeNum = 0;
00093 double ratio = 256.0/maxLoad;
00094
00095 for(i = 0; i < numVertices; i++) {
00096 xadj[i] = edgeNum;
00097 vwgt[i] = (int)ceil(ogr->vertices[i].getVertexLoad() * ratio);
00098 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00099 adjncy[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
00100 adjwgt[edgeNum] = ogr->vertices[i].sendToList[j].getNumBytes();
00101 edgeNum++;
00102 }
00103 for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
00104 adjncy[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
00105 adjwgt[edgeNum] = ogr->vertices[i].recvFromList[j].getNumBytes();
00106 edgeNum++;
00107 }
00108 }
00109 xadj[i] = edgeNum;
00110 CkAssert(edgeNum == numEdges);
00111
00112 int wgtflag = 3;
00113 int numflag = 0;
00114 int options[5];
00115 options[0] = 0;
00116 int edgecut;
00117 idxtype *pemap;
00118
00119 int option = 0;
00120 int numPes = parr->procs.size();
00121 pemap = new idxtype[numVertices];
00122
00123 if (0 == option) {
00132
00133
00134
00135
00136
00137
00138
00139 METIS_PartGraphRecursive(&numVertices, xadj, adjncy, vwgt, adjwgt,
00140 &wgtflag, &numflag, &numPes, options, &edgecut, pemap);
00141 } else if (WEIGHTED == option) {
00142
00143 float *tpwgts = new float[numPes];
00144 for (i = 0; i < numPes; i++) {
00145 tpwgts[i] = 1.0/(float)numPes;
00146 }
00147
00148 if (numPes > 8)
00149 METIS_WPartGraphKway(&numVertices, xadj, adjncy, vwgt, adjwgt,
00150 &wgtflag, &numflag, &numPes, tpwgts, options, &edgecut, pemap);
00151 else
00152 METIS_WPartGraphRecursive(&numVertices, xadj, adjncy, vwgt, adjwgt,
00153 &wgtflag, &numflag, &numPes, tpwgts, options, &edgecut, pemap);
00154 delete[] tpwgts;
00155 } else if (MULTI_CONSTRAINT == option) {
00156 CkPrintf("Metis load balance strategy: ");
00157 CkPrintf("multiple constraints not implemented yet.\n");
00158 }
00159
00160 delete[] xadj;
00161 delete[] adjncy;
00162 delete[] vwgt;
00163 delete[] adjwgt;
00164
00165 if (_lb_args.debug() >= 1) {
00166 CkPrintf("[%d] MetisLB done! \n", CkMyPe());
00167 }
00168
00169 for(i = 0; i < numVertices; i++) {
00170 if(pemap[i] != ogr->vertices[i].getCurrentPe())
00171 ogr->vertices[i].setNewPe(pemap[i]);
00172 }
00173
00174 delete[] pemap;
00175
00177 ogr->convertDecisions(stats);
00178 delete parr;
00179 delete ogr;
00180 }
00181
00182 #include "MetisLB.def.h"
00183