mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-14 04:35:57 +08:00
Memory management
This commit is contained in:
parent
268ba3b521
commit
f091879d77
@ -48,7 +48,8 @@ class SparseLU
|
|||||||
typedef SparseMatrix<Scalar,ColMajor,Index> NCMatrix;
|
typedef SparseMatrix<Scalar,ColMajor,Index> NCMatrix;
|
||||||
typedef SuperNodalMatrix<Scalar, Index> SCMatrix;
|
typedef SuperNodalMatrix<Scalar, Index> SCMatrix;
|
||||||
typedef GlobalLU_t<Scalar, Index> Eigen_GlobalLU_t;
|
typedef GlobalLU_t<Scalar, Index> Eigen_GlobalLU_t;
|
||||||
typedef Matrix<Scalar,Dynamic,1> VectorType;
|
typedef Matrix<Scalar,Dynamic,1> ScalarVector;
|
||||||
|
typedef Matrix<Index,Dynamic,1> IndexVector;
|
||||||
typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
|
typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
|
||||||
public:
|
public:
|
||||||
SparseLU():m_isInitialized(true),m_symmetricmode(false),m_fact(DOFACT),m_diagpivotthresh(1.0)
|
SparseLU():m_isInitialized(true),m_symmetricmode(false),m_fact(DOFACT),m_diagpivotthresh(1.0)
|
||||||
@ -93,15 +94,15 @@ class SparseLU
|
|||||||
fact_t m_fact;
|
fact_t m_fact;
|
||||||
NCMatrix m_mat; // The input (permuted ) matrix
|
NCMatrix m_mat; // The input (permuted ) matrix
|
||||||
SCMatrix m_Lstore; // The lower triangular matrix (supernodal)
|
SCMatrix m_Lstore; // The lower triangular matrix (supernodal)
|
||||||
NCMatrix m_Ustore; //The upper triangular matrix
|
NCMatrix m_Ustore; // The upper triangular matrix
|
||||||
PermutationType m_perm_c; // Column permutation
|
PermutationType m_perm_c; // Column permutation
|
||||||
PermutationType m_iperm_c; // Column permutation
|
PermutationType m_iperm_c; // Column permutation
|
||||||
PermutationType m_perm_r ; // Row permutation
|
PermutationType m_perm_r ; // Row permutation
|
||||||
PermutationType m_iperm_r ; // Inverse row permutation
|
PermutationType m_iperm_r ; // Inverse row permutation
|
||||||
VectorXi m_etree; // Column elimination tree
|
IndexVector m_etree; // Column elimination tree
|
||||||
|
|
||||||
Scalar *m_work; //
|
ScalarVector m_work; //
|
||||||
Index *m_iwork; //
|
IndexVector m_iwork; //
|
||||||
static Eigen_GlobalLU_t m_Glu; // persistent data to facilitate multiple factors
|
static Eigen_GlobalLU_t m_Glu; // persistent data to facilitate multiple factors
|
||||||
// should be defined as a class member
|
// should be defined as a class member
|
||||||
// SuperLU/SparseLU options
|
// SuperLU/SparseLU options
|
||||||
@ -158,7 +159,7 @@ void SparseLU::analyzePattern(const MatrixType& mat)
|
|||||||
|
|
||||||
// In symmetric mode, do not do postorder here
|
// In symmetric mode, do not do postorder here
|
||||||
if (m_symmetricmode == false) {
|
if (m_symmetricmode == false) {
|
||||||
VectorXi post, iwork;
|
IndexVector post, iwork;
|
||||||
// Post order etree
|
// Post order etree
|
||||||
post = internal::TreePostorder(m_mat.cols(), m_etree);
|
post = internal::TreePostorder(m_mat.cols(), m_etree);
|
||||||
|
|
||||||
@ -209,20 +210,20 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
int maxpanel = m_panel_size * m;
|
int maxpanel = m_panel_size * m;
|
||||||
|
|
||||||
// Set up pointers for integer working arrays
|
// Set up pointers for integer working arrays
|
||||||
Map<VectorXi> segrep(m_iwork, m); //
|
Map<IndexVector> segrep(&m_iwork(0), m); //
|
||||||
Map<VectorXi> parent(&segrep(0) + m, m); //
|
Map<IndexVector> parent(&segrep(0) + m, m); //
|
||||||
Map<VectorXi> xplore(&parent(0) + m, m); //
|
Map<IndexVector> xplore(&parent(0) + m, m); //
|
||||||
Map<VectorXi> repfnz(&xplore(0) + m, maxpanel); //
|
Map<IndexVector> repfnz(&xplore(0) + m, maxpanel); //
|
||||||
Map<VectorXi> panel_lsub(&repfnz(0) + maxpanel, maxpanel);//
|
Map<IndexVector> panel_lsub(&repfnz(0) + maxpanel, maxpanel);//
|
||||||
Map<VectorXi> xprune(&panel_lsub(0) + maxpanel, n); //
|
Map<IndexVector> xprune(&panel_lsub(0) + maxpanel, n); //
|
||||||
Map<VectorXi> marker(&xprune(0)+n, m * LU_NO_MARKER); //
|
Map<IndexVector> marker(&xprune(0)+n, m * LU_NO_MARKER); //
|
||||||
repfnz.setConstant(-1);
|
repfnz.setConstant(-1);
|
||||||
panel_lsub.setConstant(-1);
|
panel_lsub.setConstant(-1);
|
||||||
|
|
||||||
// Set up pointers for scalar working arrays
|
// Set up pointers for scalar working arrays
|
||||||
VectorType dense(maxpanel);
|
ScalarVector dense(maxpanel);
|
||||||
dense.setZero();
|
dense.setZero();
|
||||||
VectorType tempv(LU_NUM_TEMPV(m,m_panel_size,m_maxsuper,m_rowblk);
|
ScalarVector tempv(LU_NUM_TEMPV(m,m_panel_size,m_maxsuper,m_rowblk);
|
||||||
tempv.setZero();
|
tempv.setZero();
|
||||||
|
|
||||||
// Setup Permutation vectors
|
// Setup Permutation vectors
|
||||||
@ -234,7 +235,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
iperm_c = m_perm_c.inverse();
|
iperm_c = m_perm_c.inverse();
|
||||||
|
|
||||||
// Identify initial relaxed snodes
|
// Identify initial relaxed snodes
|
||||||
VectorXi relax_end(n);
|
IndexVector relax_end(n);
|
||||||
if ( m_symmetricmode = true )
|
if ( m_symmetricmode = true )
|
||||||
LU_heap_relax_snode(n, m_etree, m_relax, marker, relax_end);
|
LU_heap_relax_snode(n, m_etree, m_relax, marker, relax_end);
|
||||||
else
|
else
|
||||||
@ -243,11 +244,12 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
m_perm_r.setConstant(-1);
|
m_perm_r.setConstant(-1);
|
||||||
marker.setConstant(-1);
|
marker.setConstant(-1);
|
||||||
|
|
||||||
VectorXi& xsup = m_Glu.xsup;
|
IndexVector& xsup = m_Glu.xsup;
|
||||||
VectorXi& supno = m_GLu.supno;
|
IndexVector& supno = m_GLu.supno;
|
||||||
VectorXi& xlsub = m_Glu.xlsub;
|
IndexVector& xlsub = m_Glu.xlsub;
|
||||||
VectorXi& xlusup = m_GLu.xlusup;
|
IndexVector& xlusup = m_GLu.xlusup;
|
||||||
VectorXi& xusub = m_Glu.xusub;
|
IndexVector& xusub = m_Glu.xusub;
|
||||||
|
Index& nzlumax = m_Glu.nzlumax;
|
||||||
|
|
||||||
supno(0) = IND_EMPTY;
|
supno(0) = IND_EMPTY;
|
||||||
xsup(0) = xlsub(0) = xusub(0) = xlusup(0);
|
xsup(0) = xlsub(0) = xusub(0) = xlusup(0);
|
||||||
@ -259,7 +261,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
// (b) panel_size contiguous columns, <panel_size> defined by the user
|
// (b) panel_size contiguous columns, <panel_size> defined by the user
|
||||||
register int jcol,kcol;
|
register int jcol,kcol;
|
||||||
int min_mn = std::min(m,n);
|
int min_mn = std::min(m,n);
|
||||||
VectorXi panel_histo(n);
|
IndexVector panel_histo(n);
|
||||||
Index nextu, nextlu, jsupno, fsupc, new_next;
|
Index nextu, nextlu, jsupno, fsupc, new_next;
|
||||||
int pivrow; // Pivotal row number in the original row matrix
|
int pivrow; // Pivotal row number in the original row matrix
|
||||||
int nseg1; // Number of segments in U-column above panel row jcol
|
int nseg1; // Number of segments in U-column above panel row jcol
|
||||||
@ -274,7 +276,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
// Factorize the relaxed supernode(jcol:kcol)
|
// Factorize the relaxed supernode(jcol:kcol)
|
||||||
// First, determine the union of the row structure of the snode
|
// First, determine the union of the row structure of the snode
|
||||||
info = LU_snode_dfs(jcol, kcol, m_mat.innerIndexPtr(), m_mat.outerIndexPtr(), xprune, marker);
|
info = LU_snode_dfs(jcol, kcol, m_mat.innerIndexPtr(), m_mat.outerIndexPtr(), xprune, marker);
|
||||||
if ( !info )
|
if ( info )
|
||||||
{
|
{
|
||||||
m_info = NumericalIssue;
|
m_info = NumericalIssue;
|
||||||
m_factorizationIsOk = false;
|
m_factorizationIsOk = false;
|
||||||
@ -288,8 +290,12 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
nzlumax = m_Glu.nzlumax;
|
nzlumax = m_Glu.nzlumax;
|
||||||
while (new_next > nzlumax )
|
while (new_next > nzlumax )
|
||||||
{
|
{
|
||||||
m_Glu.lusup = LUMemXpand<Scalar>(jcol, nextlu, LUSUP, nzlumax);
|
mem = LUMemXpand<Scalar>(lusup, nzlumax, nextlu, LUSUP, m_Glu);
|
||||||
m_GLu.nzlumax = nzlumax;
|
if (mem)
|
||||||
|
{
|
||||||
|
m_factorizationIsOk = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Now, left-looking factorize each column within the snode
|
// Now, left-looking factorize each column within the snode
|
||||||
for (icol = jcol; icol<=kcol; icol++){
|
for (icol = jcol; icol<=kcol; icol++){
|
||||||
@ -303,7 +309,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
|
|
||||||
// Eliminate the current column
|
// Eliminate the current column
|
||||||
info = LU_pivotL(icol, m_diagpivotthresh, m_perm_r, m_iperm_c, pivrow, m_Glu);
|
info = LU_pivotL(icol, m_diagpivotthresh, m_perm_r, m_iperm_c, pivrow, m_Glu);
|
||||||
if ( !info )
|
if ( info )
|
||||||
{
|
{
|
||||||
m_info = NumericalIssue;
|
m_info = NumericalIssue;
|
||||||
m_factorizationIsOk = false;
|
m_factorizationIsOk = false;
|
||||||
@ -341,8 +347,8 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
|
|
||||||
nseg = nseg1; // begin after all the panel segments
|
nseg = nseg1; // begin after all the panel segments
|
||||||
//Depth-first-search for the current column
|
//Depth-first-search for the current column
|
||||||
VectorBlock<VectorXi> panel_lsubk(panel_lsub, k, m); //FIXME
|
VectorBlock<IndexVector> panel_lsubk(panel_lsub, k, m); //FIXME
|
||||||
VectorBlock<VectorXi> repfnz_k(repfnz, k, m); //FIXME
|
VectorBlock<IndexVector> repfnz_k(repfnz, k, m); //FIXME
|
||||||
info = LU_column_dfs(m, jj, perm_r, nseg, panel_lsub(k), segrep, repfnz_k, xprune, marker, parent, xplore, m_Glu);
|
info = LU_column_dfs(m, jj, perm_r, nseg, panel_lsub(k), segrep, repfnz_k, xprune, marker, parent, xplore, m_Glu);
|
||||||
if ( !info )
|
if ( !info )
|
||||||
{
|
{
|
||||||
@ -351,10 +357,10 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Numeric updates to this column
|
// Numeric updates to this column
|
||||||
VectorBlock<VectorXi> dense_k(dense, k, m); //FIXME
|
VectorBlock<IndexVector> dense_k(dense, k, m); //FIXME
|
||||||
VectorBlock<VectorXi> segrep_k(segrep, nseg1, m) // FIXME Check the length
|
VectorBlock<IndexVector> segrep_k(segrep, nseg1, m) // FIXME Check the length
|
||||||
info = LU_column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_Glu);
|
info = LU_column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_Glu);
|
||||||
if ( !info )
|
if ( info )
|
||||||
{
|
{
|
||||||
m_info = NumericalIssue;
|
m_info = NumericalIssue;
|
||||||
m_factorizationIsOk = false;
|
m_factorizationIsOk = false;
|
||||||
@ -364,7 +370,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
// Copy the U-segments to ucol(*)
|
// Copy the U-segments to ucol(*)
|
||||||
//FIXME Check that repfnz_k, dense_k... have stored references to modified columns
|
//FIXME Check that repfnz_k, dense_k... have stored references to modified columns
|
||||||
info = LU_copy_to_col(jj, nseg, segrep, repfnz_k, perm_r, dense_k, m_Glu);
|
info = LU_copy_to_col(jj, nseg, segrep, repfnz_k, perm_r, dense_k, m_Glu);
|
||||||
if ( !info )
|
if ( info )
|
||||||
{
|
{
|
||||||
m_info = NumericalIssue;
|
m_info = NumericalIssue;
|
||||||
m_factorizationIsOk = false;
|
m_factorizationIsOk = false;
|
||||||
@ -373,7 +379,7 @@ void SparseLU::factorize(const MatrixType& matrix)
|
|||||||
|
|
||||||
// Form the L-segment
|
// Form the L-segment
|
||||||
info = LU_pivotL(jj, m_diagpivotthresh, m_perm_r, iperm_c, pivrow, m_Glu);
|
info = LU_pivotL(jj, m_diagpivotthresh, m_perm_r, iperm_c, pivrow, m_Glu);
|
||||||
if ( !info )
|
if ( info )
|
||||||
{
|
{
|
||||||
m_info = NumericalIssue;
|
m_info = NumericalIssue;
|
||||||
m_factorizationIsOk = false;
|
m_factorizationIsOk = false;
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocate various working space needed in the numerical factorization phase.
|
* \brief Allocate various working space failed in the numerical factorization phase.
|
||||||
* \param m number of rows of the input matrix
|
* \param m number of rows of the input matrix
|
||||||
* \param n number of columns
|
* \param n number of columns
|
||||||
* \param annz number of initial nonzeros in the matrix
|
* \param annz number of initial nonzeros in the matrix
|
||||||
@ -61,22 +61,21 @@ namespace internal {
|
|||||||
* \param iwork Integer working space
|
* \param iwork Integer working space
|
||||||
* \param lwork if lwork=-1, this routine returns an estimated size of the required memory
|
* \param lwork if lwork=-1, this routine returns an estimated size of the required memory
|
||||||
* \param Glu persistent data to facilitate multiple factors : will be deleted later ??
|
* \param Glu persistent data to facilitate multiple factors : will be deleted later ??
|
||||||
* \return an estimated size of the required memory if lwork = -1;
|
* \return an estimated size of the required memory if lwork = -1; otherwise, return the size of actually allocated when memory allocation failed
|
||||||
* FIXME should also return the size of actually allocated when memory allocation failed
|
* NOTE Unlike SuperLU, this routine does not allow the user to provide its own user space
|
||||||
* NOTE Unlike SuperLU, this routine does not allow the user to provide the size to allocate
|
|
||||||
*/
|
*/
|
||||||
template <typename ScalarVector,typename IndexVector>
|
template <typename ScalarVector,typename IndexVector>
|
||||||
int SparseLU::LUMemInit(int m, int n, int annz, Scalar *work, Index *iwork, int lwork, int fillratio, GlobalLU_t& Glu)
|
int SparseLU::LUMemInit(int m, int n, int annz, ScalarVector& work, IndexVector& iwork, int lwork, int fillratio, GlobalLU_t& Glu)
|
||||||
{
|
{
|
||||||
typedef typename ScalarVector::Scalar;
|
typedef typename ScalarVector::Scalar;
|
||||||
typedef typename IndexVector::Index;
|
typedef typename IndexVector::Index;
|
||||||
|
|
||||||
Glu.num_expansions = 0; //No memory expansions so far
|
int& num_expansions = Glu.num_expansions; //No memory expansions so far
|
||||||
if (!Glu.expanders)
|
num_expansions = 0;
|
||||||
Glu.expanders = new ExpHeader(LU_NBR_MEMTYPE);
|
|
||||||
|
|
||||||
// Guess the size for L\U factors
|
// Guess the size for L\U factors
|
||||||
int nzlmax, nzumax, nzlumax;
|
Index& nzlmax = Glu.nzlmax;
|
||||||
|
Index& nzumax = Glu.nzumax;
|
||||||
|
Index& nzlumax = Glu.nzlumax;
|
||||||
nzumax = nzlumax = m_fillratio * annz; // estimated number of nonzeros in U
|
nzumax = nzlumax = m_fillratio * annz; // estimated number of nonzeros in U
|
||||||
nzlmax = std::max(1, m_fill_ratio/4.) * annz; // estimated nnz in L factor
|
nzlmax = std::max(1, m_fill_ratio/4.) * annz; // estimated nnz in L factor
|
||||||
|
|
||||||
@ -90,138 +89,145 @@ int SparseLU::LUMemInit(int m, int n, int annz, Scalar *work, Index *iwork, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup the required space
|
// Setup the required space
|
||||||
// NOTE: In SuperLU, there is an option to let the user provide its own space, unlike here.
|
|
||||||
|
|
||||||
// Allocate Integer pointers for L\U factors
|
// First allocate Integer pointers for L\U factors
|
||||||
Glu.supno = new IndexVector;
|
Glu.supno.resize(n+1);
|
||||||
Glu.supno->resize(n+1);
|
Glu.xlsub.resize(n+1);
|
||||||
|
Glu.xlusup.resize(n+1);
|
||||||
Glu.xlsub = new IndexVector;
|
Glu.xusub.resize(n+1);
|
||||||
Glu.xlsub->resize(n+1);
|
|
||||||
|
|
||||||
Glu.xlusup = new IndexVector;
|
|
||||||
Glu.xlusup->resize(n+1);
|
|
||||||
|
|
||||||
Glu.xusub = new IndexVector;
|
|
||||||
Glu.xusub->resize(n+1);
|
|
||||||
|
|
||||||
// Reserve memory for L/U factors
|
// Reserve memory for L/U factors
|
||||||
Glu.lusup = new ScalarVector;
|
expand<ScalarVector>(Glu.lusup, nzlumax, 0, 0, num_expansions);
|
||||||
Glu.ucol = new ScalarVector;
|
expand<ScalarVector>(Glu.ucol,nzumax, 0, 0, num_expansions);
|
||||||
Glu.lsub = new IndexVector;
|
expand<IndexVector>(Glu.lsub,nzlmax, 0, 0, num_expansions);
|
||||||
Glu.usub = new IndexVector;
|
expand<IndexVector>(Glu.usub,nzumax, 0, 1, num_expansions);
|
||||||
|
|
||||||
expand<ScalarVector>(Glu.lusup,nzlumax, LUSUP, 0, 0, Glu);
|
|
||||||
expand<ScalarVector>(Glu.ucol,nzumax, UCOL, 0, 0, Glu);
|
|
||||||
expand<IndexVector>(Glu.lsub,nzlmax, LSUB, 0, 0, Glu);
|
|
||||||
expand<IndexVector>(Glu.usub,nzumax, USUB, 0, 1, Glu);
|
|
||||||
|
|
||||||
// Check if the memory is correctly allocated,
|
// Check if the memory is correctly allocated,
|
||||||
// Should be a try... catch section here
|
// Should be a try... catch section here
|
||||||
while ( !Glu.lusup.size() || !Glu.ucol.size() || !Glu.lsub.size() || !Glu.usub.size())
|
while ( !Glu.lusup.size() || !Glu.ucol.size() || !Glu.lsub.size() || !Glu.usub.size())
|
||||||
{
|
{
|
||||||
//otherwise reduce the estimated size and retry
|
//otherwise reduce the estimated size and retry
|
||||||
// delete [] Glu.lusup;
|
|
||||||
// delete [] Glu.ucol;
|
|
||||||
// delete [] Glu.lsub;
|
|
||||||
// delete [] Glu.usub;
|
|
||||||
//
|
|
||||||
nzlumax /= 2;
|
nzlumax /= 2;
|
||||||
nzumax /= 2;
|
nzumax /= 2;
|
||||||
nzlmax /= 2;
|
nzlmax /= 2;
|
||||||
//FIXME Should be an excpetion here
|
//FIXME Should be an exception here
|
||||||
eigen_assert (nzlumax > annz && "Not enough memory to perform factorization");
|
if (nzlumax < annz ) return nzlumax;
|
||||||
|
|
||||||
expand<ScalarVector>(Glu.lsup, nzlumax, LUSUP, 0, 0, Glu);
|
expand<ScalarVector>(Glu.lsup, nzlumax, 0, 0, Glu);
|
||||||
expand<ScalarVector>(Glu.ucol, nzumax, UCOL, 0, 0, Glu);
|
expand<ScalarVector>(Glu.ucol, nzumax, 0, 0, Glu);
|
||||||
expand<IndexVector>(Glu.lsub, nzlmax, LSUB, 0, 0, Glu);
|
expand<IndexVector>(Glu.lsub, nzlmax, 0, 0, Glu);
|
||||||
expand<IndexVector>(Glu.usub, nzumax, USUB, 0, 1, Glu);
|
expand<IndexVector>(Glu.usub, nzumax, 0, 1, Glu);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LUWorkInit : Now, allocate known working storage
|
// LUWorkInit : Now, allocate known working storage
|
||||||
int isize = (2 * m_panel_size + 3 + LU_NO_MARKER) * m + n;
|
int isize = (2 * m_panel_size + 3 + LU_NO_MARKER) * m + n;
|
||||||
int dsize = m * m_panel_size + LU_NUM_TEMPV(m, m_panel_size, m_maxsuper, m_rowblk);
|
int dsize = m * m_panel_size + LU_NUM_TEMPV(m, m_panel_size, m_maxsuper, m_rowblk);
|
||||||
iwork = new Index(isize);
|
iwork.resize(isize);
|
||||||
eigen_assert( (m_iwork != 0) && "Malloc fails for iwork");
|
work.resize(isize);
|
||||||
work = new Scalar(dsize);
|
|
||||||
eigen_assert( (m_work != 0) && "Malloc fails for dwork");
|
|
||||||
|
|
||||||
++Glu.num_expansions;
|
++num_expansions;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
} // end LuMemInit
|
} // end LuMemInit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand the existing storage to accomodate more fill-ins
|
* Expand the existing storage to accomodate more fill-ins
|
||||||
* \param vec Valid pointer to a vector to allocate or expand
|
* \param vec Valid pointer to the vector to allocate or expand
|
||||||
* \param [in,out]prev_len At input, length from previous call. At output, length of the newly allocated vector
|
* \param [in,out]length At input, contain the current length of the vector that is to be increased. At output, length of the newly allocated vector
|
||||||
* \param type Which part of the memory to expand
|
* \param [in]len_to_copy Current number of elements in the factors
|
||||||
* \param len_to_copy Size of the memory to be copied to new store
|
* \param keep_prev true: use length and do not expand the vector; false: compute new_len and expand
|
||||||
* \param keep_prev true: use prev_len; Do not expand this vector; false: compute new_len and expand
|
* \param [in,out]num_expansions Number of times the memory has been expanded
|
||||||
*/
|
*/
|
||||||
template <typename VectorType >
|
template <typename VectorType >
|
||||||
int SparseLU::expand(VectorType& vec, int& prev_len, MemType type, int len_to_copy, bool keep_prev, GlobalLU_t& Glu)
|
int SparseLU::expand(VectorType& vec, int& length, int len_to_copy, bool keep_prev, int& num_expansions)
|
||||||
{
|
{
|
||||||
|
|
||||||
float alpha = 1.5; // Ratio of the memory increase
|
float alpha = 1.5; // Ratio of the memory increase
|
||||||
int new_len; // New size of the allocated memory
|
int new_len; // New size of the allocated memory
|
||||||
|
|
||||||
if(Glu.num_expansions == 0 || keep_prev)
|
if(num_expansions == 0 || keep_prev)
|
||||||
new_len = prev_len; // First time allocate requested
|
new_len = length ; // First time allocate requested
|
||||||
else
|
else
|
||||||
new_len = alpha * prev_len;
|
new_len = alpha * length ;
|
||||||
|
|
||||||
// Allocate new space
|
VectorType old_vec; // Temporary vector to hold the previous values
|
||||||
// vec = new VectorType(new_len);
|
if (len_to_copy > 0 )
|
||||||
VectorType old_vec(vec);
|
old_vec = vec; // old_vec should be of size len_to_copy... to be checked
|
||||||
if ( Glu.num_expansions != 0 ) // The memory has been expanded before
|
|
||||||
|
//expand the current vector //FIXME Should be in a try ... catch region
|
||||||
|
vec.resize(new_len);
|
||||||
|
/*
|
||||||
|
* Test if the memory has been well allocated
|
||||||
|
* otherwise reduce the size and try to reallocate
|
||||||
|
* copy data from previous vector (if exists) to the newly allocated vector
|
||||||
|
*/
|
||||||
|
if ( num_expansions != 0 ) // The memory has been expanded before
|
||||||
{
|
{
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
vec.resize(new_len); //expand the current vector
|
|
||||||
if (keep_prev)
|
if (keep_prev)
|
||||||
{
|
{
|
||||||
if (!vec.size()) return -1 ; // FIXME could throw an exception somehow
|
if (!vec.size()) return new_len ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (!vec.size())
|
while (!vec.size())
|
||||||
{
|
{
|
||||||
// Reduce the size and allocate again
|
// Reduce the size and allocate again
|
||||||
if ( ++tries > 10) return -1
|
if ( ++tries > 10) return new_len;
|
||||||
alpha = LU_Reduce(alpha);
|
alpha = LU_Reduce(alpha);
|
||||||
new_len = alpha * prev_len;
|
new_len = alpha * length ;
|
||||||
vec->resize(new_len);
|
vec.resize(new_len); //FIXME Should be in a try catch section
|
||||||
}
|
}
|
||||||
} // end allocation
|
} // end allocation
|
||||||
|
|
||||||
//Copy the previous values to the newly allocated space
|
//Copy the previous values to the newly allocated space
|
||||||
for (int i = 0; i < old_vec.size(); i++)
|
if (len_to_copy > 0)
|
||||||
vec(i) = old_vec(i);
|
vec.segment(0, len_to_copy) = old_vec;
|
||||||
} // end expansion
|
} // end expansion
|
||||||
// expanders[type].mem = vec;
|
length = new_len;
|
||||||
// expanders[type].size = new_len;
|
if(num_expansions) ++num_expansions;
|
||||||
prev_len = new_len;
|
|
||||||
if(Glu.num_expansions) ++Glu.num_expansions;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Expand the existing storage
|
* \brief Expand the existing storage
|
||||||
*
|
* \param vec vector to expand
|
||||||
* NOTE: The calling sequence of this function is different from that of SuperLU
|
* \param [in,out]maxlen On input, previous size of vec (Number of elements to copy ). on output, new size
|
||||||
*
|
* \param next current number of elements in the vector.
|
||||||
* \return a pointer to the newly allocated space
|
* \param Glu Global data structure
|
||||||
|
* \return 0 on success, > 0 size of the memory allocated so far
|
||||||
*/
|
*/
|
||||||
template <typename VectorType>
|
template <typename IndexVector>
|
||||||
VectorType* SparseLU::LUMemXpand(int jcol, int next, MemType mem_type, int& maxlen)
|
int SparseLU::LUMemXpand(VectorType& vec, int& maxlen, int next, LU_MemType memtype, LU_GlobalLu_t& Glu)
|
||||||
{
|
{
|
||||||
VectorType *newmem;
|
int failed_size;
|
||||||
|
int& num_expansions = Glu.num_expansions;
|
||||||
if (memtype == USUB)
|
if (memtype == USUB)
|
||||||
vec = expand<VectorType>(vec, maxlen, mem_type, next, 1);
|
failed_size = expand<IndexVector>(vec, maxlen, next, 1, num_expansions);
|
||||||
else
|
else
|
||||||
vec = expand<VectorType>(vec, maxlen, mem_type, next, 0);
|
failed_size = expand<IndexVector>(vec, maxlen, next, 0, num_expansions);
|
||||||
// FIXME Should be an exception instead of an assert
|
|
||||||
eigen_assert(new_mem.size() && "Can't expand memory");
|
if (failed_size)
|
||||||
|
return faileld_size;
|
||||||
|
|
||||||
return new_mem;
|
// The following code is not really needed since maxlen is passed by reference
|
||||||
|
// and correspond to the appropriate field in Glu
|
||||||
|
// switch ( mem_type ) {
|
||||||
|
// case LUSUP:
|
||||||
|
// Glu.nzlumax = maxlen;
|
||||||
|
// break;
|
||||||
|
// case UCOL:
|
||||||
|
// Glu.nzumax = maxlen;
|
||||||
|
// break;
|
||||||
|
// case LSUB:
|
||||||
|
// Glu.nzlmax = maxlen;
|
||||||
|
// break;
|
||||||
|
// case USUB:
|
||||||
|
// Glu.nzumax = maxlen;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,9 @@ typedef enum {NATURAL, MMD_ATA, MMD_AT_PLUS_A, COLAMD, MY_PERMC} colperm_t;
|
|||||||
typedef enum {DOFACT, SamePattern, Factored} fact_t;
|
typedef enum {DOFACT, SamePattern, Factored} fact_t;
|
||||||
typedef enum {LUSUP, UCOL, LSUB, USUB, LLVL, ULVL} MemType;
|
typedef enum {LUSUP, UCOL, LSUB, USUB, LLVL, ULVL} MemType;
|
||||||
|
|
||||||
/** Headers for dynamically managed memory
|
|
||||||
\tparam IndexVectorType can be int, real scalar or complex scalar*/
|
/* Obsolete, headers for dynamically managed memory
|
||||||
|
\tparam VectorType can be int, real scalar or complex scalar*/
|
||||||
template <typename VectorType>
|
template <typename VectorType>
|
||||||
struct ExpHeader {
|
struct ExpHeader {
|
||||||
int size; // Length of the memory that has been used */
|
int size; // Length of the memory that has been used */
|
||||||
@ -118,7 +119,7 @@ struct {
|
|||||||
Index n; // Number of columns in the matrix
|
Index n; // Number of columns in the matrix
|
||||||
|
|
||||||
int num_expansions;
|
int num_expansions;
|
||||||
ExpHeader *expanders; // Array of pointers to 4 types of memory
|
ExpHeader *expanders; // Deprecated... Array of pointers to 4 types of memory
|
||||||
} GlobalLU_t;
|
} GlobalLU_t;
|
||||||
|
|
||||||
}// End namespace Eigen
|
}// End namespace Eigen
|
||||||
|
@ -59,8 +59,8 @@
|
|||||||
* > 0 - number of bytes allocated when run out of space
|
* > 0 - number of bytes allocated when run out of space
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template <typename VectorType>
|
template <typename ScalarVector, typename IndexVector>
|
||||||
int SparseLU::LU_column_bmod(const int jcol, const int nseg, VectorType& dense, VectorType& tempv, VectorXi& segrep, VectorXi& repfnz, int fpanelc, LU_GlobalLu_t& Glu)
|
int SparseLU::LU_column_bmod(const int jcol, const int nseg, ScalarVector& dense, ScalarVector& tempv, IndexVector& segrep, IndexVector& repfnz, int fpanelc, LU_GlobalLu_t& Glu)
|
||||||
{
|
{
|
||||||
|
|
||||||
int jsupno, k, ksub, krep, krep_ind, ksupno;
|
int jsupno, k, ksub, krep, krep_ind, ksupno;
|
||||||
@ -72,13 +72,14 @@ int SparseLU::LU_column_bmod(const int jcol, const int nseg, VectorType& dense,
|
|||||||
* kfnz = first nonz in the k-th supernodal segment
|
* kfnz = first nonz in the k-th supernodal segment
|
||||||
* no-zeros = no lf leading zeros in a supernodal U-segment
|
* no-zeros = no lf leading zeros in a supernodal U-segment
|
||||||
*/
|
*/
|
||||||
VectorXi& xsup = Glu.xsup;
|
IndexVector& xsup = Glu.xsup;
|
||||||
VectorXi& supno = Glu.supno;
|
IndexVector& supno = Glu.supno;
|
||||||
VectorXi& lsub = Glu.lsub;
|
IndexVector& lsub = Glu.lsub;
|
||||||
VectorXi& xlsub = Glu.xlsub;
|
IndexVector& xlsub = Glu.xlsub;
|
||||||
VectorXi& xlusup = Glu.xlusup;
|
IndexVector& xlusup = Glu.xlusup;
|
||||||
VectorType& lusup = Glu.lusup;
|
ScalarVector& lusup = Glu.lusup;
|
||||||
int nzlumax = GLu.nzlumax;
|
Index& nzlumax = Glu.nzlumax;
|
||||||
|
|
||||||
int jsupno = supno(jcol);
|
int jsupno = supno(jcol);
|
||||||
// For each nonzero supernode segment of U[*,j] in topological order
|
// For each nonzero supernode segment of U[*,j] in topological order
|
||||||
k = nseg - 1;
|
k = nseg - 1;
|
||||||
@ -126,13 +127,13 @@ int SparseLU::LU_column_bmod(const int jcol, const int nseg, VectorType& dense,
|
|||||||
luptr += nsupr * no_zeros + no_zeros;
|
luptr += nsupr * no_zeros + no_zeros;
|
||||||
// Form Eigen matrix and vector
|
// Form Eigen matrix and vector
|
||||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(nsupr) );
|
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(nsupr) );
|
||||||
Map<VectorType> u(tempv.data(), segsize);
|
Map<ScalarVector> u(tempv.data(), segsize);
|
||||||
u = A.triangularView<Lower>().solve(u);
|
u = A.triangularView<Lower>().solve(u);
|
||||||
|
|
||||||
// Dense matrix-vector product y <-- A*x
|
// Dense matrix-vector product y <-- A*x
|
||||||
luptr += segsize;
|
luptr += segsize;
|
||||||
new (&A) (&A) Map<Matrix<Scalar,Dynamic, Dynamic>, 0, OuterStride<> > ( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(nsupr) );
|
new (&A) (&A) Map<Matrix<Scalar,Dynamic, Dynamic>, 0, OuterStride<> > ( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(nsupr) );
|
||||||
Map<VectorType> l( &(tempv.data()[segsize]), segsize);
|
Map<ScalarVector> l( &(tempv.data()[segsize]), segsize);
|
||||||
l= A * u;
|
l= A * u;
|
||||||
|
|
||||||
// Scatter tempv[] into SPA dense[] as a temporary storage
|
// Scatter tempv[] into SPA dense[] as a temporary storage
|
||||||
@ -164,10 +165,9 @@ int SparseLU::LU_column_bmod(const int jcol, const int nseg, VectorType& dense,
|
|||||||
new_next = nextlu + xlsub(fsupc + 1) - xlsub(fsupc);
|
new_next = nextlu + xlsub(fsupc + 1) - xlsub(fsupc);
|
||||||
while (new_next > nzlumax )
|
while (new_next > nzlumax )
|
||||||
{
|
{
|
||||||
Glu.lusup = LUmemXpand<Scalar>(jcol, nextlu, LUSUP, &nzlumax);
|
mem = LUmemXpand<Scalar>(Glu.lusup, nzlumax, nextlu, LUSUP, Glu);
|
||||||
Glu.nzlumax = nzlumax;
|
if (mem) return mem;
|
||||||
lusup = Glu.lusup;
|
lsub = Glu.lsub; //FIXME Why is it updated here.
|
||||||
lsub = Glu.lsub;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (isub = xlsub(fsupc); isub < xlsub(fsupc+1); isub++)
|
for (isub = xlsub(fsupc); isub < xlsub(fsupc+1); isub++)
|
||||||
@ -203,11 +203,11 @@ int SparseLU::LU_column_bmod(const int jcol, const int nseg, VectorType& dense,
|
|||||||
// points to the beginning of jcol in snode L\U(jsupno)
|
// points to the beginning of jcol in snode L\U(jsupno)
|
||||||
ufirst = xlusup(jcol) + d_fsupc;
|
ufirst = xlusup(jcol) + d_fsupc;
|
||||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(nsupr) );
|
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(nsupr) );
|
||||||
Map<VectorType> l( &(lusup.data()[ufirst]), nsupc );
|
Map<ScalarVector> l( &(lusup.data()[ufirst]), nsupc );
|
||||||
u = A.triangularView().solve(u);
|
u = A.triangularView().solve(u);
|
||||||
|
|
||||||
new (&A) Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(nsupr) );
|
new (&A) Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(nsupr) );
|
||||||
Map<VectorType> l( &(lusup.data()[ufirst+nsupc]), nsupr );
|
Map<ScalarVector> l( &(lusup.data()[ufirst+nsupc]), nsupr );
|
||||||
l = l - A * u;
|
l = l - A * u;
|
||||||
|
|
||||||
} // End if fst_col
|
} // End if fst_col
|
||||||
|
@ -70,9 +70,10 @@
|
|||||||
* > 0 number of bytes allocated when run out of space
|
* > 0 number of bytes allocated when run out of space
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int SparseLU::LU_column_dfs(const int m, const int jcol, VectorXi& perm_r, VectorXi& nseg VectorXi& lsub_col, VectorXi& segrep, VectorXi& repfnz, VectorXi& xprune, VectorXi& marker, VectorXi& parent, VectorXi& xplore, LU_GlobalLu_t& Glu)
|
template <typename IndexVector>
|
||||||
|
int SparseLU::LU_column_dfs(const int m, const int jcol, IndexVector& perm_r, IndexVector& nseg IndexVector& lsub_col, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, LU_GlobalLu_t& Glu)
|
||||||
{
|
{
|
||||||
typedef typename VectorXi::Index;
|
typedef typename IndexVector::IndexVector;
|
||||||
|
|
||||||
int jcolp1, jcolm1, jsuper, nsuper, nextl;
|
int jcolp1, jcolm1, jsuper, nsuper, nextl;
|
||||||
int krow; // Row index of the current element
|
int krow; // Row index of the current element
|
||||||
@ -82,17 +83,18 @@ int SparseLU::LU_column_dfs(const int m, const int jcol, VectorXi& perm_r, Vecto
|
|||||||
int chperm, chmark, chrep, oldrep, kchild;
|
int chperm, chmark, chrep, oldrep, kchild;
|
||||||
int myfnz; // First nonzero element in the current column
|
int myfnz; // First nonzero element in the current column
|
||||||
int xdfs, maxdfs, kpar;
|
int xdfs, maxdfs, kpar;
|
||||||
|
int mem;
|
||||||
// Initialize pointers
|
// Initialize pointers
|
||||||
VectorXi& xsup = Glu.xsup;
|
IndexVector& xsup = Glu.xsup;
|
||||||
VectorXi& supno = Glu.supno;
|
IndexVector& supno = Glu.supno;
|
||||||
VectorXi& lsub = Glu.lsub;
|
IndexVector& lsub = Glu.lsub;
|
||||||
VectorXi& xlsub = Glu.xlsub;
|
IndexVector& xlsub = Glu.xlsub;
|
||||||
|
IndexVector& nzlmax = Glu.nzlmax;
|
||||||
|
|
||||||
nsuper = supno(jcol);
|
nsuper = supno(jcol);
|
||||||
jsuper = nsuper;
|
jsuper = nsuper;
|
||||||
nextl = xlsup(jcol);
|
nextl = xlsup(jcol);
|
||||||
VectorBlock<VectorXi> marker2(marker, 2*m, m);
|
VectorBlock<IndexVector> marker2(marker, 2*m, m);
|
||||||
// For each nonzero in A(*,jcol) do dfs
|
// For each nonzero in A(*,jcol) do dfs
|
||||||
for (k = 0; lsub_col[k] != IND_EMPTY; k++)
|
for (k = 0; lsub_col[k] != IND_EMPTY; k++)
|
||||||
{
|
{
|
||||||
@ -113,10 +115,8 @@ int SparseLU::LU_column_dfs(const int m, const int jcol, VectorXi& perm_r, Vecto
|
|||||||
lsub(nextl++) = krow; // krow is indexed into A
|
lsub(nextl++) = krow; // krow is indexed into A
|
||||||
if ( nextl >= nzlmax )
|
if ( nextl >= nzlmax )
|
||||||
{
|
{
|
||||||
Glu.lsub = LUMemXpand<Index>(jcol, nextl, LSUB, nzlmax);
|
mem = LUMemXpand<IndexVector>(lsub, nzlmax, nextl, LSUB, Glu);
|
||||||
//FIXME try... catch out of space
|
if ( mem ) return mem;
|
||||||
Glu.nzlmax = nzlmax;
|
|
||||||
lsub = Glu.lsub;
|
|
||||||
}
|
}
|
||||||
if (kmark != jcolm1) jsuper = IND_EMPTY; // Row index subset testing
|
if (kmark != jcolm1) jsuper = IND_EMPTY; // Row index subset testing
|
||||||
}
|
}
|
||||||
@ -163,10 +163,8 @@ int SparseLU::LU_column_dfs(const int m, const int jcol, VectorXi& perm_r, Vecto
|
|||||||
lsub(nextl++) = kchild;
|
lsub(nextl++) = kchild;
|
||||||
if (nextl >= nzlmax)
|
if (nextl >= nzlmax)
|
||||||
{
|
{
|
||||||
Glu.lsub = LUMemXpand<Index>(jcol, nextl, LSUB, nzlmax);
|
mem = LUMemXpand<IndexVector>(lsub, nzlmax, nextl, LSUB);
|
||||||
//FIXME Catch out of space errors
|
if (mem) return mem;
|
||||||
GLu.nzlmax = nzlmax;
|
|
||||||
lsub = Glu.lsub;
|
|
||||||
}
|
}
|
||||||
if (chmark != jcolm1) jsuper = IND_EMPTY;
|
if (chmark != jcolm1) jsuper = IND_EMPTY;
|
||||||
}
|
}
|
||||||
|
@ -58,26 +58,28 @@
|
|||||||
* > 0 - number of bytes allocated when run out of space
|
* > 0 - number of bytes allocated when run out of space
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template <typename VectorType>
|
template <typename ScalarVector, typename IndexVector>
|
||||||
int SparseLU::LU_copy_to_ucol(const int jcol, const int nseg, VectorXi& segrep, VectorXi& repfnz, VectorXi& perm_r, VectorType& dense, LU_GlobalLu_t& Glu)
|
int SparseLU::LU_copy_to_ucol(const int jcol, const int nseg, IndexVector& segrep, IndexVector& repfnz, IndexVector& perm_r, ScalarVector& dense, LU_GlobalLu_t& Glu)
|
||||||
{
|
{
|
||||||
int ksupno, k, ksub, krep, ksupno;
|
Index ksupno, k, ksub, krep, ksupno;
|
||||||
|
typedef typename IndexVector::Index;
|
||||||
|
|
||||||
VectorXi& xsup = Glu.xsup;
|
IndexVector& xsup = Glu.xsup;
|
||||||
VectorXi& supno = Glu.supno;
|
IndexVector& supno = Glu.supno;
|
||||||
VectorXi& lsub = Glu.lsub;
|
IndexVector& lsub = Glu.lsub;
|
||||||
VectorXi& xlsub = Glu.xlsub;
|
IndexVector& xlsub = Glu.xlsub;
|
||||||
VectorType& ucol = GLu.ucol;
|
ScalarVector& ucol = GLu.ucol;
|
||||||
VectorXi& usub = Glu.usub;
|
IndexVector& usub = Glu.usub;
|
||||||
VectorXi& xusub = Glu.xusub;
|
IndexVector& xusub = Glu.xusub;
|
||||||
int nzumax = GLu.nzumax;
|
Index& nzumax = Glu.nzumax;
|
||||||
int jsupno = supno(jcol);
|
|
||||||
|
Index jsupno = supno(jcol);
|
||||||
|
|
||||||
// For each nonzero supernode segment of U[*,j] in topological order
|
// For each nonzero supernode segment of U[*,j] in topological order
|
||||||
k = nseg - 1;
|
k = nseg - 1;
|
||||||
int nextu = xusub(jcol);
|
Index nextu = xusub(jcol);
|
||||||
int kfnz, isub, segsize;
|
Index kfnz, isub, segsize;
|
||||||
int new_next,irow;
|
Index new_next,irow;
|
||||||
for (ksub = 0; ksub < nseg; ksub++)
|
for (ksub = 0; ksub < nseg; ksub++)
|
||||||
{
|
{
|
||||||
krep = segrep(k); k--;
|
krep = segrep(k); k--;
|
||||||
@ -93,13 +95,12 @@ int SparseLU::LU_copy_to_ucol(const int jcol, const int nseg, VectorXi& segrep,
|
|||||||
new_next = nextu + segsize;
|
new_next = nextu + segsize;
|
||||||
while (new_next > nzumax)
|
while (new_next > nzumax)
|
||||||
{
|
{
|
||||||
Glu.ucol = LU_MemXpand<Scalar>(jcol, nextu, UCOL, nzumax); //FIXME try and catch errors
|
mem = LU_MemXpand<ScalarVector>(ucol, nzumax, nextu, UCOL, Glu);
|
||||||
ucol = Glu.ucol;
|
if (mem) return mem;
|
||||||
Glu.nzumax = nzumax;
|
mem = LU_MemXpand<Index>(usub, nzumax, nextu, USUB, Glu);
|
||||||
Glu.usub = LU_MemXpand<Index>(jcol, nextu, USUB, nzumax); //FIXME try and catch errors
|
if (mem) return mem;
|
||||||
Glu.nzumax = nzumax;
|
|
||||||
usub = Glu.usub;
|
lsub = Glu.lsub; //FIXME Why setting this as well ??
|
||||||
lsub = Glu.lsub;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < segsize; i++)
|
for (i = 0; i < segsize; i++)
|
||||||
|
@ -55,17 +55,19 @@
|
|||||||
* \param colptr Pointer to the beginning of each column
|
* \param colptr Pointer to the beginning of each column
|
||||||
* \param xprune (out) The pruned tree ??
|
* \param xprune (out) The pruned tree ??
|
||||||
* \param marker (in/out) working vector
|
* \param marker (in/out) working vector
|
||||||
|
* \return 0 on success, > 0 size of the memory when memory allocation failed
|
||||||
*/
|
*/
|
||||||
template <typename Index>
|
template <typename IndexVector>
|
||||||
int SparseLU::LU_snode_dfs(const int jcol, const int kcol, const VectorXi* asub, const VectorXi* colptr,
|
int SparseLU::LU_snode_dfs(const int jcol, const int kcol, const IndexVector* asub, const IndexVector* colptr, IndexVector& xprune, IndexVector& marker, LU_GlobalLu_t& Glu)
|
||||||
VectorXi& xprune, VectorXi& marker, LU_GlobalLu_t *m_Glu)
|
|
||||||
{
|
{
|
||||||
VectorXi& xsup = m_Glu->xsup;
|
typedef typename IndexVector::Index;
|
||||||
VectorXi& supno = m_Glu->supno; // Supernode number corresponding to this column
|
IndexVector& xsup = Glu.xsup;
|
||||||
VectorXi& lsub = m_Glu->lsub;
|
IndexVector& supno = Glu.supno; // Supernode number corresponding to this column
|
||||||
VectorXi& xlsub = m_Glu->xlsub;
|
IndexVector& lsub = Glu.lsub;
|
||||||
|
IndexVector& xlsub = Glu.xlsub;
|
||||||
int nsuper = ++supno(jcol); // Next available supernode number
|
Index& nzlmax = Glu.nzlmax;
|
||||||
|
int mem;
|
||||||
|
Index nsuper = ++supno(jcol); // Next available supernode number
|
||||||
register int nextl = xlsub(jcol); //Index of the starting location of the jcol-th column in lsub
|
register int nextl = xlsub(jcol); //Index of the starting location of the jcol-th column in lsub
|
||||||
register int i,k;
|
register int i,k;
|
||||||
int krow,kmark;
|
int krow,kmark;
|
||||||
@ -83,26 +85,24 @@
|
|||||||
lsub(nextl++) = krow;
|
lsub(nextl++) = krow;
|
||||||
if( nextl >= nzlmax )
|
if( nextl >= nzlmax )
|
||||||
{
|
{
|
||||||
m_Glu->lsub = LUMemXpand<Index>(jcol, nextl, LSUB, nzlmax);
|
mem = LUMemXpand<IndexVector>(lsub, nzlmax, nextl, LSUB, Glu);
|
||||||
m_Glu->nzlmax = nzlmax;
|
if (mem) return mem;
|
||||||
lsub = m_Glu->lsub;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
supno(i) = nsuper;
|
supno(i) = nsuper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If supernode > 1, then make a copy of the subscripts for pruning
|
// If supernode > 1, then make a copy of the subscripts for pruning
|
||||||
if (jcol < kcol)
|
if (jcol < kcol)
|
||||||
{
|
{
|
||||||
int new_next = nextl + (nextl - xlsub(jcol));
|
Index new_next = nextl + (nextl - xlsub(jcol));
|
||||||
while (new_next > nzlmax)
|
while (new_next > nzlmax)
|
||||||
{
|
{
|
||||||
m_Glu->lsub = LUMemXpand<Index>(jcol, nextl, LSUB, &nzlmax);
|
mem = LUMemXpand<IndexVector>(lsub, nzlmax, nextl, LSUB, Glu);
|
||||||
m_Glu->nzlmax= nzlmax;
|
if (mem) return mem;
|
||||||
lsub = m_Glu->lsub;
|
|
||||||
}
|
}
|
||||||
int ifrom, ito = nextl;
|
Index ifrom, ito = nextl;
|
||||||
for (ifrom = xlsub(jcol); ifrom < nextl;)
|
for (ifrom = xlsub(jcol); ifrom < nextl;)
|
||||||
lsub(ito++) = lsub(ifrom++);
|
lsub(ito++) = lsub(ifrom++);
|
||||||
for (i = jcol+1; i <=kcol; i++)xlsub(i) = nextl;
|
for (i = jcol+1; i <=kcol; i++)xlsub(i) = nextl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user