45 cptr =
imalloc(nvtxs+1,
"OMETIS: cptr");
46 cind =
imalloc(nvtxs,
"OMETIS: cind");
48 graph =
CompressGraph(ctrl, nvtxs, xadj, adjncy, vwgt, cptr, cind);
55 nnvtxs = graph->
nvtxs;
69 iset(2*npes-1, 0, sizes);
76 for (i=0; i<nnvtxs; i++)
78 for (l=ii=0; ii<nnvtxs; ii++) {
80 for (j=cptr[i]; j<cptr[i+1]; j++)
88 for (i=0; i<nvtxs; i++)
109 idx_t *label, *bndind;
112 nvtxs = graph->
nvtxs;
126 sizes[2*npes-2-cpos] = graph->
pwgts[2];
127 sizes[2*npes-2-(2*cpos+1)] = graph->
pwgts[1];
128 sizes[2*npes-2-(2*cpos+2)] = graph->
pwgts[0];
134 label = graph->
label;
135 for (i=0; i<nbnd; i++)
136 order[label[bndind[i]]] = --lastvtx;
152 MMDOrder(ctrl, rgraph, order, lastvtx);
184 *r_sepsize = graph->
pwgts[2];
240 idx_t i, ii,
j, k, jj, kk, nvtxs, nbnd, nswaps, nmind, nbad, qsize;
242 idx_t *mptr, *mind, *swaps, *inqueue;
245 idx_t higain, oldgain, mincut, initcut, mincutorder;
246 idx_t pass, from, to, limit;
247 idx_t badmaxpwgt, mindiff, newdiff;
253 nvtxs = graph->
nvtxs;
260 where = graph->
where;
261 pwgts = graph->
pwgts;
271 badmaxpwgt = (
idx_t)(ubfactor*
gk_max(pwgts[0], pwgts[1]));
276 pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, badmaxpwgt,
279 to = (pwgts[0] < pwgts[1] ? 1 : 0);
280 for (pass=0; pass<npasses; pass++) {
287 initcut = mincut = graph->
mincut;
292 for (ii=0; ii<nbnd; ii++) {
293 i = bndind[swaps[ii]];
295 if (hmarker[i] == -1 || hmarker[i] == to) {
296 rpqInsert(queue, i, vwgt[i]-rinfo[i].edegrees[from]);
310 mptr[0] = nmind = nbad = 0;
311 mindiff =
abs(pwgts[0]-pwgts[1]);
312 for (nswaps=0; nswaps<nvtxs; nswaps++) {
316 ASSERT(bndptr[higain] != -1);
320 if (nmind + xadj[higain+1]-xadj[higain] >= 2*nvtxs-1)
323 inqueue[higain] = -1;
325 if (pwgts[to]+vwgt[higain] > badmaxpwgt) {
334 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[from]);
336 newdiff =
abs(pwgts[to]+vwgt[higain] - (pwgts[from]-rinfo[higain].edegrees[from]));
337 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
339 mincutorder = nswaps;
344 if (nbad++ > limit) {
345 pwgts[2] += (vwgt[higain]-rinfo[higain].
edegrees[from]);
351 pwgts[to] += vwgt[higain];
353 swaps[nswaps] = higain;
359 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
362 rinfo[k].
edegrees[to] += vwgt[higain];
364 else if (where[k] == from) {
365 ASSERTP(bndptr[k] == -1, (
"%"PRIDX
" %"PRIDX
" %"PRIDX
"\n", k, bndptr[k], where[k]));
370 pwgts[from] -= vwgt[k];
373 edegrees[0] = edegrees[1] = 0;
374 for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
377 edegrees[where[kk]] += vwgt[kk];
379 oldgain = vwgt[kk]-rinfo[kk].
edegrees[from];
380 rinfo[kk].
edegrees[from] -= vwgt[k];
383 if (inqueue[kk] == pass)
389 if (hmarker[k] == -1 || hmarker[k] == to) {
390 rpqInsert(queue, k, vwgt[k]-edegrees[from]);
395 mptr[nswaps+1] = nmind;
399 printf(
"Moved %6"PRIDX
" to %3"PRIDX
", Gain: %5"PRIDX
" [%5"PRIDX
"] \t[%5"PRIDX
" %5"PRIDX
" %5"PRIDX
"] [%3"PRIDX
" %2"PRIDX
"]\n",
400 higain, to, (vwgt[higain]-rinfo[higain].edegrees[from]),
401 vwgt[higain], pwgts[0], pwgts[1], pwgts[2], nswaps, limit));
409 for (nswaps--; nswaps>mincutorder; nswaps--) {
410 higain = swaps[nswaps];
413 ASSERT(where[higain] == to);
415 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
420 edegrees[0] = edegrees[1] = 0;
421 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
424 rinfo[k].
edegrees[to] -= vwgt[higain];
426 edegrees[where[k]] += vwgt[k];
430 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
434 INC_DEC(pwgts[from], pwgts[2], vwgt[k]);
436 for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
439 rinfo[kk].
edegrees[from] += vwgt[k];
444 ASSERT(mincut == pwgts[2]);
447 printf(
"\tMinimum sep: %6"PRIDX
" at %5"PRIDX
", PWGTS: [%6"PRIDX
" %6"PRIDX
"], NBND: %6"PRIDX
", QSIZE: %6"PRIDX
"\n",
448 mincut, mincutorder, pwgts[0], pwgts[1], nbnd, qsize));
453 if (pass%2 == 1 && (mincutorder == -1 || mincut >= initcut))
470 idx_t i, ii,
j, k, jj, kk, nvtxs, nbnd, nswaps, nmind;
472 idx_t *mptr, *mind, *moved, *swaps;
475 idx_t higain, oldgain, mincut, initcut, mincutorder;
477 idx_t badmaxpwgt, mindiff, newdiff;
482 nvtxs = graph->
nvtxs;
489 where = graph->
where;
490 pwgts = graph->
pwgts;
504 badmaxpwgt = (
idx_t)(ubfactor*
gk_max(pwgts[0], pwgts[1]));
506 for (pass=0; pass<npasses; pass++) {
507 iset(nvtxs, -1, moved);
512 initcut = mincut = graph->
mincut;
517 for (ii=0; ii<nbnd; ii++) {
518 i = bndind[swaps[ii]];
520 if (hmarker[i] == -1) {
521 rpqInsert(queues[0], i, vwgt[i]-rinfo[i].edegrees[1]);
522 rpqInsert(queues[1], i, vwgt[i]-rinfo[i].edegrees[0]);
525 else if (hmarker[i] != 2) {
526 rpqInsert(queues[hmarker[i]], i, vwgt[i]-rinfo[i].edegrees[(hmarker[i]+1)%2]);
527 moved[
i] = -(10+hmarker[
i]);
540 mindiff =
abs(pwgts[0]-pwgts[1]);
541 to = (pwgts[0] < pwgts[1] ? 0 : 1);
542 for (nswaps=0; nswaps<nvtxs; nswaps++) {
545 if (u[0] != -1 && u[1] != -1) {
546 g[0] = vwgt[u[0]]-rinfo[u[0]].
edegrees[1];
547 g[1] = vwgt[u[1]]-rinfo[u[1]].
edegrees[0];
549 to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2));
551 if (pwgts[to]+vwgt[u[to]] > badmaxpwgt)
554 else if (u[0] == -1 && u[1] == -1) {
557 else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) {
560 else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) {
571 if (moved[higain] == -5)
574 ASSERT(bndptr[higain] != -1);
578 if (nmind + xadj[higain+1]-xadj[higain] >= 2*nvtxs-1)
583 newdiff =
abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
584 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
586 mincutorder = nswaps;
590 if (nswaps - mincutorder > limit) {
597 pwgts[to] += vwgt[higain];
599 moved[higain] = nswaps;
600 swaps[nswaps] = higain;
606 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
609 oldgain = vwgt[k]-rinfo[k].
edegrees[to];
610 rinfo[k].
edegrees[to] += vwgt[higain];
611 if (moved[k] == -5 || moved[k] == -(10+other))
612 rpqUpdate(queues[other], k, oldgain-vwgt[higain]);
614 else if (where[k] == other) {
615 ASSERTP(bndptr[k] == -1, (
"%"PRIDX
" %"PRIDX
" %"PRIDX
"\n", k, bndptr[k], where[k]));
620 pwgts[
other] -= vwgt[k];
623 edegrees[0] = edegrees[1] = 0;
624 for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
627 edegrees[where[kk]] += vwgt[kk];
631 if (moved[kk] == -5 || moved[kk] == -(10+to))
632 rpqUpdate(queues[to], kk, oldgain+vwgt[k]);
637 if (moved[k] == -1 && (hmarker[k] == -1 || hmarker[k] == to)) {
638 rpqInsert(queues[to], k, vwgt[k]-edegrees[other]);
642 if (moved[k] == -1) {
643 if (hmarker[k] == -1) {
644 rpqInsert(queues[0], k, vwgt[k]-edegrees[1]);
645 rpqInsert(queues[1], k, vwgt[k]-edegrees[0]);
648 else if (hmarker[k] != 2) {
649 rpqInsert(queues[hmarker[k]], k, vwgt[k]-edegrees[(hmarker[k]+1)%2]);
650 moved[k] = -(10+hmarker[k]);
656 mptr[nswaps+1] = nmind;
659 printf(
"Moved %6"PRIDX
" to %3"PRIDX
", Gain: %5"PRIDX
" [%5"PRIDX
"] " 660 "[%4"PRIDX
" %4"PRIDX
"] \t[%5"PRIDX
" %5"PRIDX
" %5"PRIDX
"]\n",
661 higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]],
662 pwgts[0], pwgts[1], pwgts[2]));
670 for (nswaps--; nswaps>mincutorder; nswaps--) {
671 higain = swaps[nswaps];
677 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
682 edegrees[0] = edegrees[1] = 0;
683 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
686 rinfo[k].
edegrees[to] -= vwgt[higain];
688 edegrees[where[k]] += vwgt[k];
692 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
696 INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
698 for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
706 ASSERT(mincut == pwgts[2]);
709 printf(
"\tMinimum sep: %6"PRIDX
" at %5"PRIDX
", PWGTS: [%6"PRIDX
" %6"PRIDX
"], NBND: %6"PRIDX
"\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
714 if (mincutorder == -1 || mincut >= initcut)
idx_t idx_t idx_t idx_t * vwgt
#define Compute2WayNodePartitionParams
idx_t idx_t idx_t idx_t idx_t idx_t idx_t real_t real_t idx_t idx_t idx_t * part
#define gk_startcputimer(tmr)
#define BNDDelete(nbnd, bndind, bndptr, vtx)
#define irandArrayPermute
idx_t idx_t idx_t idx_t idx_t * hmarker
#define gk_stopcputimer(tmr)
std::vector< Array2i > sizes
idx_t idx_t idx_t idx_t idx_t real_t ubfactor
#define ASSERTP(expr, msg)
int METIS_ComputeVertexSeparator(idx_t *nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt, idx_t *options, idx_t *r_sepsize, idx_t *part)
idx_t idx_t idx_t idx_t idx_t idx_t * iperm
#define MlevelNodeBisectionMultiple
#define CheckNodePartitionParams
NonlinearFactorGraph graph
void g(const string &key, int i)
#define Allocate2WayNodePartitionMemory
#define ASSERT(expression)
#define AllocateWorkSpace
static const Line3 l(Rot3(), 1, 1)
#define BNDInsert(nbnd, bndind, bndptr, vtx)
idx_t idx_t idx_t idx_t idx_t * perm
void MlevelNestedDissectionP(ctrl_t *ctrl, graph_t *graph, idx_t *order, idx_t lastvtx, idx_t npes, idx_t cpos, idx_t *sizes)
#define INC_DEC(a, b, val)
int METIS_NodeNDP(idx_t nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt, idx_t npes, idx_t *options, idx_t *perm, idx_t *iperm, idx_t *sizes)
void gk_free(void **ptr1,...)
idx_t idx_t idx_t idx_t * where
idx_t idx_t idx_t * adjncy
void FM_2WayNodeRefine2SidedP(ctrl_t *ctrl, graph_t *graph, idx_t *hmarker, real_t ubfactor, idx_t npasses)
idx_t idx_t idx_t idx_t npes
#define IFSET(a, flag, cmd)
void FM_2WayNodeRefine1SidedP(ctrl_t *ctrl, graph_t *graph, idx_t *hmarker, real_t ubfactor, idx_t npasses)
int METIS_NodeRefine(idx_t nvtxs, idx_t *xadj, idx_t *vwgt, idx_t *adjncy, idx_t *where, idx_t *hmarker, real_t ubfactor)