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