1 /*
2  * Copyright 1997, Regents of the University of Minnesota
3  *
4  * refine.c
5  *
6  * This file contains the driving routines for multilevel refinement
7  *
8  * Started 7/24/97
9  * George
10  *
11  * $Id: mrefine.c,v 1.2 1998/11/27 18:25:09 karypis Exp $
12  */
13 
14 #include "metis.h"
15 
16 
17 /*************************************************************************
18 * This function is the entry point of refinement
19 **************************************************************************/
MocRefine2Way(CtrlType * ctrl,GraphType * orggraph,GraphType * graph,float * tpwgts,float ubfactor)20 void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor)
21 {
22   int i;
23   float tubvec[MAXNCON];
24 
25   for (i=0; i<graph->ncon; i++)
26     tubvec[i] = 1.0;
27 
28   IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr));
29 
30   /* Compute the parameters of the coarsest graph */
31   MocCompute2WayPartitionParams(ctrl, graph);
32 
33   for (;;) {
34     ASSERT(CheckBnd(graph));
35 
36     IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));
37     switch (ctrl->RType) {
38       case RTYPE_FM:
39         MocBalance2Way(ctrl, graph, tpwgts, 1.03);
40         MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8);
41         break;
42       case 2:
43         MocBalance2Way(ctrl, graph, tpwgts, 1.03);
44         MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8);
45         break;
46       default:
47         graclus_errexit("Unknown refinement type: %d\n", ctrl->RType);
48     }
49     IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));
50 
51     if (graph == orggraph)
52       break;
53 
54     graph = graph->finer;
55     IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
56     MocProject2WayPartition(ctrl, graph);
57     IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
58   }
59 
60   MocBalance2Way(ctrl, graph, tpwgts, 1.01);
61   MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8);
62 
63   IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
64 }
65 
66 
67 /*************************************************************************
68 * This function allocates memory for 2-way edge refinement
69 **************************************************************************/
MocAllocate2WayPartitionMemory(CtrlType * ctrl,GraphType * graph)70 void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
71 {
72   int nvtxs, ncon;
73 
74   nvtxs = graph->nvtxs;
75   ncon = graph->ncon;
76 
77   graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata");
78   graph->where		= graph->rdata;
79   graph->id		= graph->rdata + nvtxs;
80   graph->ed		= graph->rdata + 2*nvtxs;
81   graph->bndptr		= graph->rdata + 3*nvtxs;
82   graph->bndind		= graph->rdata + 4*nvtxs;
83 
84   graph->npwgts 	= fmalloc(2*ncon, "npwgts");
85 }
86 
87 
88 /*************************************************************************
89 * This function computes the initial id/ed
90 **************************************************************************/
MocCompute2WayPartitionParams(CtrlType * ctrl,GraphType * graph)91 void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
92 {
93   int i, j, k, l, nvtxs, ncon, nbnd, mincut;
94   idxtype *xadj, *adjncy, *adjwgt;
95   float *nvwgt, *npwgts;
96   idxtype *id, *ed, *where;
97   idxtype *bndptr, *bndind;
98   int me, other;
99 
100   nvtxs = graph->nvtxs;
101   ncon = graph->ncon;
102   xadj = graph->xadj;
103   nvwgt = graph->nvwgt;
104   adjncy = graph->adjncy;
105   adjwgt = graph->adjwgt;
106 
107   where = graph->where;
108   npwgts = sset(2*ncon, 0.0, graph->npwgts);
109   id = idxset(nvtxs, 0, graph->id);
110   ed = idxset(nvtxs, 0, graph->ed);
111   bndptr = idxset(nvtxs, -1, graph->bndptr);
112   bndind = graph->bndind;
113 
114 
115   /*------------------------------------------------------------
116   / Compute now the id/ed degrees
117   /------------------------------------------------------------*/
118   nbnd = mincut = 0;
119   for (i=0; i<nvtxs; i++) {
120     ASSERT(where[i] >= 0 && where[i] <= 1);
121     me = where[i];
122     saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
123 
124     for (j=xadj[i]; j<xadj[i+1]; j++) {
125       if (me == where[adjncy[j]])
126         id[i] += adjwgt[j];
127       else
128         ed[i] += adjwgt[j];
129     }
130 
131     if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
132       mincut += ed[i];
133       bndptr[i] = nbnd;
134       bndind[nbnd++] = i;
135     }
136   }
137 
138   graph->mincut = mincut/2;
139   graph->nbnd = nbnd;
140 
141 }
142 
143 
144 
145 /*************************************************************************
146 * This function projects a partition, and at the same time computes the
147 * parameters for refinement.
148 **************************************************************************/
MocProject2WayPartition(CtrlType * ctrl,GraphType * graph)149 void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph)
150 {
151   int i, j, k, nvtxs, nbnd, me;
152   idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
153   idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
154   idxtype *cwhere, *cid, *ced, *cbndptr;
155   GraphType *cgraph;
156 
157   cgraph = graph->coarser;
158   cwhere = cgraph->where;
159   cid = cgraph->id;
160   ced = cgraph->ed;
161   cbndptr = cgraph->bndptr;
162 
163   nvtxs = graph->nvtxs;
164   cmap = graph->cmap;
165   xadj = graph->xadj;
166   adjncy = graph->adjncy;
167   adjwgt = graph->adjwgt;
168   adjwgtsum = graph->adjwgtsum;
169 
170   MocAllocate2WayPartitionMemory(ctrl, graph);
171 
172   where = graph->where;
173   id = idxset(nvtxs, 0, graph->id);
174   ed = idxset(nvtxs, 0, graph->ed);
175   bndptr = idxset(nvtxs, -1, graph->bndptr);
176   bndind = graph->bndind;
177 
178 
179   /* Go through and project partition and compute id/ed for the nodes */
180   for (i=0; i<nvtxs; i++) {
181     k = cmap[i];
182     where[i] = cwhere[k];
183     cmap[i] = cbndptr[k];
184   }
185 
186   for (nbnd=0, i=0; i<nvtxs; i++) {
187     me = where[i];
188 
189     id[i] = adjwgtsum[i];
190 
191     if (xadj[i] == xadj[i+1]) {
192       bndptr[i] = nbnd;
193       bndind[nbnd++] = i;
194     }
195     else {
196       if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */
197         for (j=xadj[i]; j<xadj[i+1]; j++) {
198           if (me != where[adjncy[j]])
199             ed[i] += adjwgt[j];
200         }
201         id[i] -= ed[i];
202 
203         if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
204           bndptr[i] = nbnd;
205           bndind[nbnd++] = i;
206         }
207       }
208     }
209   }
210 
211   graph->mincut = cgraph->mincut;
212   graph->nbnd = nbnd;
213   scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts);
214 
215   FreeGraph(graph->coarser);
216   graph->coarser = NULL;
217 
218 }
219 
220