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