00001
00013
00014 #include "ScotchTopoLB.h"
00015 #include "TopoManager.h"
00016 #include "ckgraph.h"
00017 #include <scotch.h>
00018
00019 extern int quietModeRequested;
00020
00021 CreateLBFunc_Def(ScotchTopoLB, "Load balancing using the Scotch graph partitioning library")
00022
00023 ScotchTopoLB::ScotchTopoLB(const CkLBOptions &opt) : CBase_ScotchTopoLB(opt) {
00024 lbname = "ScotchTopoLB";
00025 if(CkMyPe() == 0 && !quietModeRequested)
00026 CkPrintf("CharmLB> ScotchTopoLB created.\n");
00027 }
00028
00029 bool ScotchTopoLB::QueryBalanceNow(int _step) {
00030 return true;
00031 }
00032
00033 void ScotchTopoLB::work(LDStats *stats) {
00035 ProcArray *parr = new ProcArray(stats);
00036 ObjGraph *ogr = new ObjGraph(stats);
00037 TopoManager tmgr;
00038 double start_time = CmiWallTimer();
00039
00041
00042 SCOTCH_Num baseval = 0;
00043 SCOTCH_Num vertnbr = ogr->vertices.size();
00044 SCOTCH_Num edgenbr = 0;
00045
00046 double maxLoad = 0.0;
00047 double minLoad = 0.0;
00048 if (vertnbr > 0) {
00049 minLoad = ogr->vertices[baseval].getVertexLoad();
00050 }
00051
00052 long maxBytes = 1;
00053 int i, j, k, vert;
00054
00055
00057 for(i = baseval; i < vertnbr; i++) {
00058 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00059 vert = ogr->vertices[i].sendToList[j].getNeighborId();
00060 for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
00061 if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
00062 ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
00063 ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
00064 }
00065 }
00066 }
00067 }
00069 for(i = baseval; i < vertnbr; i++) {
00070 if(ogr->vertices[i].getVertexLoad() > maxLoad)
00071 maxLoad = ogr->vertices[i].getVertexLoad();
00072
00073 if (ogr->vertices[i].getVertexLoad() < minLoad) {
00074 minLoad = ogr->vertices[i].getVertexLoad();
00075 }
00076 edgenbr += ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
00077 }
00078
00079 for(i = baseval; i < vertnbr; i++) {
00080 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00081 if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
00082 maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
00083 }
00084 }
00085 for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
00086 if (ogr->vertices[i].recvFromList[j].getNumBytes() > maxBytes) {
00087 maxBytes = ogr->vertices[i].recvFromList[j].getNumBytes();
00088 }
00089 }
00090 }
00091
00092
00093
00094 SCOTCH_Num *verttab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * (vertnbr+1));
00095
00096 SCOTCH_Num *velotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
00097
00098 SCOTCH_Num *edgetab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
00099
00100 SCOTCH_Num *edlotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
00101
00102 int edgeNum = 0;
00103 double ratio = 256.0/maxLoad;
00104 double byteRatio = 1024.0/maxBytes;
00105
00106 for(i = baseval; i < vertnbr; i++) {
00107 verttab[i] = edgeNum;
00108 velotab[i] = (SCOTCH_Num) ceil(ogr->vertices[i].getVertexLoad() * ratio);
00109 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00110 edgetab[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
00111 edlotab[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes() * byteRatio);
00112 edgeNum++;
00113 }
00114 for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
00115 edgetab[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
00116 edlotab[edgeNum] = (int) 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_Arch arch;
00125 SCOTCH_Strat strat;
00126
00127
00128 SCOTCH_graphInit (&graph);
00129 SCOTCH_stratInit (&strat);
00130
00131 SCOTCH_graphBuild (&graph, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, edlotab);
00132 SCOTCH_graphCheck (&graph);
00133
00134
00135 SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE, parr->procs.size (), 0.01);
00136
00137 SCOTCH_Num *pemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
00138 SCOTCH_archInit (&arch);
00139 SCOTCH_archTorus3 (&arch, tmgr.getDimNX(), tmgr.getDimNY(), tmgr.getDimNZ());
00140
00141 SCOTCH_graphMap (&graph, &arch, &strat, pemap);
00142
00143 SCOTCH_graphExit (&graph);
00144 SCOTCH_archExit (&arch);
00145 SCOTCH_stratExit (&strat);
00146
00147 free(verttab);
00148 free(velotab);
00149 free(edgetab);
00150 free(edlotab);
00151 for(i = baseval; i < vertnbr; i++) {
00152 if(pemap[i] != ogr->vertices[i].getCurrentPe()) {
00153 ogr->vertices[i].setNewPe(pemap[i]);
00154 }
00155 }
00156
00157 free(pemap);
00159 ogr->convertDecisions(stats);
00160 delete ogr;
00161 }
00162
00163 #include "ScotchTopoLB.def.h"
00164