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 // IWYU pragma: private
35 #include "./InternalHeaderCheck.h"
36 
37 namespace Eigen {
38 namespace internal {
39 
40 enum { LUNoMarker = 3 };
41 enum { emptyIdxLU = -1 };
42 inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b) { return (std::max)(m, (t + b) * w); }
43 
44 template <typename Scalar>
46  return (2 * w + 4 + LUNoMarker) * m * sizeof(Index) + (w + 1) * m * sizeof(Scalar);
47 }
48 
57 template <typename Scalar, typename StorageIndex>
58 template <typename VectorType>
60  Index& num_expansions) {
61  float alpha = 1.5; // Ratio of the memory increase
62  Index new_len; // New size of the allocated memory
63 
64  if (num_expansions == 0 || keep_prev)
65  new_len = length; // First time allocate requested
66  else
67  new_len = (std::max)(length + 1, Index(alpha * length));
68 
69  VectorType old_vec; // Temporary vector to hold the previous values
70  if (nbElts > 0) old_vec = vec.segment(0, nbElts);
71 
72  // Allocate or expand the current vector
73 #ifdef EIGEN_EXCEPTIONS
74  try
75 #endif
76  {
77  vec.resize(new_len);
78  }
79 #ifdef EIGEN_EXCEPTIONS
80  catch (std::bad_alloc&)
81 #else
82  if (!vec.size())
83 #endif
84  {
85  if (!num_expansions) {
86  // First time to allocate from LUMemInit()
87  // Let LUMemInit() deals with it.
88  return -1;
89  }
90  if (keep_prev) {
91  // In this case, the memory length should not not be reduced
92  return new_len;
93  } else {
94  // Reduce the size and increase again
95  Index tries = 0; // Number of attempts
96  do {
97  alpha = (alpha + 1) / 2;
98  new_len = (std::max)(length + 1, Index(alpha * length));
99 #ifdef EIGEN_EXCEPTIONS
100  try
101 #endif
102  {
103  vec.resize(new_len);
104  }
105 #ifdef EIGEN_EXCEPTIONS
106  catch (std::bad_alloc&)
107 #else
108  if (!vec.size())
109 #endif
110  {
111  tries += 1;
112  if (tries > 10) return new_len;
113  }
114  } while (!vec.size());
115  }
116  }
117  // Copy the previous values to the newly allocated space
118  if (nbElts > 0) vec.segment(0, nbElts) = old_vec;
119 
120  length = new_len;
121  if (num_expansions) ++num_expansions;
122  return 0;
123 }
124 
138 template <typename Scalar, typename StorageIndex>
140  Index panel_size, GlobalLU_t& glu) {
141  Index& num_expansions = glu.num_expansions; // No memory expansions so far
142  num_expansions = 0;
143  glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz + 1) / n, m) * n; // estimated number of nonzeros in U
144  glu.nzlmax = (std::max)(Index(4), fillratio) * (annz + 1) / 4; // estimated nnz in L factor
145  // Return the estimated size to the user if necessary
146  Index tempSpace;
147  tempSpace = (2 * panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
148  if (lwork == emptyIdxLU) {
149  Index estimated_size;
150  estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace + (glu.nzlmax + glu.nzumax) * sizeof(Index) +
151  (glu.nzlumax + glu.nzumax) * sizeof(Scalar) + n;
152  return estimated_size;
153  }
154 
155  // Setup the required space
156 
157  // First allocate Integer pointers for L\U factors
158  glu.xsup.resize(n + 1);
159  glu.supno.resize(n + 1);
160  glu.xlsub.resize(n + 1);
161  glu.xlusup.resize(n + 1);
162  glu.xusub.resize(n + 1);
163 
164  // Reserve memory for L/U factors
165  do {
166  if ((expand<ScalarVector>(glu.lusup, glu.nzlumax, 0, 0, num_expansions) < 0) ||
167  (expand<ScalarVector>(glu.ucol, glu.nzumax, 0, 0, num_expansions) < 0) ||
168  (expand<IndexVector>(glu.lsub, glu.nzlmax, 0, 0, num_expansions) < 0) ||
169  (expand<IndexVector>(glu.usub, glu.nzumax, 0, 1, num_expansions) < 0)) {
170  // Reduce the estimated size and retry
171  glu.nzlumax /= 2;
172  glu.nzumax /= 2;
173  glu.nzlmax /= 2;
174  if (glu.nzlumax < annz) return glu.nzlumax;
175  }
176  } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size());
177 
178  ++num_expansions;
179  return 0;
180 
181 } // end LuMemInit
182 
192 template <typename Scalar, typename StorageIndex>
193 template <typename VectorType>
195  Index& num_expansions) {
196  Index failed_size;
197  if (memtype == USUB)
198  failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
199  else
200  failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 0, num_expansions);
201 
202  if (failed_size) return failed_size;
203 
204  return 0;
205 }
206 
207 } // end namespace internal
208 
209 } // end namespace Eigen
210 #endif // EIGEN_SPARSELU_MEMORY
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
RowVector3d w
Definition: Matrix_resize_int.cpp:3
Scalar * b
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
Index memXpand(VectorType &vec, Index &maxlen, Index nbElts, MemType memtype, Index &num_expansions)
Expand the existing storage.
Definition: SparseLU_Memory.h:194
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.
Definition: SparseLU_Memory.h:139
Index expand(VectorType &vec, Index &length, Index nbElts, Index keep_prev, Index &num_expansions)
Definition: SparseLU_Memory.h:59
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
RealScalar alpha
Definition: level1_cplx_impl.h:151
int * m
Definition: level2_cplx_impl.h:294
Index LUnumTempV(Index &m, Index &w, Index &t, Index &b)
Definition: SparseLU_Memory.h:42
Index LUTempSpace(Index &m, Index &w)
Definition: SparseLU_Memory.h:45
MemType
Definition: SparseLU_Structs.h:77
@ USUB
Definition: SparseLU_Structs.h:77
@ LUNoMarker
Definition: SparseLU_Memory.h:40
@ emptyIdxLU
Definition: SparseLU_Memory.h:41
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
Definition: Eigen_Colamd.h:49
t
Definition: plotPSD.py:36
Definition: SparseLU_Structs.h:80
IndexVector usub
Definition: SparseLU_Structs.h:91
Index nzlmax
Definition: SparseLU_Structs.h:88
IndexVector xsup
Definition: SparseLU_Structs.h:82
Index nzumax
Definition: SparseLU_Structs.h:93
Index num_expansions
Definition: SparseLU_Structs.h:95
IndexVector xlusup
Definition: SparseLU_Structs.h:86
IndexVector supno
Definition: SparseLU_Structs.h:83
IndexVector lsub
Definition: SparseLU_Structs.h:85
IndexVector xusub
Definition: SparseLU_Structs.h:92
Index nzlumax
Definition: SparseLU_Structs.h:89
IndexVector xlsub
Definition: SparseLU_Structs.h:87
ScalarVector lusup
Definition: SparseLU_Structs.h:84
ScalarVector ucol
Definition: SparseLU_Structs.h:90
Definition: fft_test_shared.h:66