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"
29 #error "SuperLUDist support requires HYPRE_Int == int, for now."
32 #if SUPERLU_DIST_MAJOR_VERSION > 6 || \
33 (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
34 #define ScalePermstruct_t dScalePermstruct_t
35 #define LUstruct_t dLUstruct_t
36 #define SOLVEstruct_t dSOLVEstruct_t
37 #define ScalePermstructFree dScalePermstructFree
38 #define Destroy_LU dDestroy_LU
39 #define LUstructFree dLUstructFree
40 #define LUstructInit dLUstructInit
52 unsigned int root = 0;
53 unsigned short len =
sizeof(int); len <<= 2;
54 unsigned short shift = (
unsigned short)((len<<1) - 2);
56 for (
int i=0; i<len; i++)
59 rem = ((rem << 2) + (a_ >> shift));
75 SuperLURowLocMatrix::SuperLURowLocMatrix(MPI_Comm comm,
76 int num_loc_rows,
int first_loc_row,
77 int glob_nrows,
int glob_ncols,
78 int *I,
int *J,
double *data)
87 rowLocPtr_ =
new SuperMatrix;
88 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
94 int nnz_loc = I[num_loc_rows];
95 int m_loc = num_loc_rows;
96 int fst_row = first_loc_row;
98 double * nzval = NULL;
102 if ( !(nzval = doubleMalloc_dist(nnz_loc)) )
104 ABORT(
"Malloc fails for nzval[].");
106 for (
int i=0; i<nnz_loc; i++)
111 if ( !(colind = intMalloc_dist(nnz_loc)) )
113 ABORT(
"Malloc fails for colind[].");
115 for (
int i=0; i<nnz_loc; i++)
120 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
122 ABORT(
"Malloc fails for rowptr[].");
124 for (
int i=0; i<=m_loc; i++)
130 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
131 nzval, colind, rowptr,
132 SLU_NR_loc, SLU_D, SLU_GE);
136 : comm_(hypParMat.GetComm()),
139 rowLocPtr_ =
new SuperMatrix;
140 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
145 hypre_ParCSRMatrix * parcsr_op =
146 (hypre_ParCSRMatrix *)const_cast<HypreParMatrix&>(hypParMat);
148 MFEM_ASSERT(parcsr_op != NULL,
"SuperLU: const_cast failed in SetOperator");
152 hypre_CSRMatrix * csr_op = hypre_MergeDiagAndOffd(parcsr_op);
153 hypre_CSRMatrixSetDataOwner(csr_op,0);
154 #if MFEM_HYPRE_VERSION >= 21600
159 hypre_CSRMatrixBigJtoJ(csr_op);
162 int m = parcsr_op->global_num_rows;
163 int n = parcsr_op->global_num_cols;
164 int fst_row = parcsr_op->first_row_index;
165 int nnz_loc = csr_op->num_nonzeros;
166 int m_loc = csr_op->num_rows;
171 double * nzval = csr_op->data;
172 int * colind = csr_op->j;
176 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
178 ABORT(
"Malloc fails for rowptr[].");
180 for (
int i=0; i<=m_loc; i++)
182 rowptr[i] = (csr_op->i)[i];
186 hypre_CSRMatrixDestroy(csr_op);
189 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
190 nzval, colind, rowptr,
191 SLU_NR_loc, SLU_D, SLU_GE);
196 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
199 Destroy_CompRowLoc_Matrix_dist(A);
202 if ( A != NULL ) {
delete A; }
210 ScalePermstructPtr_(NULL),
212 SOLVEstructPtr_(NULL),
219 firstSolveWithThisA_(false),
220 gridInitialized_(false),
221 LUStructInitialized_(false)
227 : comm_(A.GetComm()),
231 ScalePermstructPtr_(NULL),
233 SOLVEstructPtr_(NULL),
240 firstSolveWithThisA_(true),
241 gridInitialized_(false),
242 LUStructInitialized_(false)
252 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
253 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
257 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
264 ScalePermstructFree(SPstruct);
265 Destroy_LU(
width, grid, LUstruct);
266 LUstructFree(LUstruct);
269 if ( options->SolveInitialized )
271 dSolveFinalize(options, SOLVEstruct);
274 if ( options != NULL ) {
delete options; }
275 if ( stat != NULL ) {
delete stat; }
276 if ( SPstruct != NULL ) {
delete SPstruct; }
277 if ( LUstruct != NULL ) {
delete LUstruct; }
278 if ( SOLVEstruct != NULL ) {
delete SOLVEstruct; }
279 if ( grid != NULL ) {
delete grid; }
283 void SuperLUSolver::Init()
295 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
296 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
300 ABORT(
"Malloc fails for berr[].");
304 set_default_options_dist(options);
324 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
326 yes_no_t opt = print_stat?YES:NO;
328 options->PrintStat = opt;
333 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
335 yes_no_t opt = equil?YES:NO;
337 options->Equil = opt;
342 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
344 colperm_t opt = (colperm_t)col_perm;
346 options->ColPerm = opt;
352 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
354 rowperm_t opt = (rowperm_t)row_perm;
356 options->RowPerm = opt;
362 mfem_error(
"SuperLUSolver::SetRowPermutation :"
363 " permutation vector not set!");
368 ABORT(
"Malloc fails for perm_r[].");
370 for (
int i=0; i<perm->
Size(); i++)
379 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
381 trans_t opt = (trans_t)trans;
383 options->Trans = opt;
388 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
390 IterRefine_t opt = (IterRefine_t)iter_ref;
392 options->IterRefine = opt;
397 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
399 yes_no_t opt = rtp?YES:NO;
401 options->ReplaceTinyPivot = opt;
406 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
408 options->num_lookaheads = num_lookaheads;
413 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
415 yes_no_t opt = etree?YES:NO;
417 options->lookahead_etree = opt;
422 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
424 yes_no_t opt = sym?YES:NO;
426 options->SymPattern = opt;
431 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
438 mfem::err <<
"Warning: User specified nprow and npcol are such that "
439 <<
"(nprow * npcol) > numProcs or (nprow * npcol) < 1. "
440 <<
"Using default values for nprow and npcol instead."
463 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
465 superlu_gridexit(grid);
473 MFEM_ASSERT(
APtr_ != NULL,
474 "SuperLU Error: The operator must be set before"
475 " the system can be solved.");
477 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
478 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
484 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
488 options->Fact = FACTORED;
499 SPstruct->DiagScale = NOEQUIL;
509 if ( !(SPstruct->perm_r = intMalloc_dist(A->nrow)) )
511 ABORT(
"Malloc fails for perm_r[].");
514 if ( !(SPstruct->perm_c = intMalloc_dist(A->ncol)) )
516 ABORT(
"Malloc fails for perm_c[].");
519 LUstructInit(A->ncol, LUstruct);
528 double* yPtr = (
double*)y;
529 int info = -1, locSize = y.
Size();
532 pdgssvx(options, A, SPstruct, yPtr, locSize,
nrhs_, grid,
533 LUstruct, SOLVEstruct,
berr_, stat, &info);
542 MFEM_ABORT(
"SuperLU: SuperLU options are invalid.");
545 MFEM_ABORT(
"SuperLU: Matrix A (in Ax=b) is invalid.");
548 MFEM_ABORT(
"SuperLU: Vector b dimension (in Ax=b) is invalid.");
551 MFEM_ABORT(
"SuperLU: Number of right-hand sides is invalid.");
554 MFEM_ABORT(
"SuperLU: Parameter with index "
555 << -info <<
"invalid. (1-indexed)");
559 else if ( info <= A->ncol )
561 MFEM_ABORT(
"SuperLU: Found a singular matrix, U("
562 << info <<
"," << info <<
") is exactly zero.");
564 else if ( info > A->ncol )
566 MFEM_ABORT(
"SuperLU: Memory allocation error with "
567 << info - A->ncol <<
" bytes already allocated,");
571 MFEM_ABORT(
"Unknown SuperLU Error");
582 mfem_error(
"SuperLUSolver::SetOperator : not SuperLURowLocMatrix!");
601 #endif // MFEM_USE_MPI
602 #endif // MFEM_USE_SUPERLU
int Size() const
Return the logical size of the array.
void * InternalData() const
void trans(const Vector &u, Vector &x)
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)
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)