umf_tuple_lengths.c
4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* ========================================================================== */
/* === UMF_tuple_lengths ==================================================== */
/* ========================================================================== */
/* -------------------------------------------------------------------------- */
/* UMFPACK Copyright (c) Timothy A. Davis, CISE, */
/* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. */
/* web: http://www.cise.ufl.edu/research/sparse/umfpack */
/* -------------------------------------------------------------------------- */
/* Determine the tuple list lengths, and the amount of memory required for */
/* them. Return the amount of memory needed to store all the tuples. */
/* This routine assumes that the tuple lists themselves are either already */
/* deallocated, or will be shortly (so Row[ ].tlen and Col[ ].tlen are */
/* overwritten) */
#include "umf_internal.h"
GLOBAL Int UMF_tuple_lengths /* return memory usage */
(
NumericType *Numeric,
WorkType *Work,
double *p_dusage /* output argument */
)
{
/* ---------------------------------------------------------------------- */
/* local variables */
/* ---------------------------------------------------------------------- */
double dusage ;
Int e, nrows, ncols, nel, i, *Rows, *Cols, row, col, n_row, n_col, *E,
*Row_degree, *Row_tlen, *Col_degree, *Col_tlen, usage, n1 ;
Element *ep ;
Unit *p ;
/* ---------------------------------------------------------------------- */
/* get parameters */
/* ---------------------------------------------------------------------- */
E = Work->E ;
Row_degree = Numeric->Rperm ; /* for NON_PIVOTAL_ROW macro only */
Col_degree = Numeric->Cperm ; /* for NON_PIVOTAL_COL macro only */
Row_tlen = Numeric->Uilen ;
Col_tlen = Numeric->Lilen ;
n_row = Work->n_row ;
n_col = Work->n_col ;
n1 = Work->n1 ;
nel = Work->nel ;
DEBUG3 (("TUPLE_LENGTHS: n_row "ID" n_col "ID" nel "ID"\n",
n_row, n_col, nel)) ;
ASSERT (nel < Work->elen) ;
/* tuple list lengths already initialized to zero */
/* ---------------------------------------------------------------------- */
/* scan each element: count tuple list lengths (include element 0) */
/* ---------------------------------------------------------------------- */
for (e = 1 ; e <= nel ; e++) /* for all elements, in any order */
{
if (E [e])
{
#ifndef NDEBUG
UMF_dump_element (Numeric, Work, e, FALSE) ;
#endif
p = Numeric->Memory + E [e] ;
GET_ELEMENT_PATTERN (ep, p, Cols, Rows, ncols) ;
nrows = ep->nrows ;
for (i = 0 ; i < nrows ; i++)
{
row = Rows [i] ;
ASSERT (row == EMPTY || (row >= n1 && row < n_row)) ;
if (row >= n1)
{
ASSERT (NON_PIVOTAL_ROW (row)) ;
Row_tlen [row] ++ ;
}
}
for (i = 0 ; i < ncols ; i++)
{
col = Cols [i] ;
ASSERT (col == EMPTY || (col >= n1 && col < n_col)) ;
if (col >= n1)
{
ASSERT (NON_PIVOTAL_COL (col)) ;
Col_tlen [col] ++ ;
}
}
}
}
/* note: tuple lengths are now modified, but the tuple lists are not */
/* updated to reflect that fact. */
/* ---------------------------------------------------------------------- */
/* determine the required memory to hold all the tuple lists */
/* ---------------------------------------------------------------------- */
DEBUG0 (("UMF_build_tuples_usage\n")) ;
usage = 0 ;
dusage = 0 ;
ASSERT (Col_tlen && Col_degree) ;
for (col = n1 ; col < n_col ; col++)
{
if (NON_PIVOTAL_COL (col))
{
usage += 1 + UNITS (Tuple, TUPLES (Col_tlen [col])) ;
dusage += 1 + DUNITS (Tuple, TUPLES (Col_tlen [col])) ;
DEBUG0 ((" col: "ID" tlen "ID" usage so far: "ID"\n",
col, Col_tlen [col], usage)) ;
}
}
ASSERT (Row_tlen && Row_degree) ;
for (row = n1 ; row < n_row ; row++)
{
if (NON_PIVOTAL_ROW (row))
{
usage += 1 + UNITS (Tuple, TUPLES (Row_tlen [row])) ;
dusage += 1 + DUNITS (Tuple, TUPLES (Row_tlen [row])) ;
DEBUG0 ((" row: "ID" tlen "ID" usage so far: "ID"\n",
row, Row_tlen [row], usage)) ;
}
}
DEBUG0 (("UMF_build_tuples_usage "ID" %g\n", usage, dusage)) ;
*p_dusage = dusage ;
return (usage) ;
}