00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <metis.h>
00015
00016
00017
00018
00019
00020 void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts,
00021 floattype *ubvec)
00022 {
00023
00024 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
00025
00026
00027 MocComputeKWayPartitionParams(ctrl, graph, nparts);
00028
00029 for (;;) {
00030 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
00031
00032 if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
00033 MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
00034 MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4);
00035 ComputeKWayBoundary(ctrl, graph, nparts);
00036 }
00037
00038 MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10);
00039
00040 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
00041
00042 if (graph == orggraph)
00043 break;
00044
00045 graph = graph->finer;
00046 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
00047 MocProjectKWayPartition(ctrl, graph, nparts);
00048 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
00049 }
00050
00051 if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
00052 MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
00053 MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4);
00054 ComputeKWayBoundary(ctrl, graph, nparts);
00055 MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10);
00056 }
00057
00058 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
00068 {
00069 int nvtxs, ncon, pad64;
00070
00071 nvtxs = graph->nvtxs;
00072 ncon = graph->ncon;
00073
00074 pad64 = (3*nvtxs+nparts)%2;
00075
00076 graph->rdata = idxmalloc(3*nvtxs+ncon*nparts+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata");
00077 graph->npwgts = (floattype *)graph->rdata;
00078 graph->where = graph->rdata + ncon*nparts;
00079 graph->bndptr = graph->rdata + nvtxs + ncon*nparts;
00080 graph->bndind = graph->rdata + 2*nvtxs + ncon*nparts;
00081 graph->rinfo = (RInfoType *)(graph->rdata + 3*nvtxs+ncon*nparts + pad64);
00082 }
00083
00084
00085
00086
00087
00088 void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
00089 {
00090 int i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other;
00091 idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr;
00092 RInfoType *rinfo, *myrinfo;
00093 EDegreeType *myedegrees;
00094 floattype *nvwgt, *npwgts;
00095
00096 nvtxs = graph->nvtxs;
00097 ncon = graph->ncon;
00098 xadj = graph->xadj;
00099 nvwgt = graph->nvwgt;
00100 adjncy = graph->adjncy;
00101 adjwgt = graph->adjwgt;
00102
00103 where = graph->where;
00104 npwgts = sset(ncon*nparts, 0.0, graph->npwgts);
00105 bndind = graph->bndind;
00106 bndptr = idxset(nvtxs, -1, graph->bndptr);
00107 rinfo = graph->rinfo;
00108
00109
00110
00111
00112
00113 ctrl->wspace.cdegree = 0;
00114 nbnd = mincut = 0;
00115 for (i=0; i<nvtxs; i++) {
00116 me = where[i];
00117 saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
00118
00119 myrinfo = rinfo+i;
00120 myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
00121 myrinfo->edegrees = NULL;
00122
00123 for (j=xadj[i]; j<xadj[i+1]; j++) {
00124 if (me != where[adjncy[j]])
00125 myrinfo->ed += adjwgt[j];
00126 }
00127 myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed;
00128
00129 if (myrinfo->ed > 0)
00130 mincut += myrinfo->ed;
00131
00132 if (myrinfo->ed-myrinfo->id >= 0)
00133 BNDInsert(nbnd, bndind, bndptr, i);
00134
00135
00136 if (myrinfo->ed > 0) {
00137 myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
00138 ctrl->wspace.cdegree += xadj[i+1]-xadj[i];
00139
00140 for (j=xadj[i]; j<xadj[i+1]; j++) {
00141 other = where[adjncy[j]];
00142 if (me != other) {
00143 for (k=0; k<myrinfo->ndegrees; k++) {
00144 if (myedegrees[k].pid == other) {
00145 myedegrees[k].ed += adjwgt[j];
00146 break;
00147 }
00148 }
00149 if (k == myrinfo->ndegrees) {
00150 myedegrees[myrinfo->ndegrees].pid = other;
00151 myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
00152 }
00153 }
00154 }
00155
00156 ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]);
00157 }
00158 }
00159
00160 graph->mincut = mincut/2;
00161 graph->nbnd = nbnd;
00162
00163 }
00164
00165
00166
00167
00168
00169
00170
00171 void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
00172 {
00173 int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees;
00174 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
00175 idxtype *cmap, *where, *bndptr, *bndind;
00176 idxtype *cwhere;
00177 GraphType *cgraph;
00178 RInfoType *crinfo, *rinfo, *myrinfo;
00179 EDegreeType *myedegrees;
00180 idxtype *htable;
00181
00182 cgraph = graph->coarser;
00183 cwhere = cgraph->where;
00184 crinfo = cgraph->rinfo;
00185
00186 nvtxs = graph->nvtxs;
00187 cmap = graph->cmap;
00188 xadj = graph->xadj;
00189 adjncy = graph->adjncy;
00190 adjwgt = graph->adjwgt;
00191 adjwgtsum = graph->adjwgtsum;
00192
00193 MocAllocateKWayPartitionMemory(ctrl, graph, nparts);
00194 where = graph->where;
00195 rinfo = graph->rinfo;
00196 bndind = graph->bndind;
00197 bndptr = idxset(nvtxs, -1, graph->bndptr);
00198
00199
00200 for (i=0; i<nvtxs; i++) {
00201 k = cmap[i];
00202 where[i] = cwhere[k];
00203 cmap[i] = crinfo[k].ed;
00204 }
00205
00206 htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts));
00207
00208 ctrl->wspace.cdegree = 0;
00209 for (nbnd=0, i=0; i<nvtxs; i++) {
00210 me = where[i];
00211
00212 myrinfo = rinfo+i;
00213 myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0;
00214 myrinfo->edegrees = NULL;
00215
00216 myrinfo->id = adjwgtsum[i];
00217
00218 if (cmap[i] > 0) {
00219 istart = xadj[i];
00220 iend = xadj[i+1];
00221
00222 myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
00223 ctrl->wspace.cdegree += iend-istart;
00224
00225 ndegrees = 0;
00226 for (j=istart; j<iend; j++) {
00227 other = where[adjncy[j]];
00228 if (me != other) {
00229 myrinfo->ed += adjwgt[j];
00230 if ((k = htable[other]) == -1) {
00231 htable[other] = ndegrees;
00232 myedegrees[ndegrees].pid = other;
00233 myedegrees[ndegrees++].ed = adjwgt[j];
00234 }
00235 else {
00236 myedegrees[k].ed += adjwgt[j];
00237 }
00238 }
00239 }
00240 myrinfo->id -= myrinfo->ed;
00241
00242
00243 if (myrinfo->ed == 0) {
00244 myrinfo->edegrees = NULL;
00245 ctrl->wspace.cdegree -= iend-istart;
00246 }
00247 else {
00248 if (myrinfo->ed-myrinfo->id >= 0)
00249 BNDInsert(nbnd, bndind, bndptr, i);
00250
00251 myrinfo->ndegrees = ndegrees;
00252
00253 for (j=0; j<ndegrees; j++)
00254 htable[myedegrees[j].pid] = -1;
00255 }
00256 }
00257 }
00258
00259 scopy(graph->ncon*nparts, cgraph->npwgts, graph->npwgts);
00260 graph->mincut = cgraph->mincut;
00261 graph->nbnd = nbnd;
00262
00263 FreeGraph(graph->coarser);
00264 graph->coarser = NULL;
00265
00266 idxwspacefree(ctrl, nparts);
00267
00268 ASSERT(CheckBnd2(graph));
00269
00270 }
00271
00272
00273
00274
00275
00276
00277 void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
00278 {
00279 int i, nvtxs, nbnd;
00280 idxtype *bndind, *bndptr;
00281
00282 nvtxs = graph->nvtxs;
00283 bndind = graph->bndind;
00284 bndptr = idxset(nvtxs, -1, graph->bndptr);
00285
00286
00287
00288 nbnd = 0;
00289 for (i=0; i<nvtxs; i++) {
00290 if (graph->rinfo[i].ed > 0)
00291 BNDInsert(nbnd, bndind, bndptr, i);
00292 }
00293
00294 graph->nbnd = nbnd;
00295 }
00296