SparseLU_Memory.h
Go to the documentation of this file.
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 
34 namespace Eigen {
35 namespace internal {
36 
37 enum { LUNoMarker = 3 };
38 enum {emptyIdxLU = -1};
39 template<typename Index>
40 inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b)
41 {
42  return (std::max)(m, (t+b)*w);
43 }
44 
45 template< typename Scalar, typename Index>
46 inline 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 
62 template <typename Scalar, typename Index>
63 template <typename VectorType>
64 Index 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 = 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  try
81  {
82  vec.resize(new_len);
83  }
84  catch(std::bad_alloc& )
85  {
86  if ( !num_expansions )
87  {
88  // First time to allocate from LUMemInit()
89  throw; // Pass the exception to LUMemInit() which has a try... catch block
90  }
91  if (keep_prev)
92  {
93  // In this case, the memory length should not not be reduced
94  return new_len;
95  }
96  else
97  {
98  // Reduce the size and increase again
99  Index tries = 0; // Number of attempts
100  do
101  {
102  alpha = (alpha + 1)/2;
103  new_len = Index(alpha * length);
104  try
105  {
106  vec.resize(new_len);
107  }
108  catch(std::bad_alloc& )
109  {
110  tries += 1;
111  if ( tries > 10) return new_len;
112  }
113  } while (!vec.size());
114  }
115  }
116  //Copy the previous values to the newly allocated space
117  if (nbElts > 0)
118  vec.segment(0, nbElts) = old_vec;
119 
120 
121  length = new_len;
122  if(num_expansions) ++num_expansions;
123  return 0;
124 }
125 
138 template <typename Scalar, typename Index>
139 Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu)
140 {
141  Index& num_expansions = glu.num_expansions; //No memory expansions so far
142  num_expansions = 0;
143  glu.nzumax = glu.nzlumax = (std::max)(fillratio * annz, m*n); // estimated number of nonzeros in U
144  glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor
145 
146  // Return the estimated size to the user if necessary
147  Index tempSpace;
148  tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
149  if (lwork == emptyIdxLU)
150  {
151  Index estimated_size;
152  estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace
153  + (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n;
154  return estimated_size;
155  }
156 
157  // Setup the required space
158 
159  // First allocate Integer pointers for L\U factors
160  glu.xsup.resize(n+1);
161  glu.supno.resize(n+1);
162  glu.xlsub.resize(n+1);
163  glu.xlusup.resize(n+1);
164  glu.xusub.resize(n+1);
165 
166  // Reserve memory for L/U factors
167  do
168  {
169  try
170  {
171  expand<ScalarVector>(glu.lusup, glu.nzlumax, 0, 0, num_expansions);
172  expand<ScalarVector>(glu.ucol,glu.nzumax, 0, 0, num_expansions);
173  expand<IndexVector>(glu.lsub,glu.nzlmax, 0, 0, num_expansions);
174  expand<IndexVector>(glu.usub,glu.nzumax, 0, 1, num_expansions);
175  }
176  catch(std::bad_alloc& )
177  {
178  //Reduce the estimated size and retry
179  glu.nzlumax /= 2;
180  glu.nzumax /= 2;
181  glu.nzlmax /= 2;
182  if (glu.nzlumax < annz ) return glu.nzlumax;
183  }
184 
185  } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size());
186 
187 
188 
189  ++num_expansions;
190  return 0;
191 
192 } // end LuMemInit
193 
203 template <typename Scalar, typename Index>
204 template <typename VectorType>
205 Index SparseLUImpl<Scalar,Index>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions)
206 {
207  Index failed_size;
208  if (memtype == USUB)
209  failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
210  else
211  failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 0, num_expansions);
212 
213  if (failed_size)
214  return failed_size;
215 
216  return 0 ;
217 }
218 
219 } // end namespace internal
220 
221 } // end namespace Eigen
222 #endif // EIGEN_SPARSELU_MEMORY
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: matrix.hpp:471
Index LUTempSpace(Index &m, Index &w)
Index memXpand(VectorType &vec, Index &maxlen, Index nbElts, MemType memtype, Index &num_expansions)
Expand the existing storage.
Index LUnumTempV(Index &m, Index &w, Index &t, Index &b)
Index expand(VectorType &vec, Index &length, Index nbElts, Index keep_prev, Index &num_expansions)
Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t &glu)
Allocate various working space for the numerical factorization phase.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:35:08