source: inundation/pymetis/metis-4.0/Programs/io.c @ 2051

Last change on this file since 2051 was 2051, checked in by jack, 19 years ago

Python interface to metis. Currently provides only the
METIS_PartMeshNodal function, since that is what is currently needed for partitioning.
Module name is metis.

File size: 9.6 KB
Line 
1/*
2 * Copyright 1997, Regents of the University of Minnesota
3 *
4 * io.c
5 *
6 * This file contains routines related to I/O
7 *
8 * Started 8/28/94
9 * George
10 *
11 * $Id: io.c,v 1.1 1998/11/27 17:59:34 karypis Exp $
12 *
13 */
14
15#include <metis.h>
16
17
18
19/*************************************************************************
20* This function reads the spd matrix
21**************************************************************************/
22void ReadGraph(GraphType *graph, char *filename, int *wgtflag)
23{
24  int i, j, k, l, fmt, readew, readvw, ncon, edge, ewgt;
25  idxtype *xadj, *adjncy, *vwgt, *adjwgt;
26  char *line, *oldstr, *newstr;
27  FILE *fpin;
28
29  InitGraph(graph);
30
31  line = (char *)malloc(sizeof(char)*(MAXLINE+1));
32
33  if ((fpin = fopen(filename, "r")) == NULL) {
34    printf("Failed to open file %s\n", filename);
35    exit(0);
36  }
37
38  do {
39    fgets(line, MAXLINE, fpin);
40  } while (line[0] == '%' && !feof(fpin));
41
42  if (feof(fpin)) {
43    graph->nvtxs = 0;
44    free(line);
45    return;
46  }
47
48  fmt = ncon = 0;
49  sscanf(line, "%d %d %d %d", &(graph->nvtxs), &(graph->nedges), &fmt, &ncon);
50
51  readew = (fmt%10 > 0);
52  readvw = ((fmt/10)%10 > 0);
53  if (fmt >= 100) {
54    printf("Cannot read this type of file format!");
55    exit(0);
56  }
57
58
59  *wgtflag = 0;
60  if (readew)
61    *wgtflag += 1;
62  if (readvw)
63    *wgtflag += 2;
64
65  if (ncon > 0 && !readvw) {
66    printf("------------------------------------------------------------------------------\n");
67    printf("***  I detected an error in your input file  ***\n\n");
68    printf("You specified ncon=%d, but the fmt parameter does not specify vertex weights\n", ncon);
69    printf("Make sure that the fmt parameter is set to either 10 or 11.\n");
70    printf("------------------------------------------------------------------------------\n");
71    exit(0);
72  }
73
74  graph->nedges *=2;
75  ncon = graph->ncon = (ncon == 0 ? 1 : ncon);
76
77  /*printf("%d %d %d %d %d [%d %d]\n", fmt, fmt%10, (fmt/10)%10, ncon, graph->ncon, readew, readvw);*/
78
79  if (graph->nvtxs > MAXIDX) 
80    errexit("\nThe matrix is too big: %d [%d %d]\n", graph->nvtxs, MAXIDX, sizeof(idxtype));
81
82  xadj = graph->xadj = idxsmalloc(graph->nvtxs+1, 0, "ReadGraph: xadj");
83  adjncy = graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: adjncy");
84
85  vwgt = graph->vwgt = (readvw ? idxmalloc(ncon*graph->nvtxs, "ReadGraph: vwgt") : NULL);
86  adjwgt = graph->adjwgt = (readew ? idxmalloc(graph->nedges, "ReadGraph: adjwgt") : NULL);
87
88  /* Start reading the graph file */
89  for (xadj[0]=0, k=0, i=0; i<graph->nvtxs; i++) {
90    do {
91      fgets(line, MAXLINE, fpin);
92    } while (line[0] == '%' && !feof(fpin));
93    oldstr = line;
94    newstr = NULL;
95
96    if (strlen(line) == MAXLINE) 
97      errexit("\nBuffer for fgets not big enough!\n");
98
99    if (readvw) {
100      for (l=0; l<ncon; l++) {
101        vwgt[i*ncon+l] = (int)strtol(oldstr, &newstr, 10);
102        oldstr = newstr;
103      }
104    }
105
106    for (;;) {
107      edge = (int)strtol(oldstr, &newstr, 10) -1;
108      oldstr = newstr;
109
110      if (readew) {
111        ewgt = (int)strtol(oldstr, &newstr, 10);
112        oldstr = newstr;
113      }
114
115      if (edge < 0)
116        break;
117
118      adjncy[k] = edge;
119      if (readew) 
120        adjwgt[k] = ewgt;
121      k++;
122    } 
123    xadj[i+1] = k;
124  }
125
126  fclose(fpin);
127
128  if (k != graph->nedges) {
129    printf("------------------------------------------------------------------------------\n");
130    printf("***  I detected an error in your input file  ***\n\n");
131    printf("In the first line of the file, you specified that the graph contained\n%d edges. However, I only found %d edges in the file.\n", graph->nedges/2, k/2);
132    if (2*k == graph->nedges) {
133      printf("\n *> I detected that you specified twice the number of edges that you have in\n");
134      printf("    the file. Remember that the number of edges specified in the first line\n");
135      printf("    counts each edge between vertices v and u only once.\n\n");
136    }
137    printf("Please specify the correct number of edges in the first line of the file.\n");
138    printf("------------------------------------------------------------------------------\n");
139    exit(0);
140  }
141
142  free(line);
143}
144
145
146
147/*************************************************************************
148* This function writes out the partition vector
149**************************************************************************/
150void WritePartition(char *fname, idxtype *part, int n, int nparts)
151{
152  FILE *fpout;
153  int i;
154  char filename[256];
155
156  sprintf(filename,"%s.part.%d",fname, nparts);
157
158  if ((fpout = fopen(filename, "w")) == NULL) 
159    errexit("Problems in opening the partition file: %s", filename);
160
161  for (i=0; i<n; i++)
162    fprintf(fpout,"%d\n",part[i]);
163
164  fclose(fpout);
165
166}
167
168
169/*************************************************************************
170* This function writes out the partition vectors for a mesh
171**************************************************************************/
172void WriteMeshPartition(char *fname, int nparts, int ne, idxtype *epart, int nn, idxtype *npart)
173{
174  FILE *fpout;
175  int i;
176  char filename[256];
177
178  sprintf(filename,"%s.epart.%d",fname, nparts);
179
180  if ((fpout = fopen(filename, "w")) == NULL) 
181    errexit("Problems in opening the partition file: %s", filename);
182
183  for (i=0; i<ne; i++)
184    fprintf(fpout,"%d\n", epart[i]);
185
186  fclose(fpout);
187
188  sprintf(filename,"%s.npart.%d",fname, nparts);
189
190  if ((fpout = fopen(filename, "w")) == NULL) 
191    errexit("Problems in opening the partition file: %s", filename);
192
193  for (i=0; i<nn; i++)
194    fprintf(fpout,"%d\n", npart[i]);
195
196  fclose(fpout);
197
198
199}
200
201
202
203/*************************************************************************
204* This function writes out the partition vector
205**************************************************************************/
206void WritePermutation(char *fname, idxtype *iperm, int n)
207{
208  FILE *fpout;
209  int i;
210  char filename[256];
211
212  sprintf(filename,"%s.iperm",fname);
213
214  if ((fpout = fopen(filename, "w")) == NULL) 
215    errexit("Problems in opening the permutation file: %s", filename);
216
217  for (i=0; i<n; i++)
218    fprintf(fpout,"%d\n", iperm[i]);
219
220  fclose(fpout);
221
222}
223
224
225
226/*************************************************************************
227* This function checks if a graph is valid
228**************************************************************************/
229int CheckGraph(GraphType *graph)
230{
231  int i, j, k, l, nvtxs, err=0;
232  idxtype *xadj, *adjncy, *adjwgt;
233
234  nvtxs = graph->nvtxs;
235  xadj = graph->xadj;
236  adjncy = graph->adjncy;
237  adjwgt = graph->adjwgt;
238
239
240  for (i=0; i<nvtxs; i++) {
241    for (j=xadj[i]; j<xadj[i+1]; j++) {
242      k = adjncy[j];
243
244      if (i == k) {
245        printf("Vertex %d contains a self-loop (i.e., diagonal entry in the matrix)!\n", i);
246        err++;
247      }
248      else {
249        for (l=xadj[k]; l<xadj[k+1]; l++) {
250          if (adjncy[l] == i) {
251            if (adjwgt != NULL && adjwgt[l] != adjwgt[j]) {
252              printf("Edges (%d %d) and (%d %d) do not have the same weight! %d %d\n", i,k,k,i, adjwgt[l], adjwgt[adjncy[j]]);
253              err++;
254            }
255            break;
256          }
257        }
258        if (l == xadj[k+1]) {
259          printf("Missing edge: (%d %d)!\n", k, i);
260          err++;
261        }
262      }
263    }
264  }
265
266  if (err > 0) 
267    printf("A total of %d errors exist in the input file. Correct them, and run again!\n", err);
268
269  return (err == 0 ? 1 : 0);
270}
271
272
273/*************************************************************************
274* This function reads the element node array of a mesh
275**************************************************************************/
276idxtype *ReadMesh(char *filename, int *ne, int *nn, int *etype)
277{
278  int i, j, k, esize;
279  idxtype *elmnts;
280  FILE *fpin;
281
282  if ((fpin = fopen(filename, "r")) == NULL) {
283    printf("Failed to open file %s\n", filename);
284    exit(0);
285  }
286
287  fscanf(fpin, "%d %d", ne, etype);
288
289  switch (*etype) {
290    case 1:
291      esize = 3;
292      break;
293    case 2:
294      esize = 4;
295      break;
296    case 3:
297      esize = 8;
298      break;
299    case 4:
300      esize = 4;
301      break;
302    default:
303      errexit("Unknown mesh-element type: %d\n", *etype);
304  }
305
306  elmnts = idxmalloc(esize*(*ne), "ReadMesh: elmnts");
307
308  for (j=esize*(*ne), i=0; i<j; i++) {
309    fscanf(fpin, "%d", elmnts+i);
310    elmnts[i]--;
311  }
312
313  fclose(fpin);
314
315  *nn = elmnts[idxamax(j, elmnts)]+1;
316
317  return elmnts;
318}
319
320
321/*************************************************************************
322* This function writes a graphs into a file
323**************************************************************************/
324void WriteGraph(char *filename, int nvtxs, idxtype *xadj, idxtype *adjncy)
325{
326  int i, j;
327  FILE *fpout;
328
329  if ((fpout = fopen(filename, "w")) == NULL) {
330    printf("Failed to open file %s\n", filename);
331    exit(0);
332  }
333
334  fprintf(fpout, "%d %d", nvtxs, xadj[nvtxs]/2);
335
336  for (i=0; i<nvtxs; i++) {
337    fprintf(fpout, "\n");
338    for (j=xadj[i]; j<xadj[i+1]; j++)
339      fprintf(fpout, " %d", adjncy[j]+1);
340  }
341
342  fclose(fpout);
343}
344
345
346/*************************************************************************
347* This function writes a graphs into a file
348**************************************************************************/
349void WriteMocGraph(GraphType *graph)
350{
351  int i, j, nvtxs, ncon;
352  idxtype *xadj, *adjncy;
353  float *nvwgt;
354  char filename[256];
355  FILE *fpout;
356
357  nvtxs = graph->nvtxs;
358  ncon = graph->ncon;
359  xadj = graph->xadj;
360  adjncy = graph->adjncy;
361  nvwgt = graph->nvwgt;
362
363  sprintf(filename, "moc.graph.%d.%d", nvtxs, ncon);
364
365  if ((fpout = fopen(filename, "w")) == NULL) {
366    printf("Failed to open file %s\n", filename);
367    exit(0);
368  }
369
370  fprintf(fpout, "%d %d 10 1 %d", nvtxs, xadj[nvtxs]/2, ncon);
371
372  for (i=0; i<nvtxs; i++) {
373    fprintf(fpout, "\n");
374    for (j=0; j<ncon; j++)
375      fprintf(fpout, "%d ", (int)((float)10e6*nvwgt[i*ncon+j]));
376
377    for (j=xadj[i]; j<xadj[i+1]; j++)
378      fprintf(fpout, " %d", adjncy[j]+1);
379  }
380
381  fclose(fpout);
382}
Note: See TracBrowser for help on using the repository browser.