00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <metis.h>
00017
00018
00019
00020
00021 void MocInit2WayPartition2(CtrlType *ctrl, GraphType *graph, floattype *tpwgts, floattype *ubvec)
00022 {
00023 int dbglvl;
00024
00025 dbglvl = ctrl->dbglvl;
00026 IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE);
00027 IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO);
00028
00029 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
00030
00031 switch (ctrl->IType) {
00032 case IPART_GGPKL:
00033 case IPART_RANDOM:
00034 MocGrowBisection2(ctrl, graph, tpwgts, ubvec);
00035 break;
00036 case 3:
00037 MocGrowBisectionNew2(ctrl, graph, tpwgts, ubvec);
00038 break;
00039 default:
00040 errexit("Unknown initial partition type: %d\n", ctrl->IType);
00041 }
00042
00043 IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut));
00044 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
00045 ctrl->dbglvl = dbglvl;
00046
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 void MocGrowBisection2(CtrlType *ctrl, GraphType *graph, floattype *tpwgts, floattype *ubvec)
00058 {
00059 int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs;
00060 idxtype *bestwhere, *where;
00061
00062 nvtxs = graph->nvtxs;
00063
00064 MocAllocate2WayPartitionMemory(ctrl, graph);
00065 where = graph->where;
00066
00067 bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
00068 nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
00069 bestcut = idxsum(graph->nedges, graph->adjwgt);
00070
00071 for (; nbfs>0; nbfs--) {
00072 idxset(nvtxs, 1, where);
00073 where[RandomInRange(nvtxs)] = 0;
00074
00075 MocCompute2WayPartitionParams(ctrl, graph);
00076
00077 MocBalance2Way2(ctrl, graph, tpwgts, ubvec);
00078
00079 MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4);
00080
00081 MocBalance2Way2(ctrl, graph, tpwgts, ubvec);
00082 MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4);
00083
00084 if (bestcut > graph->mincut) {
00085 bestcut = graph->mincut;
00086 idxcopy(nvtxs, where, bestwhere);
00087 if (bestcut == 0)
00088 break;
00089 }
00090 }
00091
00092 graph->mincut = bestcut;
00093 idxcopy(nvtxs, bestwhere, where);
00094
00095 GKfree(&bestwhere, LTERM);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void MocGrowBisectionNew2(CtrlType *ctrl, GraphType *graph, floattype *tpwgts, floattype *ubvec)
00109 {
00110 int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs;
00111 idxtype *bestwhere, *where;
00112
00113 nvtxs = graph->nvtxs;
00114
00115 MocAllocate2WayPartitionMemory(ctrl, graph);
00116 where = graph->where;
00117
00118 bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere");
00119 nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);
00120 bestcut = idxsum(graph->nedges, graph->adjwgt);
00121
00122 for (; nbfs>0; nbfs--) {
00123 idxset(nvtxs, 1, where);
00124 where[RandomInRange(nvtxs)] = 0;
00125
00126 MocCompute2WayPartitionParams(ctrl, graph);
00127
00128 MocInit2WayBalance2(ctrl, graph, tpwgts, ubvec);
00129
00130 MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4);
00131
00132 if (bestcut > graph->mincut) {
00133 bestcut = graph->mincut;
00134 idxcopy(nvtxs, where, bestwhere);
00135 if (bestcut == 0)
00136 break;
00137 }
00138 }
00139
00140 graph->mincut = bestcut;
00141 idxcopy(nvtxs, bestwhere, where);
00142
00143 GKfree(&bestwhere, LTERM);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void MocInit2WayBalance2(CtrlType *ctrl, GraphType *graph, floattype *tpwgts, floattype *ubvec)
00157 {
00158 int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp, imin;
00159 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
00160 idxtype *moved, *perm, *qnum;
00161 floattype *nvwgt, *npwgts, minwgt;
00162 PQueueType parts[MAXNCON][2];
00163 int higain, oldgain, mincut;
00164
00165 nvtxs = graph->nvtxs;
00166 ncon = graph->ncon;
00167 xadj = graph->xadj;
00168 adjncy = graph->adjncy;
00169 nvwgt = graph->nvwgt;
00170 adjwgt = graph->adjwgt;
00171 where = graph->where;
00172 id = graph->id;
00173 ed = graph->ed;
00174 npwgts = graph->npwgts;
00175 bndptr = graph->bndptr;
00176 bndind = graph->bndind;
00177
00178 moved = idxwspacemalloc(ctrl, nvtxs);
00179 perm = idxwspacemalloc(ctrl, nvtxs);
00180 qnum = idxwspacemalloc(ctrl, nvtxs);
00181
00182
00183 from = 1;
00184 to = (from+1)%2;
00185
00186 if (ctrl->dbglvl&DBG_REFINE) {
00187 printf("Parts: [");
00188 for (l=0; l<ncon; l++)
00189 printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
00190 printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
00191 }
00192
00193 for (i=0; i<ncon; i++) {
00194 PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1);
00195 PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1);
00196 }
00197
00198 idxset(nvtxs, -1, moved);
00199
00200 ASSERT(ComputeCut(graph, where) == graph->mincut);
00201 ASSERT(CheckBnd(graph));
00202 ASSERT(CheckGraph(graph));
00203
00204
00205 for (i=0; i<nvtxs; i++)
00206 qnum[i] = samax(ncon, nvwgt+i*ncon);
00207
00208
00209 RandomPermute(nvtxs, perm, 1);
00210 for (ii=0; ii<nvtxs; ii++) {
00211 i = perm[ii];
00212 if (where[i] == from) {
00213 if (ed[i] > 0)
00214 PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]);
00215 else
00216 PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]);
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 imin = 0;
00227 for (i=1; i<ncon; i++)
00228 imin = (ubvec[i] < ubvec[imin] ? i : imin);
00229 minwgt = .5/ubvec[imin];
00230
00231 mincut = graph->mincut;
00232 nbnd = graph->nbnd;
00233 for (nswaps=0; nswaps<nvtxs; nswaps++) {
00234
00235 if (npwgts[to*ncon+imin] > minwgt)
00236 break;
00237
00238 if ((cnum = SelectQueueOneWay2(ncon, npwgts+to*ncon, parts, ubvec)) == -1)
00239 break;
00240
00241 if ((higain = PQueueGetMax(&parts[cnum][0])) == -1)
00242 higain = PQueueGetMax(&parts[cnum][1]);
00243
00244 mincut -= (ed[higain]-id[higain]);
00245 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
00246 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
00247
00248 where[higain] = to;
00249 moved[higain] = nswaps;
00250
00251 if (ctrl->dbglvl&DBG_MOVEINFO) {
00252 printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut);
00253 for (l=0; l<ncon; l++)
00254 printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
00255 printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
00256 if (ed[higain] == 0 && id[higain] > 0)
00257 printf("\t Pulled from the interior!\n");
00258 }
00259
00260
00261
00262
00263
00264 SWAP(id[higain], ed[higain], tmp);
00265 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
00266 BNDDelete(nbnd, bndind, bndptr, higain);
00267 if (ed[higain] > 0 && bndptr[higain] == -1)
00268 BNDInsert(nbnd, bndind, bndptr, higain);
00269
00270 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
00271 k = adjncy[j];
00272 oldgain = ed[k]-id[k];
00273
00274 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
00275 INC_DEC(id[k], ed[k], kwgt);
00276
00277
00278 if (moved[k] == -1 && where[k] == from) {
00279 if (ed[k] > 0 && bndptr[k] == -1) {
00280 PQueueDelete(&parts[qnum[k]][1], k, oldgain);
00281 PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]);
00282 }
00283 else {
00284 if (bndptr[k] == -1)
00285 printf("What you thought was wrong!\n");
00286 PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]);
00287 }
00288 }
00289
00290
00291 if (ed[k] == 0 && bndptr[k] != -1)
00292 BNDDelete(nbnd, bndind, bndptr, k);
00293 else if (ed[k] > 0 && bndptr[k] == -1)
00294 BNDInsert(nbnd, bndind, bndptr, k);
00295 }
00296
00297 ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut));
00298
00299 }
00300
00301 if (ctrl->dbglvl&DBG_REFINE) {
00302 printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd);
00303 for (l=0; l<ncon; l++)
00304 printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
00305 printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
00306 }
00307
00308 graph->mincut = mincut;
00309 graph->nbnd = nbnd;
00310
00311 for (i=0; i<ncon; i++) {
00312 PQueueFree(ctrl, &parts[i][0]);
00313 PQueueFree(ctrl, &parts[i][1]);
00314 }
00315
00316 ASSERT(ComputeCut(graph, where) == graph->mincut);
00317 ASSERT(CheckBnd(graph));
00318
00319 idxwspacefree(ctrl, nvtxs);
00320 idxwspacefree(ctrl, nvtxs);
00321 idxwspacefree(ctrl, nvtxs);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 int SelectQueueOneWay2(int ncon, floattype *pto, PQueueType queues[MAXNCON][2], floattype *ubvec)
00331 {
00332 int i, cnum=-1, imax, maxgain;
00333 floattype max=0.0;
00334 floattype twgt[MAXNCON];
00335
00336 for (i=0; i<ncon; i++) {
00337 if (max < pto[i]) {
00338 imax = i;
00339 max = pto[i];
00340 }
00341 }
00342 for (i=0; i<ncon; i++)
00343 twgt[i] = (max/(ubvec[imax]*ubvec[i]))/pto[i];
00344 twgt[imax] = 0.0;
00345
00346 max = 0.0;
00347 for (i=0; i<ncon; i++) {
00348 if (max < twgt[i] && (PQueueGetSize(&queues[i][0]) > 0 || PQueueGetSize(&queues[i][1]) > 0)) {
00349 max = twgt[i];
00350 cnum = i;
00351 }
00352 }
00353 if (max > 1)
00354 return cnum;
00355
00356
00357 maxgain = -10000000;
00358 for (i=0; i<ncon; i++) {
00359 if (PQueueGetSize(&queues[i][0]) > 0 && PQueueGetKey(&queues[i][0]) > maxgain) {
00360 maxgain = PQueueGetKey(&queues[i][0]);
00361 cnum = i;
00362 }
00363 }
00364
00365 return cnum;
00366
00367 }
00368