Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 53394
Collapse All | Expand All

(-)metis-5.0pre2_orig/GKlib/trunk/Makefile.am (+25 lines)
Line 0 Link Here
1
AM_CFLAGS = -DLINUX -std=c99 -D_FILE_OFFSET_BITS=64
2
noinst_LTLIBRARIES = libGKlib.la
3
noinst_HEADERS = GKlib.h
4
5
common_src = b64.c \
6
	blas.c \
7
	dfkvkselect.c \
8
	dlmalloc.c \
9
	error.c \
10
	fs.c \
11
	getopt.c \
12
	htable.c \
13
	io.c \
14
	memory.c \
15
	omp.c \
16
	pdb.c \
17
	seq.c \
18
	sort.c \
19
	string.c \
20
	timers.c \
21
	tokenizer.c \
22
	util.c
23
24
25
libGKlib_la_SOURCES =  $(common_src)
(-)metis-5.0pre2_orig/Makefile.am (+3 lines)
Line 0 Link Here
1
SUBDIRS = GKlib/trunk libmetis programs test
2
EXTRA_DIST = CHANGES*
3
include_HEADERS = include/metis.h
(-)metis-5.0pre2_orig/configure.ac (+14 lines)
Line 0 Link Here
1
AC_INIT(metis, 5.0pre2, metis@cs.umn.edu)
2
AM_INIT_AUTOMAKE([foreign])
3
AC_CHECK_LIB(m, [sqrt, pow, log] )
4
AC_PROG_INSTALL
5
AC_PROG_LIBTOOL
6
AC_CONFIG_FILES( \
7
    Makefile \
8
    GKlib/trunk/Makefile \
9
    libmetis/Makefile \
10
    programs/Makefile \
11
    test/Makefile 
12
)
13
AC_OUTPUT
14
(-)metis-5.0pre2_orig/libmetis/Makefile.am (+17 lines)
Line 0 Link Here
1
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/GKlib/trunk -DLINUX -DUNIX -D_FILE_OFFSET_BITS=64
2
lib_LTLIBRARIES = libmetis.la
3
libmetis_la_SOURCES= \
4
	balance.c bucketsort.c ccgraph.c checkgraph.c cmetis.c \
5
	coarsen.c compress.c debug.c estmem.c fm.c fortran.c \
6
	frename.c graph.c initpart.c kfmetis.c kmetis.c kvmetis.c \
7
	kwayfm.c kwayrefine.c kwayvolfm.c kwayvolrefine.c match.c \
8
	mbalance.c mbalance2.c mcoarsen.c memory.c mesh.c meshpart.c \
9
	mfm.c mfm2.c mincover.c minitpart.c minitpart2.c mkmetis.c \
10
	mkwayfmh.c mkwayrefine.c mmatch.c mmd.c mpmetis.c mrefine.c \
11
	mrefine2.c mrkmetis.c mutil.c myqsort.c ometis.c parmetis.c \
12
	pmetis.c pqueue.c refine.c rkmetis.c separator.c sfm.c \
13
	srefine.c stat.c streamio.c subdomains.c timing.c util.c \
14
	smbfactor.c
15
16
libmetis_la_LIBADD = \
17
	$(top_srcdir)/GKlib/trunk/libGKlib.la
(-)metis-5.0pre2_orig/libmetis/smbfactor.c (+383 lines)
Line 0 Link Here
1
/*
2
 * Copyright 1997, Regents of the University of Minnesota
3
 *
4
 * smbfactor.c
5
 *
6
 * This file performs the symbolic factorization of a matrix
7
 *
8
 * Started 8/1/97
9
 * George
10
 *
11
 * $Id: smbfactor.c,v 1.2 2002/08/10 06:02:55 karypis Exp $
12
 *
13
 */
14
15
#include <metislib.h>
16
/*************************************************************************
17
* This function sets up data structures for fill-in computations
18
**************************************************************************/
19
void ComputeFillIn(GraphType *graph, idxtype *iperm)
20
{
21
  idxtype i, j, k, nvtxs, maxlnz, maxsub;
22
  idxtype *xadj, *adjncy;
23
  idxtype *perm, *xlnz, *xnzsub, *nzsub;
24
  double opc;
25
26
/*
27
  mprintf("\nSymbolic factorization... --------------------------------------------\n");
28
*/
29
30
  nvtxs = graph->nvtxs;
31
  xadj = graph->xadj;
32
  adjncy = graph->adjncy;
33
34
  maxsub = 4*xadj[nvtxs];
35
36
  /* Relabel the vertices so that it starts from 1 */
37
  k = xadj[nvtxs];
38
  for (i=0; i<k; i++)
39
    adjncy[i]++;
40
  for (i=0; i<nvtxs+1; i++)
41
    xadj[i]++;
42
43
  /* Allocate the required memory */
44
  perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
45
  xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
46
  xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
47
  nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
48
49
  /* Construct perm from iperm and change the numbering of iperm */
50
  for (i=0; i<nvtxs; i++)
51
    perm[iperm[i]] = i;
52
  for (i=0; i<nvtxs; i++) {
53
    iperm[i]++;
54
    perm[i]++;
55
  }
56
  
57
  /*
58
   * Call sparspak routine.
59
   */
60
  if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
61
    gk_free((void **)&nzsub, LTERM);
62
63
    maxsub = 4*maxsub; 
64
    nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
65
    if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) 
66
      errexit("MAXSUB is too small!");
67
  }
68
69
  opc = 0;
70
  for (i=0; i<nvtxs; i++)
71
    xlnz[i]--;
72
  for (i=0; i<nvtxs; i++)
73
    opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
74
75
  mprintf("  Nonzeros: %D, \tOperation Count: %6.4le\n", maxlnz, opc);
76
77
78
  gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
79
80
81
  /* Relabel the vertices so that it starts from 0 */
82
  for (i=0; i<nvtxs; i++)
83
    iperm[i]--;
84
  for (i=0; i<nvtxs+1; i++)
85
    xadj[i]--;
86
  k = xadj[nvtxs];
87
  for (i=0; i<k; i++)
88
    adjncy[i]--;
89
90
}
91
92
93
94
/*************************************************************************
95
* This function sets up data structures for fill-in computations
96
**************************************************************************/
97
idxtype ComputeFillIn2(GraphType *graph, idxtype *iperm)
98
{
99
  idxtype i, j, k, nvtxs, maxlnz, maxsub;
100
  idxtype *xadj, *adjncy;
101
  idxtype *perm, *xlnz, *xnzsub, *nzsub;
102
  double opc;
103
104
  nvtxs = graph->nvtxs;
105
  xadj = graph->xadj;
106
  adjncy = graph->adjncy;
107
108
  maxsub = 4*xadj[nvtxs];
109
110
  /* Relabel the vertices so that it starts from 1 */
111
  k = xadj[nvtxs];
112
  for (i=0; i<k; i++)
113
    adjncy[i]++;
114
  for (i=0; i<nvtxs+1; i++)
115
    xadj[i]++;
116
117
  /* Allocate the required memory */
118
  perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
119
  xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
120
  xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
121
  nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
122
123
  /* Construct perm from iperm and change the numbering of iperm */
124
  for (i=0; i<nvtxs; i++)
125
    perm[iperm[i]] = i;
126
  for (i=0; i<nvtxs; i++) {
127
    iperm[i]++;
128
    perm[i]++;
129
  }
130
  
131
  /*
132
   * Call sparspak routine.
133
   */
134
  if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
135
    gk_free((void **)&nzsub, LTERM);
136
137
    maxsub = 4*maxsub; 
138
    nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
139
    if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) 
140
      errexit("MAXSUB is too small!");
141
  }
142
143
  opc = 0;
144
  for (i=0; i<nvtxs; i++)
145
    xlnz[i]--;
146
  for (i=0; i<nvtxs; i++)
147
    opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
148
149
150
  gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
151
152
153
  /* Relabel the vertices so that it starts from 0 */
154
  for (i=0; i<nvtxs; i++)
155
    iperm[i]--;
156
  for (i=0; i<nvtxs+1; i++)
157
    xadj[i]--;
158
  k = xadj[nvtxs];
159
  for (i=0; i<k; i++)
160
    adjncy[i]--;
161
162
  return maxlnz;
163
164
}
165
166
167
/*****************************************************************          
168
**********     SMBFCT ..... SYMBOLIC FACTORIZATION       ********* 
169
******************************************************************          
170
*   PURPOSE - THIS ROUTINE PERFORMS SYMBOLIC FACTORIZATION               
171
*   ON A PERMUTED LINEAR SYSTEM AND IT ALSO SETS UP THE               
172
*   COMPRESSED DATA STRUCTURE FOR THE SYSTEM.                         
173
*
174
*   INPUT PARAMETERS -                                               
175
*      NEQNS - NUMBER OF EQUATIONS.                                 
176
*      (XADJ, ADJNCY) - THE ADJACENCY STRUCTURE.                   
177
*      (PERM, INVP) - THE PERMUTATION VECTOR AND ITS INVERSE.     
178
*
179
*   UPDATED PARAMETERS -                                         
180
*      MAXSUB - SIZE OF THE SUBSCRIPT ARRAY NZSUB.  ON RETURN,  
181
*             IT CONTAINS THE NUMBER OF SUBSCRIPTS USED        
182
*
183
*   OUTPUT PARAMETERS -                                       
184
*      XLNZ - INDEX INTO THE NONZERO STORAGE VECTOR LNZ.   
185
*      (XNZSUB, NZSUB) - THE COMPRESSED SUBSCRIPT VECTORS. 
186
*      MAXLNZ - THE NUMBER OF NONZEROS FOUND.             
187
*
188
*******************************************************************/
189
idxtype smbfct(idxtype neqns, idxtype *xadj, idxtype *adjncy, idxtype *perm, idxtype *invp, 
190
	       idxtype *xlnz, idxtype *maxlnz, idxtype *xnzsub, idxtype *nzsub, idxtype *maxsub)
191
{
192
  /* Local variables */
193
  idxtype node, rchm, mrgk, lmax, i, j, k, m, nabor, nzbeg, nzend;
194
  idxtype kxsub, jstop, jstrt, mrkflg, inz, knz, flag;
195
  idxtype *mrglnk, *marker, *rchlnk;
196
197
  rchlnk = idxmalloc(neqns+1, "smbfct: rchlnk");
198
  marker = idxsmalloc(neqns+1, 0, "smbfct: marker");
199
  mrglnk = idxsmalloc(neqns+1, 0, "smbfct: mgrlnk");
200
201
  /* Parameter adjustments */
202
  --marker;
203
  --mrglnk;
204
  --rchlnk;
205
  --nzsub;
206
  --xnzsub;
207
  --xlnz;
208
  --invp;
209
  --perm;
210
  --adjncy;
211
  --xadj;
212
213
  /* Function Body */
214
  flag = 0;
215
  nzbeg = 1;
216
  nzend = 0;
217
  xlnz[1] = 1;
218
219
  /* FOR EACH COLUMN KNZ COUNTS THE NUMBER OF NONZEROS IN COLUMN K ACCUMULATED IN RCHLNK. */
220
  for (k = 1; k <= neqns; ++k) {
221
    knz = 0;
222
    mrgk = mrglnk[k];
223
    mrkflg = 0;
224
    marker[k] = k;
225
    if (mrgk != 0) 
226
      marker[k] = marker[mrgk];
227
    xnzsub[k] = nzend;
228
    node = perm[k];
229
230
    if (xadj[node] >= xadj[node+1]) {
231
      xlnz[k+1] = xlnz[k];
232
      continue;
233
    }
234
235
    /* USE RCHLNK TO LINK THROUGH THE STRUCTURE OF A(*,K) BELOW DIAGONAL */
236
    rchlnk[k] = neqns+1;
237
    for (j=xadj[node]; j<xadj[node+1]; j++) {
238
      nabor = invp[adjncy[j]];
239
      if (nabor <= k) 
240
        continue;
241
      rchm = k;
242
243
      do {
244
        m = rchm;
245
        rchm = rchlnk[m];
246
      } while (rchm <= nabor); 
247
248
      knz++;
249
      rchlnk[m] = nabor;
250
      rchlnk[nabor] = rchm;
251
      if (marker[nabor] != marker[k]) 
252
        mrkflg = 1;
253
    }
254
255
    /* TEST FOR MASS SYMBOLIC ELIMINATION */
256
    lmax = 0;
257
    if (mrkflg != 0 || mrgk == 0 || mrglnk[mrgk] != 0) 
258
      goto L350;
259
    xnzsub[k] = xnzsub[mrgk] + 1;
260
    knz = xlnz[mrgk + 1] - (xlnz[mrgk] + 1);
261
    goto L1400;
262
263
264
    /* LINK THROUGH EACH COLUMN I THAT AFFECTS L(*,K) */
265
L350:
266
    i = k;
267
    while ((i = mrglnk[i]) != 0) {
268
      inz = xlnz[i+1] - (xlnz[i]+1);
269
      jstrt = xnzsub[i] + 1;
270
      jstop = xnzsub[i] + inz;
271
272
      if (inz > lmax) { 
273
        lmax = inz;
274
        xnzsub[k] = jstrt;
275
      }
276
277
      /* MERGE STRUCTURE OF L(*,I) IN NZSUB INTO RCHLNK. */ 
278
      rchm = k;
279
      for (j = jstrt; j <= jstop; ++j) {
280
        nabor = nzsub[j];
281
        do {
282
          m = rchm;
283
          rchm = rchlnk[m];
284
        } while (rchm < nabor);
285
286
        if (rchm != nabor) {
287
          knz++;
288
          rchlnk[m] = nabor;
289
          rchlnk[nabor] = rchm;
290
          rchm = nabor;
291
        }
292
      }
293
    }
294
295
    /* CHECK IF SUBSCRIPTS DUPLICATE THOSE OF ANOTHER COLUMN */
296
    if (knz == lmax) 
297
      goto L1400;
298
299
    /* OR IF TAIL OF K-1ST COLUMN MATCHES HEAD OF KTH */
300
    if (nzbeg > nzend) 
301
      goto L1200;
302
303
    i = rchlnk[k];
304
    for (jstrt = nzbeg; jstrt <= nzend; ++jstrt) {
305
      if (nzsub[jstrt] < i) 
306
        continue;
307
308
      if (nzsub[jstrt] == i) 
309
        goto L1000;
310
      else 
311
        goto L1200;
312
    }
313
    goto L1200;
314
315
L1000:
316
    xnzsub[k] = jstrt;
317
    for (j = jstrt; j <= nzend; ++j) {
318
      if (nzsub[j] != i) 
319
        goto L1200;
320
      
321
      i = rchlnk[i];
322
      if (i > neqns) 
323
        goto L1400;
324
    }
325
    nzend = jstrt - 1;
326
327
    /* COPY THE STRUCTURE OF L(*,K) FROM RCHLNK TO THE DATA STRUCTURE (XNZSUB, NZSUB) */
328
L1200:
329
    nzbeg = nzend + 1;
330
    nzend += knz;
331
332
    if (nzend > *maxsub) {
333
      flag = 1; /* Out of memory */
334
      break;
335
    }
336
337
    i = k;
338
    for (j=nzbeg; j<=nzend; ++j) {
339
      i = rchlnk[i];
340
      nzsub[j] = i;
341
      marker[i] = k;
342
    }
343
    xnzsub[k] = nzbeg;
344
    marker[k] = k;
345
346
    /*
347
     * UPDATE THE VECTOR MRGLNK.  NOTE COLUMN L(*,K) JUST FOUND   
348
     * IS REQUIRED TO DETERMINE COLUMN L(*,J), WHERE              
349
     * L(J,K) IS THE FIRST NONZERO IN L(*,K) BELOW DIAGONAL.      
350
     */
351
L1400:
352
    if (knz > 1) { 
353
      kxsub = xnzsub[k];
354
      i = nzsub[kxsub];
355
      mrglnk[k] = mrglnk[i];
356
      mrglnk[i] = k;
357
    }
358
359
    xlnz[k + 1] = xlnz[k] + knz;
360
  }
361
362
  if (flag == 0) {
363
    *maxlnz = xlnz[neqns] - 1;
364
    *maxsub = xnzsub[neqns];
365
    xnzsub[neqns + 1] = xnzsub[neqns];
366
  }
367
368
  marker++;
369
  mrglnk++;
370
  rchlnk++;
371
  nzsub++;
372
  xnzsub++;
373
  xlnz++;
374
  invp++;
375
  perm++;
376
  adjncy++;
377
  xadj++;
378
  gk_free((void **)&rchlnk, &mrglnk, &marker, LTERM);
379
380
  return flag;
381
  
382
} 
383
(-)metis-5.0pre2_orig/programs/Makefile.am (+20 lines)
Line 0 Link Here
1
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/GKlib/trunk -DLINUX -DUNIX -D_FILE_OFFSET_BITS=64
2
AM_LDFLAGS = -L$(top_builddir)/libmetis -lmetis
3
4
bin_PROGRAMS = cmetis graphchk kfmetis kmetis mesh2dual mesh2nodal metis \
5
	oemetis onmetis partdmesh partnmesh pmetis
6
7
# Differing from upstream, a lot of these get smbfactor.c as we need
8
# ComputeFillIn2, which is referenced in proto.h <- metisbin.h
9
cmetis_SOURCES = cmetis.c io.c cmdline_cmetis.c 
10
graphchk_SOURCES = graphchk.c io.c 
11
kfmetis_SOURCES = kfmetis.c io.c cmdline_kfmetis.c 
12
kmetis_SOURCES = kmetis.c io.c 
13
mesh2dual_SOURCES = mesh2dual.c io.c 
14
mesh2nodal_SOURCES = mesh2nodal.c io.c 
15
metis_SOURCES = metis.c io.c 
16
oemetis_SOURCES = oemetis.c io.c 
17
onmetis_SOURCES = onmetis.c io.c 
18
partdmesh_SOURCES = partdmesh.c io.c 
19
partnmesh_SOURCES = partnmesh.c io.c 
20
pmetis_SOURCES = pmetis.c io.c cmdline_pmetis.c 
(-)metis-5.0pre2_orig/programs/smbfactor.c (-385 lines)
Lines 1-385 Link Here
1
/*
2
 * Copyright 1997, Regents of the University of Minnesota
3
 *
4
 * smbfactor.c
5
 *
6
 * This file performs the symbolic factorization of a matrix
7
 *
8
 * Started 8/1/97
9
 * George
10
 *
11
 * $Id: smbfactor.c,v 1.2 2002/08/10 06:02:55 karypis Exp $
12
 *
13
 */
14
15
#include <metisbin.h>
16
17
18
/*************************************************************************
19
* This function sets up data structures for fill-in computations
20
**************************************************************************/
21
void ComputeFillIn(GraphType *graph, idxtype *iperm)
22
{
23
  idxtype i, j, k, nvtxs, maxlnz, maxsub;
24
  idxtype *xadj, *adjncy;
25
  idxtype *perm, *xlnz, *xnzsub, *nzsub;
26
  double opc;
27
28
/*
29
  mprintf("\nSymbolic factorization... --------------------------------------------\n");
30
*/
31
32
  nvtxs = graph->nvtxs;
33
  xadj = graph->xadj;
34
  adjncy = graph->adjncy;
35
36
  maxsub = 4*xadj[nvtxs];
37
38
  /* Relabel the vertices so that it starts from 1 */
39
  k = xadj[nvtxs];
40
  for (i=0; i<k; i++)
41
    adjncy[i]++;
42
  for (i=0; i<nvtxs+1; i++)
43
    xadj[i]++;
44
45
  /* Allocate the required memory */
46
  perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
47
  xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
48
  xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
49
  nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
50
51
  /* Construct perm from iperm and change the numbering of iperm */
52
  for (i=0; i<nvtxs; i++)
53
    perm[iperm[i]] = i;
54
  for (i=0; i<nvtxs; i++) {
55
    iperm[i]++;
56
    perm[i]++;
57
  }
58
  
59
  /*
60
   * Call sparspak routine.
61
   */
62
  if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
63
    gk_free((void **)&nzsub, LTERM);
64
65
    maxsub = 4*maxsub; 
66
    nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
67
    if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) 
68
      errexit("MAXSUB is too small!");
69
  }
70
71
  opc = 0;
72
  for (i=0; i<nvtxs; i++)
73
    xlnz[i]--;
74
  for (i=0; i<nvtxs; i++)
75
    opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
76
77
  mprintf("  Nonzeros: %D, \tOperation Count: %6.4le\n", maxlnz, opc);
78
79
80
  gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
81
82
83
  /* Relabel the vertices so that it starts from 0 */
84
  for (i=0; i<nvtxs; i++)
85
    iperm[i]--;
86
  for (i=0; i<nvtxs+1; i++)
87
    xadj[i]--;
88
  k = xadj[nvtxs];
89
  for (i=0; i<k; i++)
90
    adjncy[i]--;
91
92
}
93
94
95
96
/*************************************************************************
97
* This function sets up data structures for fill-in computations
98
**************************************************************************/
99
idxtype ComputeFillIn2(GraphType *graph, idxtype *iperm)
100
{
101
  idxtype i, j, k, nvtxs, maxlnz, maxsub;
102
  idxtype *xadj, *adjncy;
103
  idxtype *perm, *xlnz, *xnzsub, *nzsub;
104
  double opc;
105
106
  nvtxs = graph->nvtxs;
107
  xadj = graph->xadj;
108
  adjncy = graph->adjncy;
109
110
  maxsub = 4*xadj[nvtxs];
111
112
  /* Relabel the vertices so that it starts from 1 */
113
  k = xadj[nvtxs];
114
  for (i=0; i<k; i++)
115
    adjncy[i]++;
116
  for (i=0; i<nvtxs+1; i++)
117
    xadj[i]++;
118
119
  /* Allocate the required memory */
120
  perm = idxmalloc(nvtxs+1, "ComputeFillIn: perm");
121
  xlnz = idxmalloc(nvtxs+1, "ComputeFillIn: xlnz");
122
  xnzsub = idxmalloc(nvtxs+1, "ComputeFillIn: xnzsub");
123
  nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
124
125
  /* Construct perm from iperm and change the numbering of iperm */
126
  for (i=0; i<nvtxs; i++)
127
    perm[iperm[i]] = i;
128
  for (i=0; i<nvtxs; i++) {
129
    iperm[i]++;
130
    perm[i]++;
131
  }
132
  
133
  /*
134
   * Call sparspak routine.
135
   */
136
  if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) {
137
    gk_free((void **)&nzsub, LTERM);
138
139
    maxsub = 4*maxsub; 
140
    nzsub = idxmalloc(maxsub, "ComputeFillIn: nzsub");
141
    if (smbfct(nvtxs, xadj, adjncy, perm, iperm, xlnz, &maxlnz, xnzsub, nzsub, &maxsub)) 
142
      errexit("MAXSUB is too small!");
143
  }
144
145
  opc = 0;
146
  for (i=0; i<nvtxs; i++)
147
    xlnz[i]--;
148
  for (i=0; i<nvtxs; i++)
149
    opc += (xlnz[i+1]-xlnz[i])*(xlnz[i+1]-xlnz[i]) - (xlnz[i+1]-xlnz[i]);
150
151
152
  gk_free((void **)&perm, &xlnz, &xnzsub, &nzsub, LTERM);
153
154
155
  /* Relabel the vertices so that it starts from 0 */
156
  for (i=0; i<nvtxs; i++)
157
    iperm[i]--;
158
  for (i=0; i<nvtxs+1; i++)
159
    xadj[i]--;
160
  k = xadj[nvtxs];
161
  for (i=0; i<k; i++)
162
    adjncy[i]--;
163
164
  return maxlnz;
165
166
}
167
168
169
/*****************************************************************          
170
**********     SMBFCT ..... SYMBOLIC FACTORIZATION       ********* 
171
******************************************************************          
172
*   PURPOSE - THIS ROUTINE PERFORMS SYMBOLIC FACTORIZATION               
173
*   ON A PERMUTED LINEAR SYSTEM AND IT ALSO SETS UP THE               
174
*   COMPRESSED DATA STRUCTURE FOR THE SYSTEM.                         
175
*
176
*   INPUT PARAMETERS -                                               
177
*      NEQNS - NUMBER OF EQUATIONS.                                 
178
*      (XADJ, ADJNCY) - THE ADJACENCY STRUCTURE.                   
179
*      (PERM, INVP) - THE PERMUTATION VECTOR AND ITS INVERSE.     
180
*
181
*   UPDATED PARAMETERS -                                         
182
*      MAXSUB - SIZE OF THE SUBSCRIPT ARRAY NZSUB.  ON RETURN,  
183
*             IT CONTAINS THE NUMBER OF SUBSCRIPTS USED        
184
*
185
*   OUTPUT PARAMETERS -                                       
186
*      XLNZ - INDEX INTO THE NONZERO STORAGE VECTOR LNZ.   
187
*      (XNZSUB, NZSUB) - THE COMPRESSED SUBSCRIPT VECTORS. 
188
*      MAXLNZ - THE NUMBER OF NONZEROS FOUND.             
189
*
190
*******************************************************************/
191
idxtype smbfct(idxtype neqns, idxtype *xadj, idxtype *adjncy, idxtype *perm, idxtype *invp, 
192
	       idxtype *xlnz, idxtype *maxlnz, idxtype *xnzsub, idxtype *nzsub, idxtype *maxsub)
193
{
194
  /* Local variables */
195
  idxtype node, rchm, mrgk, lmax, i, j, k, m, nabor, nzbeg, nzend;
196
  idxtype kxsub, jstop, jstrt, mrkflg, inz, knz, flag;
197
  idxtype *mrglnk, *marker, *rchlnk;
198
199
  rchlnk = idxmalloc(neqns+1, "smbfct: rchlnk");
200
  marker = idxsmalloc(neqns+1, 0, "smbfct: marker");
201
  mrglnk = idxsmalloc(neqns+1, 0, "smbfct: mgrlnk");
202
203
  /* Parameter adjustments */
204
  --marker;
205
  --mrglnk;
206
  --rchlnk;
207
  --nzsub;
208
  --xnzsub;
209
  --xlnz;
210
  --invp;
211
  --perm;
212
  --adjncy;
213
  --xadj;
214
215
  /* Function Body */
216
  flag = 0;
217
  nzbeg = 1;
218
  nzend = 0;
219
  xlnz[1] = 1;
220
221
  /* FOR EACH COLUMN KNZ COUNTS THE NUMBER OF NONZEROS IN COLUMN K ACCUMULATED IN RCHLNK. */
222
  for (k = 1; k <= neqns; ++k) {
223
    knz = 0;
224
    mrgk = mrglnk[k];
225
    mrkflg = 0;
226
    marker[k] = k;
227
    if (mrgk != 0) 
228
      marker[k] = marker[mrgk];
229
    xnzsub[k] = nzend;
230
    node = perm[k];
231
232
    if (xadj[node] >= xadj[node+1]) {
233
      xlnz[k+1] = xlnz[k];
234
      continue;
235
    }
236
237
    /* USE RCHLNK TO LINK THROUGH THE STRUCTURE OF A(*,K) BELOW DIAGONAL */
238
    rchlnk[k] = neqns+1;
239
    for (j=xadj[node]; j<xadj[node+1]; j++) {
240
      nabor = invp[adjncy[j]];
241
      if (nabor <= k) 
242
        continue;
243
      rchm = k;
244
245
      do {
246
        m = rchm;
247
        rchm = rchlnk[m];
248
      } while (rchm <= nabor); 
249
250
      knz++;
251
      rchlnk[m] = nabor;
252
      rchlnk[nabor] = rchm;
253
      if (marker[nabor] != marker[k]) 
254
        mrkflg = 1;
255
    }
256
257
    /* TEST FOR MASS SYMBOLIC ELIMINATION */
258
    lmax = 0;
259
    if (mrkflg != 0 || mrgk == 0 || mrglnk[mrgk] != 0) 
260
      goto L350;
261
    xnzsub[k] = xnzsub[mrgk] + 1;
262
    knz = xlnz[mrgk + 1] - (xlnz[mrgk] + 1);
263
    goto L1400;
264
265
266
    /* LINK THROUGH EACH COLUMN I THAT AFFECTS L(*,K) */
267
L350:
268
    i = k;
269
    while ((i = mrglnk[i]) != 0) {
270
      inz = xlnz[i+1] - (xlnz[i]+1);
271
      jstrt = xnzsub[i] + 1;
272
      jstop = xnzsub[i] + inz;
273
274
      if (inz > lmax) { 
275
        lmax = inz;
276
        xnzsub[k] = jstrt;
277
      }
278
279
      /* MERGE STRUCTURE OF L(*,I) IN NZSUB INTO RCHLNK. */ 
280
      rchm = k;
281
      for (j = jstrt; j <= jstop; ++j) {
282
        nabor = nzsub[j];
283
        do {
284
          m = rchm;
285
          rchm = rchlnk[m];
286
        } while (rchm < nabor);
287
288
        if (rchm != nabor) {
289
          knz++;
290
          rchlnk[m] = nabor;
291
          rchlnk[nabor] = rchm;
292
          rchm = nabor;
293
        }
294
      }
295
    }
296
297
    /* CHECK IF SUBSCRIPTS DUPLICATE THOSE OF ANOTHER COLUMN */
298
    if (knz == lmax) 
299
      goto L1400;
300
301
    /* OR IF TAIL OF K-1ST COLUMN MATCHES HEAD OF KTH */
302
    if (nzbeg > nzend) 
303
      goto L1200;
304
305
    i = rchlnk[k];
306
    for (jstrt = nzbeg; jstrt <= nzend; ++jstrt) {
307
      if (nzsub[jstrt] < i) 
308
        continue;
309
310
      if (nzsub[jstrt] == i) 
311
        goto L1000;
312
      else 
313
        goto L1200;
314
    }
315
    goto L1200;
316
317
L1000:
318
    xnzsub[k] = jstrt;
319
    for (j = jstrt; j <= nzend; ++j) {
320
      if (nzsub[j] != i) 
321
        goto L1200;
322
      
323
      i = rchlnk[i];
324
      if (i > neqns) 
325
        goto L1400;
326
    }
327
    nzend = jstrt - 1;
328
329
    /* COPY THE STRUCTURE OF L(*,K) FROM RCHLNK TO THE DATA STRUCTURE (XNZSUB, NZSUB) */
330
L1200:
331
    nzbeg = nzend + 1;
332
    nzend += knz;
333
334
    if (nzend > *maxsub) {
335
      flag = 1; /* Out of memory */
336
      break;
337
    }
338
339
    i = k;
340
    for (j=nzbeg; j<=nzend; ++j) {
341
      i = rchlnk[i];
342
      nzsub[j] = i;
343
      marker[i] = k;
344
    }
345
    xnzsub[k] = nzbeg;
346
    marker[k] = k;
347
348
    /*
349
     * UPDATE THE VECTOR MRGLNK.  NOTE COLUMN L(*,K) JUST FOUND   
350
     * IS REQUIRED TO DETERMINE COLUMN L(*,J), WHERE              
351
     * L(J,K) IS THE FIRST NONZERO IN L(*,K) BELOW DIAGONAL.      
352
     */
353
L1400:
354
    if (knz > 1) { 
355
      kxsub = xnzsub[k];
356
      i = nzsub[kxsub];
357
      mrglnk[k] = mrglnk[i];
358
      mrglnk[i] = k;
359
    }
360
361
    xlnz[k + 1] = xlnz[k] + knz;
362
  }
363
364
  if (flag == 0) {
365
    *maxlnz = xlnz[neqns] - 1;
366
    *maxsub = xnzsub[neqns];
367
    xnzsub[neqns + 1] = xnzsub[neqns];
368
  }
369
370
  marker++;
371
  mrglnk++;
372
  rchlnk++;
373
  nzsub++;
374
  xnzsub++;
375
  xlnz++;
376
  invp++;
377
  perm++;
378
  adjncy++;
379
  xadj++;
380
  gk_free((void **)&rchlnk, &mrglnk, &marker, LTERM);
381
382
  return flag;
383
  
384
} 
385
(-)metis-5.0pre2_orig/test/Makefile.am (+6 lines)
Line 0 Link Here
1
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/GKlib/trunk -DLINUX -DUNIX -D_FILE_OFFSET_BITS=64
2
AM_LDFLAGS = -L$(top_builddir) -lmetis
3
4
check_PROGRAMS = mtest
5
mtest_SOURCES = mtest.c
6

Return to bug 53394