00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <metis.h>
00016
00017
00018
00019
00020
00021 void Refine2WayNode(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, floattype ubfactor)
00022 {
00023
00024 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
00025
00026 for (;;) {
00027 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
00028 if (ctrl->RType != 15)
00029 FM_2WayNodeBalance(ctrl, graph, ubfactor);
00030
00031 switch (ctrl->RType) {
00032 case 1:
00033 FM_2WayNodeRefine(ctrl, graph, ubfactor, 8);
00034 break;
00035 case 2:
00036 FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8);
00037 break;
00038 case 3:
00039 FM_2WayNodeRefine(ctrl, graph, ubfactor, 8);
00040 FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8);
00041 break;
00042 case 4:
00043 FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8);
00044 FM_2WayNodeRefine(ctrl, graph, ubfactor, 8);
00045 break;
00046 case 5:
00047 FM_2WayNodeRefineEqWgt(ctrl, graph, 8);
00048 break;
00049 }
00050 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
00051
00052 if (graph == orggraph)
00053 break;
00054
00055 graph = graph->finer;
00056 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
00057 Project2WayNodePartition(ctrl, graph);
00058 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
00059 }
00060
00061 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
00062 }
00063
00064
00065
00066
00067
00068 void Allocate2WayNodePartitionMemory(CtrlType *ctrl, GraphType *graph)
00069 {
00070 int nvtxs, pad64;
00071
00072 nvtxs = graph->nvtxs;
00073
00074 pad64 = (3*nvtxs+3)%2;
00075
00076 graph->rdata = idxmalloc(3*nvtxs+3+(sizeof(NRInfoType)/sizeof(idxtype))*nvtxs+pad64, "Allocate2WayPartitionMemory: rdata");
00077 graph->pwgts = graph->rdata;
00078 graph->where = graph->rdata + 3;
00079 graph->bndptr = graph->rdata + nvtxs + 3;
00080 graph->bndind = graph->rdata + 2*nvtxs + 3;
00081 graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3 + pad64);
00082 }
00083
00084
00085
00086
00087
00088
00089 void Compute2WayNodePartitionParams(CtrlType *ctrl, GraphType *graph)
00090 {
00091 int i, j, k, l, nvtxs, nbnd;
00092 idxtype *xadj, *adjncy, *adjwgt, *vwgt;
00093 idxtype *where, *pwgts, *bndind, *bndptr, *edegrees;
00094 NRInfoType *rinfo;
00095 int me, other;
00096
00097 nvtxs = graph->nvtxs;
00098 xadj = graph->xadj;
00099 vwgt = graph->vwgt;
00100 adjncy = graph->adjncy;
00101 adjwgt = graph->adjwgt;
00102
00103 where = graph->where;
00104 rinfo = graph->nrinfo;
00105 pwgts = idxset(3, 0, graph->pwgts);
00106 bndind = graph->bndind;
00107 bndptr = idxset(nvtxs, -1, graph->bndptr);
00108
00109
00110
00111
00112
00113 nbnd = 0;
00114 for (i=0; i<nvtxs; i++) {
00115 me = where[i];
00116 pwgts[me] += vwgt[i];
00117
00118 ASSERT(me >=0 && me <= 2);
00119
00120 if (me == 2) {
00121 BNDInsert(nbnd, bndind, bndptr, i);
00122
00123 edegrees = rinfo[i].edegrees;
00124 edegrees[0] = edegrees[1] = 0;
00125
00126 for (j=xadj[i]; j<xadj[i+1]; j++) {
00127 other = where[adjncy[j]];
00128 if (other != 2)
00129 edegrees[other] += vwgt[adjncy[j]];
00130 }
00131 }
00132 }
00133
00134 ASSERT(CheckNodeBnd(graph, nbnd));
00135
00136 graph->mincut = pwgts[2];
00137 graph->nbnd = nbnd;
00138 }
00139
00140
00141
00142
00143
00144 void Project2WayNodePartition(CtrlType *ctrl, GraphType *graph)
00145 {
00146 int i, j, nvtxs;
00147 idxtype *cmap, *where, *cwhere;
00148 GraphType *cgraph;
00149
00150 cgraph = graph->coarser;
00151 cwhere = cgraph->where;
00152
00153 nvtxs = graph->nvtxs;
00154 cmap = graph->cmap;
00155
00156 Allocate2WayNodePartitionMemory(ctrl, graph);
00157 where = graph->where;
00158
00159
00160 for (i=0; i<nvtxs; i++) {
00161 where[i] = cwhere[cmap[i]];
00162 ASSERTP(where[i] >= 0 && where[i] <= 2, ("%d %d %d %d\n", i, cmap[i], where[i], cwhere[cmap[i]]));
00163 }
00164
00165 FreeGraph(graph->coarser);
00166 graph->coarser = NULL;
00167
00168 Compute2WayNodePartitionParams(ctrl, graph);
00169 }