alpar@1
|
1 |
/* ========================================================================= */
|
alpar@1
|
2 |
/* === AMD_dump ============================================================ */
|
alpar@1
|
3 |
/* ========================================================================= */
|
alpar@1
|
4 |
|
alpar@1
|
5 |
/* ------------------------------------------------------------------------- */
|
alpar@1
|
6 |
/* AMD, Copyright (c) Timothy A. Davis, */
|
alpar@1
|
7 |
/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
|
alpar@1
|
8 |
/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */
|
alpar@1
|
9 |
/* web: http://www.cise.ufl.edu/research/sparse/amd */
|
alpar@1
|
10 |
/* ------------------------------------------------------------------------- */
|
alpar@1
|
11 |
|
alpar@1
|
12 |
/* Debugging routines for AMD. Not used if NDEBUG is not defined at compile-
|
alpar@1
|
13 |
* time (the default). See comments in amd_internal.h on how to enable
|
alpar@1
|
14 |
* debugging. Not user-callable.
|
alpar@1
|
15 |
*/
|
alpar@1
|
16 |
|
alpar@1
|
17 |
#include "amd_internal.h"
|
alpar@1
|
18 |
|
alpar@1
|
19 |
#ifndef NDEBUG
|
alpar@1
|
20 |
|
alpar@1
|
21 |
/* This global variable is present only when debugging */
|
alpar@1
|
22 |
GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */
|
alpar@1
|
23 |
|
alpar@1
|
24 |
/* ========================================================================= */
|
alpar@1
|
25 |
/* === AMD_debug_init ====================================================== */
|
alpar@1
|
26 |
/* ========================================================================= */
|
alpar@1
|
27 |
|
alpar@1
|
28 |
/* Sets the debug print level, by reading the file debug.amd (if it exists) */
|
alpar@1
|
29 |
|
alpar@1
|
30 |
GLOBAL void AMD_debug_init ( char *s )
|
alpar@1
|
31 |
{
|
alpar@1
|
32 |
FILE *f ;
|
alpar@1
|
33 |
f = fopen ("debug.amd", "r") ;
|
alpar@1
|
34 |
if (f == (FILE *) NULL)
|
alpar@1
|
35 |
{
|
alpar@1
|
36 |
AMD_debug = -999 ;
|
alpar@1
|
37 |
}
|
alpar@1
|
38 |
else
|
alpar@1
|
39 |
{
|
alpar@1
|
40 |
fscanf (f, ID, &AMD_debug) ;
|
alpar@1
|
41 |
fclose (f) ;
|
alpar@1
|
42 |
}
|
alpar@1
|
43 |
if (AMD_debug >= 0)
|
alpar@1
|
44 |
{
|
alpar@1
|
45 |
printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ;
|
alpar@1
|
46 |
}
|
alpar@1
|
47 |
}
|
alpar@1
|
48 |
|
alpar@1
|
49 |
/* ========================================================================= */
|
alpar@1
|
50 |
/* === AMD_dump ============================================================ */
|
alpar@1
|
51 |
/* ========================================================================= */
|
alpar@1
|
52 |
|
alpar@1
|
53 |
/* Dump AMD's data structure, except for the hash buckets. This routine
|
alpar@1
|
54 |
* cannot be called when the hash buckets are non-empty.
|
alpar@1
|
55 |
*/
|
alpar@1
|
56 |
|
alpar@1
|
57 |
GLOBAL void AMD_dump (
|
alpar@1
|
58 |
Int n, /* A is n-by-n */
|
alpar@1
|
59 |
Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */
|
alpar@1
|
60 |
Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1]
|
alpar@1
|
61 |
* holds the matrix on input */
|
alpar@1
|
62 |
Int Len [ ], /* len [0..n-1]: length for row i */
|
alpar@1
|
63 |
Int iwlen, /* length of iw */
|
alpar@1
|
64 |
Int pfree, /* iw [pfree ... iwlen-1] is empty on input */
|
alpar@1
|
65 |
Int Nv [ ], /* nv [0..n-1] */
|
alpar@1
|
66 |
Int Next [ ], /* next [0..n-1] */
|
alpar@1
|
67 |
Int Last [ ], /* last [0..n-1] */
|
alpar@1
|
68 |
Int Head [ ], /* head [0..n-1] */
|
alpar@1
|
69 |
Int Elen [ ], /* size n */
|
alpar@1
|
70 |
Int Degree [ ], /* size n */
|
alpar@1
|
71 |
Int W [ ], /* size n */
|
alpar@1
|
72 |
Int nel
|
alpar@1
|
73 |
)
|
alpar@1
|
74 |
{
|
alpar@1
|
75 |
Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ;
|
alpar@1
|
76 |
|
alpar@1
|
77 |
if (AMD_debug < 0) return ;
|
alpar@1
|
78 |
ASSERT (pfree <= iwlen) ;
|
alpar@1
|
79 |
AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ;
|
alpar@1
|
80 |
for (i = 0 ; i < n ; i++)
|
alpar@1
|
81 |
{
|
alpar@1
|
82 |
pe = Pe [i] ;
|
alpar@1
|
83 |
elen = Elen [i] ;
|
alpar@1
|
84 |
nv = Nv [i] ;
|
alpar@1
|
85 |
len = Len [i] ;
|
alpar@1
|
86 |
w = W [i] ;
|
alpar@1
|
87 |
|
alpar@1
|
88 |
if (elen >= EMPTY)
|
alpar@1
|
89 |
{
|
alpar@1
|
90 |
if (nv == 0)
|
alpar@1
|
91 |
{
|
alpar@1
|
92 |
AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ;
|
alpar@1
|
93 |
ASSERT (elen == EMPTY) ;
|
alpar@1
|
94 |
if (pe == EMPTY)
|
alpar@1
|
95 |
{
|
alpar@1
|
96 |
AMD_DEBUG3 ((" dense node\n")) ;
|
alpar@1
|
97 |
ASSERT (w == 1) ;
|
alpar@1
|
98 |
}
|
alpar@1
|
99 |
else
|
alpar@1
|
100 |
{
|
alpar@1
|
101 |
ASSERT (pe < EMPTY) ;
|
alpar@1
|
102 |
AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i])));
|
alpar@1
|
103 |
}
|
alpar@1
|
104 |
}
|
alpar@1
|
105 |
else
|
alpar@1
|
106 |
{
|
alpar@1
|
107 |
AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i));
|
alpar@1
|
108 |
AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ;
|
alpar@1
|
109 |
ASSERT (elen >= 0) ;
|
alpar@1
|
110 |
ASSERT (nv > 0 && pe >= 0) ;
|
alpar@1
|
111 |
p = pe ;
|
alpar@1
|
112 |
AMD_DEBUG3 ((" e/s: ")) ;
|
alpar@1
|
113 |
if (elen == 0) AMD_DEBUG3 ((" : ")) ;
|
alpar@1
|
114 |
ASSERT (pe + len <= pfree) ;
|
alpar@1
|
115 |
for (k = 0 ; k < len ; k++)
|
alpar@1
|
116 |
{
|
alpar@1
|
117 |
j = Iw [p] ;
|
alpar@1
|
118 |
AMD_DEBUG3 ((" "ID"", j)) ;
|
alpar@1
|
119 |
ASSERT (j >= 0 && j < n) ;
|
alpar@1
|
120 |
if (k == elen-1) AMD_DEBUG3 ((" : ")) ;
|
alpar@1
|
121 |
p++ ;
|
alpar@1
|
122 |
}
|
alpar@1
|
123 |
AMD_DEBUG3 (("\n")) ;
|
alpar@1
|
124 |
}
|
alpar@1
|
125 |
}
|
alpar@1
|
126 |
else
|
alpar@1
|
127 |
{
|
alpar@1
|
128 |
e = i ;
|
alpar@1
|
129 |
if (w == 0)
|
alpar@1
|
130 |
{
|
alpar@1
|
131 |
AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ;
|
alpar@1
|
132 |
ASSERT (nv > 0 && pe < 0) ;
|
alpar@1
|
133 |
AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ;
|
alpar@1
|
134 |
}
|
alpar@1
|
135 |
else
|
alpar@1
|
136 |
{
|
alpar@1
|
137 |
AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ;
|
alpar@1
|
138 |
ASSERT (nv > 0 && pe >= 0) ;
|
alpar@1
|
139 |
p = pe ;
|
alpar@1
|
140 |
AMD_DEBUG3 ((" : ")) ;
|
alpar@1
|
141 |
ASSERT (pe + len <= pfree) ;
|
alpar@1
|
142 |
for (k = 0 ; k < len ; k++)
|
alpar@1
|
143 |
{
|
alpar@1
|
144 |
j = Iw [p] ;
|
alpar@1
|
145 |
AMD_DEBUG3 ((" "ID"", j)) ;
|
alpar@1
|
146 |
ASSERT (j >= 0 && j < n) ;
|
alpar@1
|
147 |
p++ ;
|
alpar@1
|
148 |
}
|
alpar@1
|
149 |
AMD_DEBUG3 (("\n")) ;
|
alpar@1
|
150 |
}
|
alpar@1
|
151 |
}
|
alpar@1
|
152 |
}
|
alpar@1
|
153 |
|
alpar@1
|
154 |
/* this routine cannot be called when the hash buckets are non-empty */
|
alpar@1
|
155 |
AMD_DEBUG3 (("\nDegree lists:\n")) ;
|
alpar@1
|
156 |
if (nel >= 0)
|
alpar@1
|
157 |
{
|
alpar@1
|
158 |
cnt = 0 ;
|
alpar@1
|
159 |
for (deg = 0 ; deg < n ; deg++)
|
alpar@1
|
160 |
{
|
alpar@1
|
161 |
if (Head [deg] == EMPTY) continue ;
|
alpar@1
|
162 |
ilast = EMPTY ;
|
alpar@1
|
163 |
AMD_DEBUG3 ((ID": \n", deg)) ;
|
alpar@1
|
164 |
for (i = Head [deg] ; i != EMPTY ; i = Next [i])
|
alpar@1
|
165 |
{
|
alpar@1
|
166 |
AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n",
|
alpar@1
|
167 |
i, Next [i], Last [i], Degree [i])) ;
|
alpar@1
|
168 |
ASSERT (i >= 0 && i < n && ilast == Last [i] &&
|
alpar@1
|
169 |
deg == Degree [i]) ;
|
alpar@1
|
170 |
cnt += Nv [i] ;
|
alpar@1
|
171 |
ilast = i ;
|
alpar@1
|
172 |
}
|
alpar@1
|
173 |
AMD_DEBUG3 (("\n")) ;
|
alpar@1
|
174 |
}
|
alpar@1
|
175 |
ASSERT (cnt == n - nel) ;
|
alpar@1
|
176 |
}
|
alpar@1
|
177 |
|
alpar@1
|
178 |
}
|
alpar@1
|
179 |
|
alpar@1
|
180 |
#endif
|