Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
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 <[email protected]>
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
37namespace Eigen {
38namespace internal {
39
40enum { LUNoMarker = 3 };
41enum { emptyIdxLU = -1 };
42inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b) { return (std::max)(m, (t + b) * w); }
43
44template <typename Scalar>
45inline Index LUTempSpace(Index& m, Index& w) {
46 return (2 * w + 4 + LUNoMarker) * m * sizeof(Index) + (w + 1) * m * sizeof(Scalar);
47}
48
57template <typename Scalar, typename StorageIndex>
58template <typename VectorType>
59Index SparseLUImpl<Scalar, StorageIndex>::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev,
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
138template <typename Scalar, typename StorageIndex>
139Index SparseLUImpl<Scalar, StorageIndex>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio,
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
192template <typename Scalar, typename StorageIndex>
193template <typename VectorType>
194Index SparseLUImpl<Scalar, StorageIndex>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype,
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
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83