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