00001
00012
00013
00014 #include "ZoltanLB.h"
00015 #include "mpi.h"
00016 #include "ckgraph.h"
00017 #include "zoltan.h"
00018
00019 typedef struct {
00020 int numMyVertices;
00021
00022 ZOLTAN_ID_TYPE *vtxGID;
00023
00024 int *vtxWgt;
00025
00026 int numMyHEdges;
00027
00028 ZOLTAN_ID_TYPE *edgeGID;
00029 int *edgWgt;
00030
00031
00032 int *nborIndex;
00033
00034 ZOLTAN_ID_TYPE *nborGID;
00035
00036 int numAllNbors;
00037
00038 ProcArray *parr;
00039 ObjGraph *ogr;
00040 } HGRAPH_DATA;
00041
00042 static int get_number_of_vertices(void *data, int *ierr);
00043 static void get_vertex_list(void *data, int sizeGID, int sizeLID,
00044 ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
00045 int wgt_dim, float *obj_wgts, int *ierr);
00046 static void get_hypergraph_size(void *data, int *num_lists, int *num_nonzeroes,
00047 int *format, int *ierr);
00048 static void get_hypergraph(void *data, int sizeGID, int num_edges, int num_nonzeroes,
00049 int format, ZOLTAN_ID_PTR edgeGID, int *vtxPtr,
00050 ZOLTAN_ID_PTR vtxGID, int *ierr);
00051 static void get_hypergraph_edge_size(void *data, int *num_edges, int *ierr);
00052
00053 static void get_hypergraph_edge_wgts(void *data, int numGID, int numLID, int num_edges,
00054 int edge_weight_dim, ZOLTAN_ID_PTR edgeGID, ZOLTAN_ID_PTR edgeLID,
00055 float *edge_wgts, int *ierr);
00056
00057 extern int quietModeRequested;
00058
00059 CreateLBFunc_Def(ZoltanLB, "Use Zoltan(tm) to partition object graph")
00060
00061 ZoltanLB::ZoltanLB(const CkLBOptions &opt): CBase_ZoltanLB(opt)
00062 {
00063 lbname = "ZoltanLB";
00064 if (CkMyPe() == 0 && !quietModeRequested)
00065 CkPrintf("CharmLB> ZoltanLB created.\n");
00066 }
00067
00068 void ZoltanLB::work(LDStats* stats)
00069 {
00071 ProcArray *parr = new ProcArray(stats);
00072 ObjGraph *ogr = new ObjGraph(stats);
00073
00075 if (_lb_args.debug() >= 2) {
00076 CkPrintf("[%d] In ZoltanLB Strategy...\n", CkMyPe());
00077 }
00078
00079 int rc;
00080 float ver;
00081 struct Zoltan_Struct *zz;
00082 int changes, numGidEntries, numLidEntries, numImport, numExport;
00083 int myRank, numProcs;
00084 ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids;
00085 int *importProcs, *importToPart, *exportProcs, *exportToPart;
00086 int *parts;
00087
00088 HGRAPH_DATA hg;
00089
00090 hg.parr = parr;
00091 hg.ogr = ogr;
00092
00093 int numPes = parr->procs.size();
00094
00095 int numVertices = ogr->vertices.size();
00096 int numEdges = 0;
00097 int numAllNbors = 0;
00098 hg.numMyVertices = numVertices;
00099 hg.vtxGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numVertices);
00100 hg.vtxWgt = (int *)malloc(sizeof(int) * numVertices);
00101
00102 double maxLoad = 0.0;
00103 double maxBytes = 0.0;
00104 int i, j, k, vert;
00105
00107 for(i = 0; i < numVertices; i++) {
00108 hg.vtxGID[i] = (ZOLTAN_ID_TYPE) i;
00109
00110 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00111 vert = ogr->vertices[i].sendToList[j].getNeighborId();
00112 for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
00113 if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
00114 ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
00115 ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
00116 }
00117 }
00118 }
00119 }
00120
00122 for(i = 0; i < numVertices; i++) {
00123 if(ogr->vertices[i].getVertexLoad() > maxLoad)
00124 maxLoad = ogr->vertices[i].getVertexLoad();
00125 numEdges += ogr->vertices[i].sendToList.size();
00126 numEdges += ogr->vertices[i].mcastToList.size();
00127
00128 numAllNbors += 2 * ogr->vertices[i].sendToList.size();
00129 for (k = 0; k < ogr->vertices[i].mcastToList.size(); k++) {
00130 McastSrc mcast_src = ogr->vertices[i].mcastToList[k];
00131 numAllNbors += mcast_src.destList.size();
00132 numAllNbors++;
00133 }
00134 }
00135
00136 for(i = 0; i < numVertices; i++) {
00137 for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00138 if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
00139 maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
00140 }
00141 }
00142 }
00143
00144 hg.numMyHEdges = numEdges;
00145 hg.numAllNbors = numAllNbors;
00146 hg.edgeGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numEdges);
00147 hg.edgWgt = (int *)malloc(sizeof(int) * numEdges);
00148 hg.nborIndex = (int *)malloc(sizeof(int) * numEdges);
00149 hg.nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numAllNbors);
00150
00151 double ratio = 256.0/maxLoad;
00152 double byteRatio = 1024.0 / maxBytes;
00153 int edgeNum = 0;
00154 int index = 0;
00155
00156 for (i = 0; i < numVertices; i++) {
00157 hg.vtxWgt[i] = (int)ceil(ogr->vertices[i].getVertexLoad() * ratio);
00158
00159 for (j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
00160 hg.edgeGID[edgeNum] = edgeNum;
00161 hg.edgWgt[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes() * byteRatio);
00162 hg.nborIndex[edgeNum++] = index;
00163 hg.nborGID[index++] = i;
00164 hg.nborGID[index++] = ogr->vertices[i].sendToList[j].getNeighborId();
00165 }
00166
00167 for (j = 0; j < ogr->vertices[i].mcastToList.size(); j++) {
00168 hg.edgeGID[edgeNum] = edgeNum;
00169 hg.edgWgt[edgeNum] = (int) ceil(ogr->vertices[i].mcastToList[j].getNumBytes() * byteRatio);
00170 hg.nborIndex[edgeNum++] = index;
00171 McastSrc mcast_src = ogr->vertices[i].mcastToList[j];
00172
00173 hg.nborGID[index++] = i;
00174 for (k = 0; k < mcast_src.destList.size(); k++) {
00175
00176 hg.nborGID[index++] = mcast_src.destList[k];
00177 }
00178 }
00179 }
00180
00181 CkAssert(edgeNum == numEdges);
00182
00183 rc = Zoltan_Initialize(0, NULL, &ver);
00184 zz = Zoltan_Create(MPI_COMM_WORLD);
00185 char global_parts[10];
00186 sprintf(global_parts, "%d", numPes);
00187
00188 Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0");
00189 Zoltan_Set_Param(zz, "LB_METHOD", "HYPERGRAPH");
00190 Zoltan_Set_Param(zz, "HYPERGRAPH_PACKAGE", "PHG");
00191 Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
00192 Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1");
00193 Zoltan_Set_Param(zz, "RETURN_LISTS", "PART");
00194 Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "1");
00195 Zoltan_Set_Param(zz, "EDGE_WEIGHT_DIM", "1");
00196 Zoltan_Set_Param(zz, "NUM_GLOBAL_PARTS", global_parts);
00197 Zoltan_Set_Param(zz, "LB_APPROACH", "PARTITION");
00198
00199
00200
00201 Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &hg);
00202 Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &hg);
00203 Zoltan_Set_HG_Size_CS_Fn(zz, get_hypergraph_size, &hg);
00204 Zoltan_Set_HG_CS_Fn(zz, get_hypergraph, &hg);
00205 Zoltan_Set_HG_Size_Edge_Wts_Fn(zz, get_hypergraph_edge_size, &hg);
00206 Zoltan_Set_HG_Edge_Wts_Fn(zz, get_hypergraph_edge_wgts, &hg);
00207
00208
00209 rc = Zoltan_LB_Partition(zz,
00210 &changes,
00211 &numGidEntries,
00212 &numLidEntries,
00213 &numImport,
00214 &importGlobalGids,
00215 &importLocalGids,
00216 &importProcs,
00217 &importToPart,
00218 &numExport,
00219 &exportGlobalGids,
00220 &exportLocalGids,
00221 &exportProcs,
00222 &exportToPart);
00223
00224 if (rc != ZOLTAN_OK){
00225 CkPrintf("Zoltan exiting\n");
00226 Zoltan_Destroy(&zz);
00227 exit(0);
00228 }
00229
00230
00231 for(i = 0; i < numVertices; i++) {
00232 if(exportToPart[i] != ogr->vertices[i].getCurrentPe())
00233 ogr->vertices[i].setNewPe(exportToPart[i]);
00234 }
00235
00236
00237
00238
00239
00240
00241 Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids,
00242 &importProcs, &importToPart);
00243 Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids,
00244 &exportProcs, &exportToPart);
00245
00246 Zoltan_Destroy(&zz);
00247
00248
00249
00250
00251
00252 if (hg.numMyVertices > 0){
00253 free(hg.vtxGID);
00254 }
00255 if (hg.numMyHEdges > 0){
00256 free(hg.edgeGID);
00257 free(hg.nborIndex);
00258 if (hg.numAllNbors > 0){
00259 free(hg.nborGID);
00260 }
00261 }
00262
00263 ogr->convertDecisions(stats);
00264
00265 delete parr;
00266 delete ogr;
00267 }
00268
00269
00270
00271 static int get_number_of_vertices(void *data, int *ierr)
00272 {
00273 HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
00274 *ierr = ZOLTAN_OK;
00275 return hg->numMyVertices;
00276 }
00277
00278 static void get_vertex_list(void *data, int sizeGID, int sizeLID,
00279 ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
00280 int wgt_dim, float *obj_wgts, int *ierr)
00281 {
00282 int i;
00283
00284 HGRAPH_DATA *hg= (HGRAPH_DATA *)data;
00285 *ierr = ZOLTAN_OK;
00286
00287
00288
00289
00290
00291 for (i=0; i<hg->numMyVertices; i++){
00292 globalID[i] = hg->vtxGID[i];
00293 localID[i] = i;
00294 obj_wgts[i] = hg->vtxWgt[i];
00295 }
00296 }
00297
00298 static void get_hypergraph_size(void *data, int *num_lists, int *num_nonzeroes,
00299 int *format, int *ierr)
00300 {
00301 HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
00302 *ierr = ZOLTAN_OK;
00303
00304 *num_lists = hg->numMyHEdges;
00305 *num_nonzeroes = hg->numAllNbors;
00306
00307
00308
00309
00310
00311 *format = ZOLTAN_COMPRESSED_EDGE;
00312
00313 return;
00314 }
00315
00316 static void get_hypergraph(void *data, int sizeGID, int num_edges, int num_nonzeroes,
00317 int format, ZOLTAN_ID_PTR edgeGID, int *vtxPtr,
00318 ZOLTAN_ID_PTR vtxGID, int *ierr)
00319 {
00320 int i;
00321
00322 HGRAPH_DATA *hg = (HGRAPH_DATA *)data;
00323 *ierr = ZOLTAN_OK;
00324
00325 if ( (num_edges != hg->numMyHEdges) || (num_nonzeroes != hg->numAllNbors) ||
00326 (format != ZOLTAN_COMPRESSED_EDGE)) {
00327 *ierr = ZOLTAN_FATAL;
00328 return;
00329 }
00330
00331 for (i=0; i < num_edges; i++){
00332 edgeGID[i] = hg->edgeGID[i];
00333 vtxPtr[i] = hg->nborIndex[i];
00334 }
00335
00336 for (i=0; i < num_nonzeroes; i++){
00337 vtxGID[i] = hg->nborGID[i];
00338 }
00339
00340 return;
00341 }
00342
00343 static void get_hypergraph_edge_size(void *data, int *num_edges, int *ierr) {
00344 HGRAPH_DATA *hg = (HGRAPH_DATA *) data;
00345 *ierr = ZOLTAN_OK;
00346 *num_edges = hg->numMyHEdges;
00347 }
00348
00349 static void get_hypergraph_edge_wgts(void *data, int numGID, int numLID, int num_edges,
00350 int edge_weight_dim, ZOLTAN_ID_PTR edgeGID, ZOLTAN_ID_PTR edgeLID,
00351 float *edge_wgts, int *ierr) {
00352 int i;
00353 HGRAPH_DATA *hg = (HGRAPH_DATA *) data;
00354 *ierr = ZOLTAN_OK;
00355 for (i = 0; i < num_edges; i++) {
00356 edgeGID[i] = hg->edgeGID[i];
00357 edgeLID[i] = hg->edgeGID[i];
00358 edge_wgts[i] = hg->edgWgt[i];
00359 }
00360 }
00361
00362 #include "ZoltanLB.def.h"
00363