00001
00010
00011 #include "ScotchRefineLB.h"
00012 #include "ckgraph.h"
00013 #include "scotch.h"
00014
00015 CreateLBFunc_Def(ScotchRefineLB, "Load balancing using the Scotch graph partitioning library")
00016
00017 ScotchRefineLB::ScotchRefineLB(const CkLBOptions &opt) : CentralLB(opt) {
00018 lbname = "ScotchRefineLB";
00019 if(CkMyPe() == 0)
00020 CkPrintf("ScotchRefineLB created\n");
00021 }
00022
00023 CmiBool ScotchRefineLB::QueryBalanceNow(int _step) {
00024 return CmiTrue;
00025 }
00026
00027 void ScotchRefineLB::work(LDStats *stats) {
00029 ProcArray *parr = new ProcArray(stats);
00030 ObjGraph *ogr = new ObjGraph(stats);
00031 int cost_array[10] = {64, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
00032
00034
00035 SCOTCH_Num baseval = 0;
00036 SCOTCH_Num vertnbr = ogr->vertices.size();
00037 SCOTCH_Num edgenbr = 0;
00038
00039 SCOTCH_Num *oldpemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
00040
00041 double maxLoad = 0.0;
00042 double minLoad = 0.0;
00043 if (vertnbr > 0) {
00044 minLoad = ogr->vertices[baseval].getVertexLoad();
00045 }
00046
00047 long maxBytes = 1;
00048 int i, j, k, vert;
00049
00050
00052 for(i = baseval; i < vertnbr; i++) {
00053 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00054 vert = ogr->vertices[i].sendToList[j].getNeighborId();
00055 for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
00056 if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
00057 ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
00058 ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
00059 }
00060 }
00061 }
00062 }
00063
00065 for(i = baseval; i < vertnbr; i++) {
00066 if(ogr->vertices[i].getVertexLoad() > maxLoad)
00067 maxLoad = ogr->vertices[i].getVertexLoad();
00068
00069 if (ogr->vertices[i].getVertexLoad() < minLoad) {
00070 minLoad = ogr->vertices[i].getVertexLoad();
00071 }
00072 edgenbr += ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
00073 oldpemap[i] = ogr->vertices[i].getCurrentPe();
00074 }
00075
00076 for(i = baseval; i < vertnbr; i++) {
00077 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00078 if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
00079 maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
00080 }
00081 }
00082 for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
00083 if (ogr->vertices[i].recvFromList[j].getNumBytes() > maxBytes) {
00084 maxBytes = ogr->vertices[i].recvFromList[j].getNumBytes();
00085 }
00086 }
00087 }
00088
00089
00090 SCOTCH_Num *verttab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * (vertnbr+1));
00091
00092 SCOTCH_Num *velotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
00093
00094 SCOTCH_Num *edgetab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
00095
00096 SCOTCH_Num *edlotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
00097
00098 int edgeNum = 0;
00099 double ratio = 256.0/maxLoad;
00100 double byteRatio = 1024.0/maxBytes;
00101
00102 for(i = baseval; i < vertnbr; i++) {
00103 verttab[i] = edgeNum;
00104 velotab[i] = (int)ceil(ogr->vertices[i].getVertexLoad() * ratio);
00105 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00106 edgetab[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
00107 edlotab[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes()
00108 * byteRatio);
00109 edgeNum++;
00110 }
00111 for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
00112 edgetab[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
00113 edlotab[edgeNum] = (int)
00114 ceil(ogr->vertices[i].recvFromList[j].getNumBytes() * byteRatio);
00115 edgeNum++;
00116 }
00117 }
00118 verttab[i] = edgeNum;
00119 CkAssert(edgeNum == edgenbr);
00120
00121 SCOTCH_Graph graph;
00122 SCOTCH_Strat strat;
00123
00124
00125 SCOTCH_graphInit (&graph);
00126 SCOTCH_stratInit (&strat);
00127
00128 SCOTCH_graphBuild (&graph, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, edlotab);
00129 SCOTCH_graphCheck (&graph);
00130
00131 double migration_cost = 1024.0;
00132
00133 if (step() == 0) {
00134 SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE, parr->procs.size (), 0.01);
00135 } else {
00136 SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE | SCOTCH_STRATREMAP, parr->procs.size (), 0.01);
00137 }
00138
00139 SCOTCH_Num *pemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
00140
00141
00142
00143
00144 if (step() == 0) {
00145 SCOTCH_graphPart(&graph, parr->procs.size(), &strat, pemap);
00146 } else {
00147 SCOTCH_graphRepart(&graph, parr->procs.size(), oldpemap, migration_cost, NULL, &strat, pemap);
00148 }
00149
00150 SCOTCH_graphExit (&graph);
00151 SCOTCH_stratExit (&strat);
00152
00153 free(verttab);
00154 free(velotab);
00155 free(edgetab);
00156 free(edlotab);
00157
00158 for(i = baseval; i < vertnbr; i++) {
00159 if(pemap[i] != ogr->vertices[i].getCurrentPe())
00160 ogr->vertices[i].setNewPe(pemap[i]);
00161 }
00162
00163 free(pemap);
00164 free(oldpemap);
00166 ogr->convertDecisions(stats);
00167 delete parr;
00168 delete ogr;
00169 }
00170
00171 #include "ScotchRefineLB.def.h"
00172