12 #include "../config/config.hpp"
14 #ifdef MFEM_USE_SUPERLU
20 #include "superlu_defs.h"
21 #include "superlu_ddefs.h"
23 #if XSDK_INDEX_SIZE == 64
24 #error "SuperLUDist has been built with 64bit integers. This is not supported"
35 unsigned int root = 0;
36 unsigned short len =
sizeof(int); len <<= 2;
37 unsigned short shift = (
unsigned short)((len<<1) - 2);
39 for (
int i=0; i<len; i++)
42 rem = ((rem << 2) + (a_ >> shift));
58 SuperLURowLocMatrix::SuperLURowLocMatrix(MPI_Comm comm,
59 int num_loc_rows,
int first_loc_row,
60 int glob_nrows,
int glob_ncols,
61 int *I,
int *J,
double *data)
70 rowLocPtr_ =
new SuperMatrix;
71 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
77 int nnz_loc = I[num_loc_rows];
78 int m_loc = num_loc_rows;
79 int fst_row = first_loc_row;
81 double * nzval = NULL;
85 if ( !(nzval = doubleMalloc_dist(nnz_loc)) )
87 ABORT(
"Malloc fails for nzval[].");
89 for (
int i=0; i<nnz_loc; i++)
94 if ( !(colind = intMalloc_dist(nnz_loc)) )
96 ABORT(
"Malloc fails for colind[].");
98 for (
int i=0; i<nnz_loc; i++)
103 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
105 ABORT(
"Malloc fails for rowptr[].");
107 for (
int i=0; i<=m_loc; i++)
113 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
114 nzval, colind, rowptr,
115 SLU_NR_loc, SLU_D, SLU_GE);
119 : comm_(hypParMat.GetComm()),
122 rowLocPtr_ =
new SuperMatrix;
123 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
128 hypre_ParCSRMatrix * parcsr_op =
129 (hypre_ParCSRMatrix *)const_cast<HypreParMatrix&>(hypParMat);
131 MFEM_ASSERT(parcsr_op != NULL,
"SuperLU: const_cast failed in SetOperator");
135 hypre_CSRMatrix * csr_op = hypre_MergeDiagAndOffd(parcsr_op);
136 hypre_CSRMatrixSetDataOwner(csr_op,0);
137 #if MFEM_HYPRE_VERSION >= 21600
138 MFEM_VERIFY(csr_op->num_rows < INT_MAX,
"SuperLU: number of local rows "
139 "is too large to store as an integer.");
140 hypre_CSRMatrixBigJtoJ(csr_op);
143 int m = parcsr_op->global_num_rows;
144 int n = parcsr_op->global_num_cols;
145 int fst_row = parcsr_op->first_row_index;
146 int nnz_loc = csr_op->num_nonzeros;
147 int m_loc = csr_op->num_rows;
152 double * nzval = csr_op->data;
153 int * colind = csr_op->j;
157 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
159 ABORT(
"Malloc fails for rowptr[].");
161 for (
int i=0; i<=m_loc; i++)
163 rowptr[i] = (csr_op->i)[i];
167 hypre_CSRMatrixDestroy(csr_op);
170 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
171 nzval, colind, rowptr,
172 SLU_NR_loc, SLU_D, SLU_GE);
177 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
180 Destroy_CompRowLoc_Matrix_dist(A);
183 if ( A != NULL ) {
delete A; }
191 ScalePermstructPtr_(NULL),
193 SOLVEstructPtr_(NULL),
200 firstSolveWithThisA_(false),
201 gridInitialized_(false),
202 LUStructInitialized_(false)
208 : comm_(A.GetComm()),
212 ScalePermstructPtr_(NULL),
214 SOLVEstructPtr_(NULL),
221 firstSolveWithThisA_(true),
222 gridInitialized_(false),
223 LUStructInitialized_(false)
233 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
234 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
238 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
245 ScalePermstructFree(SPstruct);
246 Destroy_LU(
width, grid, LUstruct);
247 LUstructFree(LUstruct);
250 if ( options->SolveInitialized )
252 dSolveFinalize(options, SOLVEstruct);
255 if ( options != NULL ) {
delete options; }
256 if ( stat != NULL ) {
delete stat; }
257 if ( SPstruct != NULL ) {
delete SPstruct; }
258 if ( LUstruct != NULL ) {
delete LUstruct; }
259 if ( SOLVEstruct != NULL ) {
delete SOLVEstruct; }
260 if ( grid != NULL ) {
delete grid; }
264 void SuperLUSolver::Init()
276 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
277 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
281 ABORT(
"Malloc fails for berr[].");
285 set_default_options_dist(options);
287 options->ParSymbFact = YES;
308 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
310 yes_no_t opt = print_stat?YES:NO;
312 options->PrintStat = opt;
317 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
319 yes_no_t opt = equil?YES:NO;
321 options->Equil = opt;
326 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
328 colperm_t opt = (colperm_t)col_perm;
330 options->ColPerm = opt;
336 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
338 rowperm_t opt = (rowperm_t)row_perm;
340 options->RowPerm = opt;
346 mfem_error(
"SuperLUSolver::SetRowPermutation :"
347 " permutation vector not set!");
352 ABORT(
"Malloc fails for perm_r[].");
354 for (
int i=0; i<perm->
Size(); i++)
363 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
365 trans_t opt = (trans_t)trans;
367 options->Trans = opt;
372 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
374 IterRefine_t opt = (IterRefine_t)iter_ref;
376 options->IterRefine = opt;
381 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
383 yes_no_t opt = rtp?YES:NO;
385 options->ReplaceTinyPivot = opt;
390 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
392 options->num_lookaheads = num_lookaheads;
397 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
399 yes_no_t opt = etree?YES:NO;
401 options->lookahead_etree = opt;
406 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
408 yes_no_t opt = sym?YES:NO;
410 options->SymPattern = opt;
415 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
422 mfem::err <<
"Warning: User specified nprow and npcol are such that "
423 <<
"(nprow * npcol) > numProcs or (nprow * npcol) < 1. "
424 <<
"Using default values for nprow and npcol instead."
447 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
449 superlu_gridexit(grid);
457 MFEM_ASSERT(
APtr_ != NULL,
458 "SuperLU Error: The operator must be set before"
459 " the system can be solved.");
461 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
462 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
468 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
472 options->Fact = FACTORED;
483 SPstruct->DiagScale = NOEQUIL;
493 if ( !(SPstruct->perm_r = intMalloc_dist(A->nrow)) )
495 ABORT(
"Malloc fails for perm_r[].");
498 if ( !(SPstruct->perm_c = intMalloc_dist(A->ncol)) )
500 ABORT(
"Malloc fails for perm_c[].");
503 LUstructInit(A->ncol, LUstruct);
512 double* yPtr = (
double*)y;
513 int info = -1, locSize = y.
Size();
516 pdgssvx(options, A, SPstruct, yPtr, locSize,
nrhs_, grid,
517 LUstruct, SOLVEstruct,
berr_, stat, &info);
521 if ( info <= A->ncol )
523 MFEM_ABORT(
"SuperLU: Found a singular matrix, U("
524 << info <<
"," << info <<
") is exactly zero.");
526 else if ( info > A->ncol )
528 MFEM_ABORT(
"SuperLU: Memory allocation error with "
529 << info - A->ncol <<
" bytes already allocated,");
533 MFEM_ABORT(
"Unknown SuperLU Error");
544 mfem_error(
"SuperLUSolver::SetOperator : not SuperLURowLocMatrix!");
563 #endif // MFEM_USE_MPI
564 #endif // MFEM_USE_SUPERLU
int Size() const
Logical size of the array.
void * InternalData() const
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
bool LUStructInitialized_
void * ScalePermstructPtr_
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void SetRowPermutation(superlu::RowPerm row_perm, Array< int > *perm=NULL)
int Size() const
Returns the size of the vector.
void SetSymmetricPattern(bool sym)
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void SetIterativeRefine(superlu::IterRefine iter_ref)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetColumnPermutation(superlu::ColPerm col_perm)
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void SetNumLookAheads(int num_lookaheads)
void SetPrintStatistics(bool print_stat)
void trans(const Vector &x, Vector &p)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
A class to initialize the size of a Tensor.
int height
Dimension of the output / number of rows in the matrix.
void SetLookAheadElimTree(bool etree)
unsigned int sqrti(const unsigned int &a)
void SetReplaceTinyPivot(bool rtp)
void SetTranspose(superlu::Trans trans)
const SuperLURowLocMatrix * APtr_
bool firstSolveWithThisA_
SuperLURowLocMatrix(MPI_Comm comm, int num_loc_rows, int first_loc_row, int glob_nrows, int glob_ncols, int *I, int *J, double *data)
Wrapper for hypre's ParCSR matrix class.
SuperLUSolver(MPI_Comm comm)
int width
Dimension of the input / number of columns in the matrix.
void SetEquilibriate(bool equil)