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