Eigen  5.0.1
 
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// SPDX-License-Identifier: MPL-2.0
10
11/*
12
13 * NOTE: This file is the modified version of [s,d,c,z]memory.c files in SuperLU
14
15 * -- SuperLU routine (version 3.1) --
16 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
17 * and Lawrence Berkeley National Lab.
18 * August 1, 2008
19 *
20 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
21 *
22 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
23 * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
24 *
25 * Permission is hereby granted to use or copy this program for any
26 * purpose, provided the above notices are retained on all copies.
27 * Permission to modify the code and to distribute modified code is
28 * granted, provided the above notices are retained, and a notice that
29 * the code was modified is included with the above copyright notice.
30 */
31
32#ifndef EIGEN_SPARSELU_MEMORY
33#define EIGEN_SPARSELU_MEMORY
34
35// IWYU pragma: private
36#include "./InternalHeaderCheck.h"
37
38namespace Eigen {
39namespace internal {
40
41enum { LUNoMarker = 3 };
42enum { emptyIdxLU = -1 };
43inline Index LUnumTempV(Index& m, Index& w, Index& t, Index& b) { return (std::max)(m, (t + b) * w); }
44
53template <typename Scalar, typename StorageIndex>
54template <typename VectorType>
55Index SparseLUImpl<Scalar, StorageIndex>::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev,
56 Index& num_expansions) {
57 float alpha = 1.5; // Ratio of the memory increase
58 Index new_len; // New size of the allocated memory
59
60 if (num_expansions == 0 || keep_prev)
61 new_len = length; // First time allocate requested
62 else
63 new_len = (std::max)(length + 1, Index(alpha * length));
64
65 VectorType old_vec; // Temporary vector to hold the previous values
66 if (nbElts > 0) old_vec = vec.segment(0, nbElts);
67
68 // Allocate or expand the current vector
69#ifdef EIGEN_EXCEPTIONS
70 try
71#endif
72 {
73 vec.resize(new_len);
74 }
75#ifdef EIGEN_EXCEPTIONS
76 catch (std::bad_alloc&)
77#else
78 if (!vec.size())
79#endif
80 {
81 if (!num_expansions) {
82 // First time to allocate from LUMemInit()
83 // Let LUMemInit() deals with it.
84 return -1;
85 }
86 if (keep_prev) {
87 // In this case, the memory length should not be reduced
88 return new_len;
89 } else {
90 // Reduce the size and increase again
91 Index tries = 0; // Number of attempts
92 do {
93 alpha = (alpha + 1) / 2;
94 new_len = (std::max)(length + 1, Index(alpha * length));
95#ifdef EIGEN_EXCEPTIONS
96 try
97#endif
98 {
99 vec.resize(new_len);
100 }
101#ifdef EIGEN_EXCEPTIONS
102 catch (std::bad_alloc&)
103#else
104 if (!vec.size())
105#endif
106 {
107 tries += 1;
108 if (tries > 10) return new_len;
109 }
110 } while (!vec.size());
111 }
112 }
113 // Copy the previous values to the newly allocated space
114 if (nbElts > 0) vec.segment(0, nbElts) = old_vec;
115
116 length = new_len;
117 if (num_expansions) ++num_expansions;
118 return 0;
119}
120
134template <typename Scalar, typename StorageIndex>
135Index SparseLUImpl<Scalar, StorageIndex>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio,
136 Index panel_size, GlobalLU_t& glu) {
137 Index& num_expansions = glu.num_expansions; // No memory expansions so far
138 num_expansions = 0;
139 glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz + 1) / n, m) * n; // estimated number of nonzeros in U
140 glu.nzlmax = (std::max)(Index(4), fillratio) * (annz + 1) / 4; // estimated nnz in L factor
141 // Return the estimated size to the user if necessary
142 Index tempSpace;
143 tempSpace = (2 * panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
144 if (lwork == emptyIdxLU) {
145 Index estimated_size;
146 estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace + (glu.nzlmax + glu.nzumax) * sizeof(Index) +
147 (glu.nzlumax + glu.nzumax) * sizeof(Scalar) + n;
148 return estimated_size;
149 }
150
151 // Setup the required space
152
153 // First allocate Integer pointers for L\U factors
154 glu.xsup.resize(n + 1);
155 glu.supno.resize(n + 1);
156 glu.xlsub.resize(n + 1);
157 glu.xlusup.resize(n + 1);
158 glu.xusub.resize(n + 1);
159
160 // Reserve memory for L/U factors
161 do {
162 if ((expand<ScalarVector>(glu.lusup, glu.nzlumax, 0, 0, num_expansions) < 0) ||
163 (expand<ScalarVector>(glu.ucol, glu.nzumax, 0, 0, num_expansions) < 0) ||
164 (expand<IndexVector>(glu.lsub, glu.nzlmax, 0, 0, num_expansions) < 0) ||
165 (expand<IndexVector>(glu.usub, glu.nzumax, 0, 1, num_expansions) < 0)) {
166 // Reduce the estimated size and retry
167 glu.nzlumax /= 2;
168 glu.nzumax /= 2;
169 glu.nzlmax /= 2;
170 if (glu.nzlumax < annz) return glu.nzlumax;
171 }
172 } while (!glu.lusup.size() || !glu.ucol.size() || !glu.lsub.size() || !glu.usub.size());
173
174 ++num_expansions;
175 return 0;
176
177} // end LuMemInit
178
188template <typename Scalar, typename StorageIndex>
189template <typename VectorType>
190Index SparseLUImpl<Scalar, StorageIndex>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype,
191 Index& num_expansions) {
192 Index failed_size;
193 if (memtype == USUB)
194 failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
195 else
196 failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 0, num_expansions);
197
198 if (failed_size) return failed_size;
199
200 return 0;
201}
202
203} // end namespace internal
204
205} // end namespace Eigen
206#endif // EIGEN_SPARSELU_MEMORY
Index expand(VectorType &vec, Index &length, Index nbElts, Index keep_prev, Index &num_expansions)
Definition SparseLU_Memory.h:55
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:135
Index memXpand(VectorType &vec, Index &maxlen, Index nbElts, MemType memtype, Index &num_expansions)
Expand the existing storage.
Definition SparseLU_Memory.h:190