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