00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <metis.h>
00015
00016
00017
00018
00019
00020 void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, floattype ubfactor)
00021 {
00022
00023 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
00024
00025
00026 Compute2WayPartitionParams(ctrl, graph);
00027
00028 for (;;) {
00029 ASSERT(CheckBnd(graph));
00030
00031 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
00032 switch (ctrl->RType) {
00033 case 1:
00034 Balance2Way(ctrl, graph, tpwgts, ubfactor);
00035 FM_2WayEdgeRefine(ctrl, graph, tpwgts, 8);
00036 break;
00037 default:
00038 errexit("Unknown refinement type: %d\n", ctrl->RType);
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 Project2WayPartition(ctrl, graph);
00048 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
00049 }
00050
00051 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
00052 }
00053
00054
00055
00056
00057
00058 void Allocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
00059 {
00060 int nvtxs;
00061
00062 nvtxs = graph->nvtxs;
00063
00064 graph->rdata = idxmalloc(5*nvtxs+2, "Allocate2WayPartitionMemory: rdata");
00065 graph->pwgts = graph->rdata;
00066 graph->where = graph->rdata + 2;
00067 graph->id = graph->rdata + nvtxs + 2;
00068 graph->ed = graph->rdata + 2*nvtxs + 2;
00069 graph->bndptr = graph->rdata + 3*nvtxs + 2;
00070 graph->bndind = graph->rdata + 4*nvtxs + 2;
00071 }
00072
00073
00074
00075
00076
00077 void Compute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
00078 {
00079 int i, j, k, l, nvtxs, nbnd, mincut;
00080 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts;
00081 idxtype *id, *ed, *where;
00082 idxtype *bndptr, *bndind;
00083 int me, other;
00084
00085 nvtxs = graph->nvtxs;
00086 xadj = graph->xadj;
00087 vwgt = graph->vwgt;
00088 adjncy = graph->adjncy;
00089 adjwgt = graph->adjwgt;
00090
00091 where = graph->where;
00092 pwgts = idxset(2, 0, graph->pwgts);
00093 id = idxset(nvtxs, 0, graph->id);
00094 ed = idxset(nvtxs, 0, graph->ed);
00095 bndptr = idxset(nvtxs, -1, graph->bndptr);
00096 bndind = graph->bndind;
00097
00098
00099
00100
00101
00102 nbnd = mincut = 0;
00103 for (i=0; i<nvtxs; i++) {
00104 ASSERT(where[i] >= 0 && where[i] <= 1);
00105 me = where[i];
00106 pwgts[me] += vwgt[i];
00107
00108 for (j=xadj[i]; j<xadj[i+1]; j++) {
00109 if (me == where[adjncy[j]])
00110 id[i] += adjwgt[j];
00111 else
00112 ed[i] += adjwgt[j];
00113 }
00114
00115 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
00116 mincut += ed[i];
00117 bndptr[i] = nbnd;
00118 bndind[nbnd++] = i;
00119 }
00120 }
00121
00122 graph->mincut = mincut/2;
00123 graph->nbnd = nbnd;
00124
00125 ASSERT(pwgts[0]+pwgts[1] == idxsum(nvtxs, vwgt));
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 void Project2WayPartition(CtrlType *ctrl, GraphType *graph)
00135 {
00136 int i, j, k, nvtxs, nbnd, me;
00137 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
00138 idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
00139 idxtype *cwhere, *cid, *ced, *cbndptr;
00140 GraphType *cgraph;
00141
00142 cgraph = graph->coarser;
00143 cwhere = cgraph->where;
00144 cid = cgraph->id;
00145 ced = cgraph->ed;
00146 cbndptr = cgraph->bndptr;
00147
00148 nvtxs = graph->nvtxs;
00149 cmap = graph->cmap;
00150 xadj = graph->xadj;
00151 adjncy = graph->adjncy;
00152 adjwgt = graph->adjwgt;
00153 adjwgtsum = graph->adjwgtsum;
00154
00155 Allocate2WayPartitionMemory(ctrl, graph);
00156
00157 where = graph->where;
00158 id = idxset(nvtxs, 0, graph->id);
00159 ed = idxset(nvtxs, 0, graph->ed);
00160 bndptr = idxset(nvtxs, -1, graph->bndptr);
00161 bndind = graph->bndind;
00162
00163
00164
00165 for (i=0; i<nvtxs; i++) {
00166 k = cmap[i];
00167 where[i] = cwhere[k];
00168 cmap[i] = cbndptr[k];
00169 }
00170
00171 for (nbnd=0, i=0; i<nvtxs; i++) {
00172 me = where[i];
00173
00174 id[i] = adjwgtsum[i];
00175
00176 if (xadj[i] == xadj[i+1]) {
00177 bndptr[i] = nbnd;
00178 bndind[nbnd++] = i;
00179 }
00180 else {
00181 if (cmap[i] != -1) {
00182 for (j=xadj[i]; j<xadj[i+1]; j++) {
00183 if (me != where[adjncy[j]])
00184 ed[i] += adjwgt[j];
00185 }
00186 id[i] -= ed[i];
00187
00188 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
00189 bndptr[i] = nbnd;
00190 bndind[nbnd++] = i;
00191 }
00192 }
00193 }
00194 }
00195
00196 graph->mincut = cgraph->mincut;
00197 graph->nbnd = nbnd;
00198 idxcopy(2, cgraph->pwgts, graph->pwgts);
00199
00200 FreeGraph(graph->coarser);
00201 graph->coarser = NULL;
00202
00203 }
00204