00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "metislib.h"
00016
00017
00018
00022
00023 void Refine2WayNode(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph)
00024 {
00025
00026 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));
00027
00028 if (graph == orggraph) {
00029 Compute2WayNodePartitionParams(ctrl, graph);
00030 }
00031 else {
00032 do {
00033 graph = graph->finer;
00034
00035 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
00036 Project2WayNodePartition(ctrl, graph);
00037 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
00038
00039 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));
00040 FM_2WayNodeBalance(ctrl, graph);
00041
00042 ASSERT(CheckNodePartitionParams(graph));
00043
00044 switch (ctrl->rtype) {
00045 case METIS_RTYPE_SEP2SIDED:
00046 FM_2WayNodeRefine2Sided(ctrl, graph, ctrl->niter);
00047 break;
00048 case METIS_RTYPE_SEP1SIDED:
00049 FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter);
00050 break;
00051 default:
00052 gk_errexit(SIGERR, "Unknown rtype of %d\n", ctrl->rtype);
00053 }
00054 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));
00055
00056 } while (graph != orggraph);
00057 }
00058
00059 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
00060 }
00061
00062
00063
00065
00066 void Allocate2WayNodePartitionMemory(ctrl_t *ctrl, graph_t *graph)
00067 {
00068 idx_t nvtxs;
00069
00070 nvtxs = graph->nvtxs;
00071
00072 graph->pwgts = imalloc(3, "Allocate2WayNodePartitionMemory: pwgts");
00073 graph->where = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: where");
00074 graph->bndptr = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndptr");
00075 graph->bndind = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndind");
00076 graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "Allocate2WayNodePartitionMemory: nrinfo");
00077 }
00078
00079
00080
00082
00083 void Compute2WayNodePartitionParams(ctrl_t *ctrl, graph_t *graph)
00084 {
00085 idx_t i, j, nvtxs, nbnd;
00086 idx_t *xadj, *adjncy, *vwgt;
00087 idx_t *where, *pwgts, *bndind, *bndptr, *edegrees;
00088 nrinfo_t *rinfo;
00089 idx_t me, other;
00090
00091 nvtxs = graph->nvtxs;
00092 xadj = graph->xadj;
00093 vwgt = graph->vwgt;
00094 adjncy = graph->adjncy;
00095
00096 where = graph->where;
00097 rinfo = graph->nrinfo;
00098 pwgts = iset(3, 0, graph->pwgts);
00099 bndind = graph->bndind;
00100 bndptr = iset(nvtxs, -1, graph->bndptr);
00101
00102
00103
00104
00105
00106 nbnd = 0;
00107 for (i=0; i<nvtxs; i++) {
00108 me = where[i];
00109 pwgts[me] += vwgt[i];
00110
00111 ASSERT(me >=0 && me <= 2);
00112
00113 if (me == 2) {
00114 BNDInsert(nbnd, bndind, bndptr, i);
00115
00116 edegrees = rinfo[i].edegrees;
00117 edegrees[0] = edegrees[1] = 0;
00118
00119 for (j=xadj[i]; j<xadj[i+1]; j++) {
00120 other = where[adjncy[j]];
00121 if (other != 2)
00122 edegrees[other] += vwgt[adjncy[j]];
00123 }
00124 }
00125 }
00126
00127 ASSERT(CheckNodeBnd(graph, nbnd));
00128
00129 graph->mincut = pwgts[2];
00130 graph->nbnd = nbnd;
00131 }
00132
00133
00134
00136
00137 void Project2WayNodePartition(ctrl_t *ctrl, graph_t *graph)
00138 {
00139 idx_t i, j, nvtxs;
00140 idx_t *cmap, *where, *cwhere;
00141 graph_t *cgraph;
00142
00143 cgraph = graph->coarser;
00144 cwhere = cgraph->where;
00145
00146 nvtxs = graph->nvtxs;
00147 cmap = graph->cmap;
00148
00149 Allocate2WayNodePartitionMemory(ctrl, graph);
00150 where = graph->where;
00151
00152
00153 for (i=0; i<nvtxs; i++) {
00154 where[i] = cwhere[cmap[i]];
00155 ASSERTP(where[i] >= 0 && where[i] <= 2, ("%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"\n",
00156 i, cmap[i], where[i], cwhere[cmap[i]]));
00157 }
00158
00159 FreeGraph(&graph->coarser);
00160 graph->coarser = NULL;
00161
00162 Compute2WayNodePartitionParams(ctrl, graph);
00163 }