1 /**
2 \file
3 \brief Functions that deal with setting up the graphs for METIS.
4
5 \date Started 7/25/1997
6 \author George
7 \author Copyright 1997-2009, Regents of the University of Minnesota
8 \version\verbatim $Id: graph.c 10513 2011-07-07 22:06:03Z karypis $ \endverbatim
9 */
10
11 #include "metislib.h"
12
13
14 /*************************************************************************/
15 /*! This function sets up the graph from the user input */
16 /*************************************************************************/
SetupGraph(ctrl_t * ctrl,idx_t nvtxs,idx_t ncon,idx_t * xadj,idx_t * adjncy,idx_t * vwgt,idx_t * vsize,idx_t * adjwgt)17 graph_t *SetupGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t ncon, idx_t *xadj,
18 idx_t *adjncy, idx_t *vwgt, idx_t *vsize, idx_t *adjwgt)
19 {
20 idx_t i, j, k, sum;
21 real_t *nvwgt;
22 graph_t *graph;
23
24 /* allocate the graph and fill in the fields */
25 graph = CreateGraph();
26
27 graph->nvtxs = nvtxs;
28 graph->nedges = xadj[nvtxs];
29 graph->ncon = ncon;
30
31 graph->xadj = xadj;
32 graph->free_xadj = 0;
33
34 graph->adjncy = adjncy;
35 graph->free_adjncy = 0;
36
37
38 /* setup the vertex weights */
39 if (vwgt) {
40 graph->vwgt = vwgt;
41 graph->free_vwgt = 0;
42 }
43 else {
44 vwgt = graph->vwgt = ismalloc(ncon*nvtxs, 1, "SetupGraph: vwgt");
45 }
46
47 graph->tvwgt = imalloc(ncon, "SetupGraph: tvwgts");
48 graph->invtvwgt = rmalloc(ncon, "SetupGraph: invtvwgts");
49 for (i=0; i<ncon; i++) {
50 graph->tvwgt[i] = isum(nvtxs, vwgt+i, ncon);
51 graph->invtvwgt[i] = 1.0/(graph->tvwgt[i] > 0 ? graph->tvwgt[i] : 1);
52 }
53
54
55 if (ctrl->objtype == METIS_OBJTYPE_VOL) {
56 /* Setup the vsize */
57 if (vsize) {
58 graph->vsize = vsize;
59 graph->free_vsize = 0;
60 }
61 else {
62 vsize = graph->vsize = ismalloc(nvtxs, 1, "SetupGraph: vsize");
63 }
64
65 /* Allocate memory for edge weights and initialize them to the sum of the vsize */
66 adjwgt = graph->adjwgt = imalloc(graph->nedges, "SetupGraph: adjwgt");
67 for (i=0; i<nvtxs; i++) {
68 for (j=xadj[i]; j<xadj[i+1]; j++)
69 adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
70 }
71 }
72 else { /* For edgecut minimization */
73 /* setup the edge weights */
74 if (adjwgt) {
75 graph->adjwgt = adjwgt;
76 graph->free_adjwgt = 0;
77 }
78 else {
79 adjwgt = graph->adjwgt = ismalloc(graph->nedges, 1, "SetupGraph: adjwgt");
80 }
81 }
82
83
84 /* setup various derived info */
85 SetupGraph_tvwgt(graph);
86
87 if (ctrl->optype == METIS_OP_PMETIS || ctrl->optype == METIS_OP_OMETIS)
88 SetupGraph_label(graph);
89
90 ASSERT(CheckGraph(graph, ctrl->numflag, 1));
91
92 return graph;
93 }
94
95
96 /*************************************************************************/
97 /*! Set's up the tvwgt/invtvwgt info */
98 /*************************************************************************/
SetupGraph_tvwgt(graph_t * graph)99 void SetupGraph_tvwgt(graph_t *graph)
100 {
101 idx_t i;
102
103 if (graph->tvwgt == NULL)
104 graph->tvwgt = imalloc(graph->ncon, "SetupGraph_tvwgt: tvwgt");
105 if (graph->invtvwgt == NULL)
106 graph->invtvwgt = rmalloc(graph->ncon, "SetupGraph_tvwgt: invtvwgt");
107
108 for (i=0; i<graph->ncon; i++) {
109 graph->tvwgt[i] = isum(graph->nvtxs, graph->vwgt+i, graph->ncon);
110 graph->invtvwgt[i] = 1.0/(graph->tvwgt[i] > 0 ? graph->tvwgt[i] : 1);
111 }
112 }
113
114
115 /*************************************************************************/
116 /*! Set's up the label info */
117 /*************************************************************************/
SetupGraph_label(graph_t * graph)118 void SetupGraph_label(graph_t *graph)
119 {
120 idx_t i;
121
122 if (graph->label == NULL)
123 graph->label = imalloc(graph->nvtxs, "SetupGraph_label: label");
124
125 for (i=0; i<graph->nvtxs; i++)
126 graph->label[i] = i;
127 }
128
129
130 /*************************************************************************/
131 /*! Setup the various arrays for the splitted graph */
132 /*************************************************************************/
SetupSplitGraph(graph_t * graph,idx_t snvtxs,idx_t snedges)133 graph_t *SetupSplitGraph(graph_t *graph, idx_t snvtxs, idx_t snedges)
134 {
135 graph_t *sgraph;
136
137 sgraph = CreateGraph();
138
139 sgraph->nvtxs = snvtxs;
140 sgraph->nedges = snedges;
141 sgraph->ncon = graph->ncon;
142
143 /* Allocate memory for the splitted graph */
144 sgraph->xadj = imalloc(snvtxs+1, "SetupSplitGraph: xadj");
145 sgraph->vwgt = imalloc(sgraph->ncon*snvtxs, "SetupSplitGraph: vwgt");
146 sgraph->adjncy = imalloc(snedges, "SetupSplitGraph: adjncy");
147 sgraph->adjwgt = imalloc(snedges, "SetupSplitGraph: adjwgt");
148 sgraph->label = imalloc(snvtxs, "SetupSplitGraph: label");
149 sgraph->tvwgt = imalloc(sgraph->ncon, "SetupSplitGraph: tvwgt");
150 sgraph->invtvwgt = rmalloc(sgraph->ncon, "SetupSplitGraph: invtvwgt");
151
152 if (graph->vsize)
153 sgraph->vsize = imalloc(snvtxs, "SetupSplitGraph: vsize");
154
155 return sgraph;
156 }
157
158
159 /*************************************************************************/
160 /*! This function creates and initializes a graph_t data structure */
161 /*************************************************************************/
CreateGraph(void)162 graph_t *CreateGraph(void)
163 {
164 graph_t *graph;
165
166 graph = (graph_t *)gk_malloc(sizeof(graph_t), "CreateGraph: graph");
167
168 InitGraph(graph);
169
170 return graph;
171 }
172
173
174 /*************************************************************************/
175 /*! This function initializes a graph_t data structure */
176 /*************************************************************************/
InitGraph(graph_t * graph)177 void InitGraph(graph_t *graph)
178 {
179 memset((void *)graph, 0, sizeof(graph_t));
180
181 /* graph size constants */
182 graph->nvtxs = -1;
183 graph->nedges = -1;
184 graph->ncon = -1;
185 graph->mincut = -1;
186 graph->minvol = -1;
187 graph->nbnd = -1;
188
189 /* memory for the graph structure */
190 graph->xadj = NULL;
191 graph->vwgt = NULL;
192 graph->vsize = NULL;
193 graph->adjncy = NULL;
194 graph->adjwgt = NULL;
195 graph->label = NULL;
196 graph->cmap = NULL;
197 graph->tvwgt = NULL;
198 graph->invtvwgt = NULL;
199
200 /* by default these are set to true, but the can be explicitly changed afterwards */
201 graph->free_xadj = 1;
202 graph->free_vwgt = 1;
203 graph->free_vsize = 1;
204 graph->free_adjncy = 1;
205 graph->free_adjwgt = 1;
206
207
208 /* memory for the partition/refinement structure */
209 graph->where = NULL;
210 graph->pwgts = NULL;
211 graph->id = NULL;
212 graph->ed = NULL;
213 graph->bndptr = NULL;
214 graph->bndind = NULL;
215 graph->nrinfo = NULL;
216 graph->ckrinfo = NULL;
217 graph->vkrinfo = NULL;
218
219 /* linked-list structure */
220 graph->coarser = NULL;
221 graph->finer = NULL;
222 }
223
224
225 /*************************************************************************/
226 /*! This function frees the refinement/partition memory stored in a graph */
227 /*************************************************************************/
FreeRData(graph_t * graph)228 void FreeRData(graph_t *graph)
229 {
230
231 /* The following is for the -minconn and -contig to work properly in
232 the vol-refinement routines */
233 if ((void *)graph->ckrinfo == (void *)graph->vkrinfo)
234 graph->ckrinfo = NULL;
235
236
237 /* free partition/refinement structure */
238 gk_free((void **)&graph->where, &graph->pwgts, &graph->id, &graph->ed,
239 &graph->bndptr, &graph->bndind, &graph->nrinfo, &graph->ckrinfo,
240 &graph->vkrinfo, LTERM);
241 }
242
243
244 /*************************************************************************/
245 /*! This function deallocates any memory stored in a graph */
246 /*************************************************************************/
FreeGraph(graph_t ** r_graph)247 void FreeGraph(graph_t **r_graph)
248 {
249 graph_t *graph;
250
251 graph = *r_graph;
252
253 /* free graph structure */
254 if (graph->free_xadj)
255 gk_free((void **)&graph->xadj, LTERM);
256 if (graph->free_vwgt)
257 gk_free((void **)&graph->vwgt, LTERM);
258 if (graph->free_vsize)
259 gk_free((void **)&graph->vsize, LTERM);
260 if (graph->free_adjncy)
261 gk_free((void **)&graph->adjncy, LTERM);
262 if (graph->free_adjwgt)
263 gk_free((void **)&graph->adjwgt, LTERM);
264
265 /* free partition/refinement structure */
266 FreeRData(graph);
267
268 gk_free((void **)&graph->tvwgt, &graph->invtvwgt, &graph->label,
269 &graph->cmap, &graph, LTERM);
270
271 *r_graph = NULL;
272 }
273
274
275