Eigen  3.2.10
 
Loading...
Searching...
No Matches
SparseLU_Memory.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10/*
11
12 * NOTE: This file is the modified version of [s,d,c,z]memory.c files in SuperLU
13
14 * -- SuperLU routine (version 3.1) --
15 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
16 * and Lawrence Berkeley National Lab.
17 * August 1, 2008
18 *
19 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
20 *
21 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
22 * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
23 *
24 * Permission is hereby granted to use or copy this program for any
25 * purpose, provided the above notices are retained on all copies.
26 * Permission to modify the code and to distribute modified code is
27 * granted, provided the above notices are retained, and a notice that
28 * the code was modified is included with the above copyright notice.
29 */
30
31#ifndef EIGEN_SPARSELU_MEMORY
32#define EIGEN_SPARSELU_MEMORY
33
34namespace Eigen {
35namespace internal {
36
37enum { LUNoMarker = 3 };
38enum {emptyIdxLU = -1};
39template<typename Index>
40inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b)
41{
42 return (std::max)(m, (t+b)*w);
43}
44
45template< typename Scalar, typename Index>
46inline Index LUTempSpace(Index&m, Index& w)
47{
48 return (2*w + 4 + LUNoMarker) * m * sizeof(Index) + (w + 1) * m * sizeof(Scalar);
49}
50
51
52
53
62template <typename Scalar, typename Index>
63template <typename VectorType>
64Index SparseLUImpl<Scalar,Index>::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions)
65{
66
67 float alpha = 1.5; // Ratio of the memory increase
68 Index new_len; // New size of the allocated memory
69
70 if(num_expansions == 0 || keep_prev)
71 new_len = length ; // First time allocate requested
72 else
73 new_len = (std::max)(length+1,Index(alpha * length));
74
75 VectorType old_vec; // Temporary vector to hold the previous values
76 if (nbElts > 0 )
77 old_vec = vec.segment(0,nbElts);
78
79 //Allocate or expand the current vector
80#ifdef EIGEN_EXCEPTIONS
81 try
82#endif
83 {
84 vec.resize(new_len);
85 }
86#ifdef EIGEN_EXCEPTIONS
87 catch(std::bad_alloc& )
88#else
89 if(!vec.size())
90#endif
91 {
92 if (!num_expansions)
93 {
94 // First time to allocate from LUMemInit()
95 // Let LUMemInit() deals with it.
96 return -1;
97 }
98 if (keep_prev)
99 {
100 // In this case, the memory length should not not be reduced
101 return new_len;
102 }
103 else
104 {
105 // Reduce the size and increase again
106 Index tries = 0; // Number of attempts
107 do
108 {
109 alpha = (alpha + 1)/2;
110 new_len = (std::max)(length+1,Index(alpha * length));
111#ifdef EIGEN_EXCEPTIONS
112 try
113#endif
114 {
115 vec.resize(new_len);
116 }
117#ifdef EIGEN_EXCEPTIONS
118 catch(std::bad_alloc& )
119#else
120 if (!vec.size())
121#endif
122 {
123 tries += 1;
124 if ( tries > 10) return new_len;
125 }
126 } while (!vec.size());
127 }
128 }
129 //Copy the previous values to the newly allocated space
130 if (nbElts > 0)
131 vec.segment(0, nbElts) = old_vec;
132
133
134 length = new_len;
135 if(num_expansions) ++num_expansions;
136 return 0;
137}
138
151template <typename Scalar, typename Index>
152Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu)
153{
154 Index& num_expansions = glu.num_expansions; //No memory expansions so far
155 num_expansions = 0;
156 glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz+1) / n, m) * n; // estimated number of nonzeros in U
157 glu.nzlmax = (std::max)(Index(4), fillratio) * (annz+1) / 4; // estimated nnz in L factor
158 // Return the estimated size to the user if necessary
159 Index tempSpace;
160 tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
161 if (lwork == emptyIdxLU)
162 {
163 Index estimated_size;
164 estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace
165 + (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n;
166 return estimated_size;
167 }
168
169 // Setup the required space
170
171 // First allocate Integer pointers for L\U factors
172 glu.xsup.resize(n+1);
173 glu.supno.resize(n+1);
174 glu.xlsub.resize(n+1);
175 glu.xlusup.resize(n+1);
176 glu.xusub.resize(n+1);
177
178 // Reserve memory for L/U factors
179 do
180 {
181 if( (expand<ScalarVector>(glu.lusup, glu.nzlumax, 0, 0, num_expansions)<0)
182 || (expand<ScalarVector>(glu.ucol, glu.nzumax, 0, 0, num_expansions)<0)
183 || (expand<IndexVector> (glu.lsub, glu.nzlmax, 0, 0, num_expansions)<0)
184 || (expand<IndexVector> (glu.usub, glu.nzumax, 0, 1, num_expansions)<0) )
185 {
186 //Reduce the estimated size and retry
187 glu.nzlumax /= 2;
188 glu.nzumax /= 2;
189 glu.nzlmax /= 2;
190 if (glu.nzlumax < annz ) return glu.nzlumax;
191 }
192 } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size());
193
194 ++num_expansions;
195 return 0;
196
197} // end LuMemInit
198
208template <typename Scalar, typename Index>
209template <typename VectorType>
210Index SparseLUImpl<Scalar,Index>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions)
211{
212 Index failed_size;
213 if (memtype == USUB)
214 failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
215 else
216 failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 0, num_expansions);
217
218 if (failed_size)
219 return failed_size;
220
221 return 0 ;
222}
223
224} // end namespace internal
225
226} // end namespace Eigen
227#endif // EIGEN_SPARSELU_MEMORY
Definition LDLT.h:18