1 /* ========================================================================== */
2 /* === UMFPACK_report_symbolic ============================================== */
3 /* ========================================================================== */
4
5 /* -------------------------------------------------------------------------- */
6 /* Copyright (c) 2005-2012 by Timothy A. Davis, http://www.suitesparse.com. */
7 /* All Rights Reserved. See ../Doc/License.txt for License. */
8 /* -------------------------------------------------------------------------- */
9
10 /*
11 User-callable. Prints the Symbolic object. See umfpack_report_symbolic.h
12 for details. Not all of the object is printed.
13
14 Dynamic memory usage: Allocates a size MAX (n_row,n_col)*sizeof(Int)
15 workspace via a single call to UMF_malloc and then frees all of it via
16 UMF_free on return. The workspace is not allocated if an early error
17 return occurs before the workspace is needed.
18 */
19
20 #include "umf_internal.h"
21 #include "umf_valid_symbolic.h"
22 #include "umf_report_perm.h"
23 #include "umf_malloc.h"
24 #include "umf_free.h"
25
UMFPACK_report_symbolic(void * SymbolicHandle,const double Control[UMFPACK_CONTROL])26 GLOBAL Int UMFPACK_report_symbolic
27 (
28 void *SymbolicHandle,
29 const double Control [UMFPACK_CONTROL]
30 )
31 {
32 Int n_row, n_col, nz, nchains, nfr, maxnrows, maxncols, prl,
33 k, chain, frontid, frontid1, frontid2, kk, *Chain_start, *W,
34 *Chain_maxrows, *Chain_maxcols, *Front_npivcol, *Front_1strow,
35 *Front_leftmostdesc, *Front_parent, done, status1, status2 ;
36 SymbolicType *Symbolic ;
37
38 prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;
39
40 if (prl <= 2)
41 {
42 return (UMFPACK_OK) ;
43 }
44
45 PRINTF (("Symbolic object: ")) ;
46
47 Symbolic = (SymbolicType *) SymbolicHandle ;
48 if (!UMF_valid_symbolic (Symbolic))
49 {
50 PRINTF (("ERROR: invalid\n")) ;
51 return (UMFPACK_ERROR_invalid_Symbolic_object) ;
52 }
53
54 n_row = Symbolic->n_row ;
55 n_col = Symbolic->n_col ;
56
57 nz = Symbolic->nz ;
58
59 nchains = Symbolic->nchains ;
60 nfr = Symbolic->nfr ;
61 maxnrows = Symbolic->maxnrows ;
62 maxncols = Symbolic->maxncols ;
63
64 Chain_start = Symbolic->Chain_start ;
65 Chain_maxrows = Symbolic->Chain_maxrows ;
66 Chain_maxcols = Symbolic->Chain_maxcols ;
67 Front_npivcol = Symbolic->Front_npivcol ;
68 Front_1strow = Symbolic->Front_1strow ;
69 Front_leftmostdesc = Symbolic->Front_leftmostdesc ;
70 Front_parent = Symbolic->Front_parent ;
71
72 if (prl >= 4)
73 {
74
75 PRINTF (("\n matrix to be factorized:\n")) ;
76 PRINTF (("\tn_row: "ID" n_col: "ID"\n", n_row, n_col)) ;
77 PRINTF (("\tnumber of entries: "ID"\n", nz)) ;
78 PRINTF ((" block size used for dense matrix kernels: "ID"\n",
79 Symbolic->nb)) ;
80
81 PRINTF ((" strategy used: ")) ;
82 /* strategy cannot be auto */
83 if (Symbolic->strategy == UMFPACK_STRATEGY_SYMMETRIC)
84 {
85 PRINTF (("symmetric\n")) ;
86 PRINTF ((" ordering used: ")) ;
87 if (Symbolic->ordering == UMFPACK_ORDERING_AMD)
88 {
89 PRINTF (("amd on A\n")) ;
90 }
91 else if (Symbolic->ordering == UMFPACK_ORDERING_GIVEN)
92 {
93 PRINTF (("user permutation")) ;
94 }
95 else if (Symbolic->ordering == UMFPACK_ORDERING_USER)
96 {
97 PRINTF (("user function")) ;
98 }
99 else if (Symbolic->ordering == UMFPACK_ORDERING_METIS)
100 {
101 PRINTF (("metis on A")) ;
102 }
103 }
104 else /* if (Symbolic->strategy == UMFPACK_STRATEGY_UNSYMMETRIC) */
105 {
106 PRINTF (("unsymmetric\n")) ;
107 PRINTF ((" ordering used: ")) ;
108 if (Symbolic->ordering == UMFPACK_ORDERING_AMD)
109 {
110 PRINTF (("colamd on A\n")) ;
111 }
112 else if (Symbolic->ordering == UMFPACK_ORDERING_GIVEN)
113 {
114 PRINTF (("user permutation")) ;
115 }
116 else if (Symbolic->ordering == UMFPACK_ORDERING_USER)
117 {
118 PRINTF (("user function")) ;
119 }
120 else if (Symbolic->ordering == UMFPACK_ORDERING_METIS)
121 {
122 PRINTF (("metis on A'A")) ;
123 }
124 }
125 PRINTF (("\n")) ;
126
127 PRINTF ((" performn column etree postorder: ")) ;
128 if (Symbolic->fixQ)
129 {
130 PRINTF (("no\n")) ;
131 }
132 else
133 {
134 PRINTF (("yes\n")) ;
135 }
136
137 PRINTF ((" prefer diagonal pivoting (attempt P=Q): ")) ;
138 if (Symbolic->prefer_diagonal)
139 {
140 PRINTF (("yes\n")) ;
141 }
142 else
143 {
144 PRINTF (("no\n")) ;
145 }
146
147 PRINTF ((" variable-size part of Numeric object:\n")) ;
148 PRINTF (("\tminimum initial size (Units): %.20g (MBytes): %.1f\n",
149 Symbolic->dnum_mem_init_usage,
150 MBYTES (Symbolic->dnum_mem_init_usage))) ;
151 PRINTF (("\testimated peak size (Units): %.20g (MBytes): %.1f\n",
152 Symbolic->num_mem_usage_est,
153 MBYTES (Symbolic->num_mem_usage_est))) ;
154 PRINTF (("\testimated final size (Units): %.20g (MBytes): %.1f\n",
155 Symbolic->num_mem_size_est,
156 MBYTES (Symbolic->num_mem_size_est))) ;
157 PRINTF ((" symbolic factorization memory usage (Units):"
158 " %.20g (MBytes): %.1f\n",
159 Symbolic->peak_sym_usage,
160 MBYTES (Symbolic->peak_sym_usage))) ;
161 PRINTF ((" frontal matrices / supercolumns:\n")) ;
162 PRINTF (("\tnumber of frontal chains: "ID"\n", nchains)) ;
163 PRINTF (("\tnumber of frontal matrices: "ID"\n", nfr)) ;
164 PRINTF (("\tlargest frontal matrix row dimension: "ID"\n", maxnrows)) ;
165 PRINTF (("\tlargest frontal matrix column dimension: "ID"\n",maxncols));
166 }
167
168 k = 0 ;
169 done = FALSE ;
170
171 for (chain = 0 ; chain < nchains ; chain++)
172 {
173 frontid1 = Chain_start [chain] ;
174 frontid2 = Chain_start [chain+1] - 1 ;
175 PRINTF4 (("\n Frontal chain: "ID". Frontal matrices "ID" to "ID"\n",
176 INDEX (chain), INDEX (frontid1), INDEX (frontid2))) ;
177 PRINTF4 (("\tLargest frontal matrix in Frontal chain: "ID"-by-"ID"\n",
178 Chain_maxrows [chain], Chain_maxcols [chain])) ;
179 for (frontid = frontid1 ; frontid <= frontid2 ; frontid++)
180 {
181 kk = Front_npivcol [frontid] ;
182 PRINTF4 (("\tFront: "ID" pivot cols: "ID" (pivot columns "ID" to "
183 ID")\n", INDEX (frontid), kk, INDEX (k), INDEX (k+kk-1))) ;
184 PRINTF4 (("\t pivot row candidates: "ID" to "ID"\n",
185 INDEX (Front_1strow [Front_leftmostdesc [frontid]]),
186 INDEX (Front_1strow [frontid+1]-1))) ;
187 PRINTF4 (("\t leftmost descendant: "ID"\n",
188 INDEX (Front_leftmostdesc [frontid]))) ;
189 PRINTF4 (("\t 1st new candidate row : "ID"\n",
190 INDEX (Front_1strow [frontid]))) ;
191 PRINTF4 (("\t parent:")) ;
192 if (Front_parent [frontid] == EMPTY)
193 {
194 PRINTF4 ((" (none)\n")) ;
195 }
196 else
197 {
198 PRINTF4 ((" "ID"\n", INDEX (Front_parent [frontid]))) ;
199 }
200 done = (frontid == 20 && frontid < nfr-1 && prl == 4) ;
201 if (done)
202 {
203 PRINTF4 (("\t...\n")) ;
204 break ;
205 }
206 k += kk ;
207 }
208 if (Front_npivcol [nfr] != 0)
209 {
210 PRINTF4 (("\tFront: "ID" placeholder for "ID" empty columns\n",
211 INDEX (nfr), Front_npivcol [nfr])) ;
212 }
213 if (done)
214 {
215 break ;
216 }
217 }
218
219 W = (Int *) UMF_malloc (MAX (n_row, n_col), sizeof (Int)) ;
220 if (!W)
221 {
222 PRINTF (("ERROR: out of memory to check Symbolic object\n\n")) ;
223 return (UMFPACK_ERROR_out_of_memory) ;
224 }
225
226 PRINTF4 (("\nInitial column permutation, Q1: ")) ;
227 status1 = UMF_report_perm (n_col, Symbolic->Cperm_init, W, prl, 0) ;
228
229 PRINTF4 (("\nInitial row permutation, P1: ")) ;
230 status2 = UMF_report_perm (n_row, Symbolic->Rperm_init, W, prl, 0) ;
231
232 (void) UMF_free ((void *) W) ;
233
234 if (status1 != UMFPACK_OK || status2 != UMFPACK_OK)
235 {
236 return (UMFPACK_ERROR_invalid_Symbolic_object) ;
237 }
238
239 PRINTF4 ((" Symbolic object: ")) ;
240 PRINTF (("OK\n\n")) ;
241 return (UMFPACK_OK) ;
242 }
243