1 /* ========================================================================== */
2 /* === UMF_set_stats ======================================================== */
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     Sets statistics in Info array.  Calculates everything in double precision,
12     rather than Int or size_t, so that usage estimates can be computed even if
13     the problem is so large that it would cause integer overflow.
14 
15     This routine has many double relop's, but the NaN case is ignored.
16 */
17 
18 #include "umf_internal.h"
19 #include "umf_set_stats.h"
20 #include "umf_symbolic_usage.h"
21 
UMF_set_stats(double Info[],SymbolicType * Symbolic,double max_usage,double num_mem_size,double flops,double lnz,double unz,double maxfrsize,double ulen,double npiv,double maxnrows,double maxncols,Int scale,Int prefer_diagonal,Int what)22 GLOBAL void UMF_set_stats
23 (
24     double Info [ ],
25     SymbolicType *Symbolic,
26     double max_usage,		/* peak size of Numeric->Memory, in Units */
27     double num_mem_size,	/* final size of Numeric->Memory, in Units */
28     double flops,		/* "true flops" */
29     double lnz,			/* nz in L */
30     double unz,			/* nz in U */
31     double maxfrsize,		/* largest front size */
32     double ulen,		/* size of Numeric->Upattern */
33     double npiv,		/* number of pivots found */
34     double maxnrows,		/* largest #rows in front */
35     double maxncols,		/* largest #cols in front */
36     Int scale,			/* true if scaling the rows of A */
37     Int prefer_diagonal,	/* true if diagonal pivoting (only square A) */
38     Int what			/* ESTIMATE or ACTUAL */
39 )
40 {
41 
42     double sym_size, work_usage, nn, n_row, n_col, n_inner, num_On_size1,
43 	num_On_size2, num_usage, sym_maxncols, sym_maxnrows, elen, n1 ;
44 
45     n_col = Symbolic->n_col ;
46     n_row = Symbolic->n_row ;
47     n1 = Symbolic->n1 ;
48     nn = MAX (n_row, n_col) ;
49     n_inner = MIN (n_row, n_col) ;
50     sym_maxncols = MIN (Symbolic->maxncols + Symbolic->nb, n_col) ;
51     sym_maxnrows = MIN (Symbolic->maxnrows + Symbolic->nb, n_row) ;
52     elen = (n_col - n1) + (n_row - n1) + MIN (n_col - n1, n_row - n1) + 1 ;
53 
54     /* final Symbolic object size */
55     sym_size = UMF_symbolic_usage (Symbolic->n_row, Symbolic->n_col,
56 	Symbolic->nchains, Symbolic->nfr, Symbolic->esize, prefer_diagonal) ;
57 
58     /* size of O(n) part of Numeric object during factorization, */
59     /* except Numeric->Memory and Numeric->Upattern */
60     num_On_size1 =
61 	DUNITS (NumericType, 1)		/* Numeric structure */
62 	+ DUNITS (Entry, n_inner+1)	/* D */
63 	+ 4 * DUNITS (Int, n_row+1)	/* Rperm, Lpos, Uilen, Uip */
64 	+ 4 * DUNITS (Int, n_col+1)	/* Cperm, Upos, Lilen, Lip */
65 	+ (scale ? DUNITS (Entry, n_row) : 0) ;   /* Rs, row scale factors */
66 
67     /* size of O(n) part of Numeric object after factorization, */
68     /* except Numeric->Memory and Numeric->Upattern */
69     num_On_size2 =
70 	DUNITS (NumericType, 1)		/* Numeric structure */
71 	+ DUNITS (Entry, n_inner+1)	/* D */
72 	+ DUNITS (Int, n_row+1)		/* Rperm */
73 	+ DUNITS (Int, n_col+1)		/* Cperm */
74 	+ 6 * DUNITS (Int, npiv+1)	/* Lpos, Uilen, Uip, Upos, Lilen, Lip */
75 	+ (scale ? DUNITS (Entry, n_row) : 0) ;	    /* Rs, row scale factors */
76 
77     DEBUG1 (("num O(n) size2: %g\n", num_On_size2)) ;
78 
79     /* peak size of Numeric->Memory, including LU factors, current frontal
80      * matrix, elements, and tuple lists.  */
81     Info [UMFPACK_VARIABLE_PEAK + what] = max_usage ;
82 
83     /* final size of Numeric->Memory (LU factors only) */
84     Info [UMFPACK_VARIABLE_FINAL + what] = num_mem_size ;
85 
86     /* final size of Numeric object, including Numeric->Memory and ->Upattern */
87     Info [UMFPACK_NUMERIC_SIZE + what] =
88 	num_On_size2
89 	+ num_mem_size		/* final Numeric->Memory size */
90 	+ DUNITS (Int, ulen+1) ;/* Numeric->Upattern (from Work->Upattern) */
91 
92     DEBUG1 (("num mem size: %g\n", num_mem_size)) ;
93     DEBUG1 (("ulen units %g\n", DUNITS (Int, ulen))) ;
94     DEBUG1 (("numeric size %g\n", Info [UMFPACK_NUMERIC_SIZE + what])) ;
95 
96     /* largest front size (working array size, or actual size used) */
97     Info [UMFPACK_MAX_FRONT_SIZE + what] = maxfrsize ;
98     Info [UMFPACK_MAX_FRONT_NROWS + what] = maxnrows ;
99     Info [UMFPACK_MAX_FRONT_NCOLS + what] = maxncols ;
100     DEBUGm4 (("maxnrows %g maxncols %g\n", maxnrows, maxncols)) ;
101     DEBUGm4 (("maxfrsize %g\n", maxfrsize)) ;
102 
103     /* UMF_kernel usage, from work_alloc routine in umf_kernel.c */
104     work_usage =
105 	/* Work-> arrays, except for current frontal matrix which is allocated
106 	 * inside Numeric->Memory. */
107 	2 * DUNITS (Entry, sym_maxnrows + 1)	/* Wx, Wy */
108 	+ 2 * DUNITS (Int, n_row+1)		/* Frpos, Lpattern */
109 	+ 2 * DUNITS (Int, n_col+1)		/* Fcpos, Upattern */
110 	+ DUNITS (Int, nn + 1)			/* Wp */
111 	+ DUNITS (Int, MAX (n_col, sym_maxnrows) + 1)	/* Wrp */
112 	+ 2 * DUNITS (Int, sym_maxnrows + 1)	/* Frows, Wm */
113 	+ 3 * DUNITS (Int, sym_maxncols + 1)	/* Fcols, Wio, Woi */
114 	+ DUNITS (Int, MAX (sym_maxnrows, sym_maxncols) + 1)	/* Woo */
115 	+ DUNITS (Int, elen)			/* E */
116 	+ DUNITS (Int, Symbolic->nfr + 1)	/* Front_new1strow */
117 	+ ((n_row == n_col) ? (2 * DUNITS (Int, nn)) : 0) ;  /* Diag map,imap */
118 
119     /* Peak memory for just UMFPACK_numeric. */
120     num_usage =
121 	sym_size	/* size of Symbolic object */
122 	+ num_On_size1	/* O(n) part of Numeric object (excl. Upattern) */
123 	+ work_usage	/* Work-> arrays (including Upattern) */
124 	+ max_usage ;	/* peak size of Numeric->Memory */
125 
126     /* peak memory usage for both UMFPACK_*symbolic and UMFPACK_numeric. */
127     Info [UMFPACK_PEAK_MEMORY + what] =
128 	MAX (Symbolic->peak_sym_usage, num_usage) ;
129 
130     Info [UMFPACK_FLOPS + what] = flops ;
131     Info [UMFPACK_LNZ + what] = lnz ;
132     Info [UMFPACK_UNZ + what] = unz ;
133 }
134