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"
28 #if defined(HYPRE_BIGINT) || defined(HYPRE_MIXEDINT)
29 #error "SuperLUDist support requires HYPRE_BigInt == 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);
199 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
202 Destroy_CompRowLoc_Matrix_dist(A);
205 if ( A != NULL ) {
delete A; }
213 ScalePermstructPtr_(NULL),
215 SOLVEstructPtr_(NULL),
222 firstSolveWithThisA_(false),
223 gridInitialized_(false),
224 LUStructInitialized_(false)
230 : comm_(A.GetComm()),
234 ScalePermstructPtr_(NULL),
236 SOLVEstructPtr_(NULL),
243 firstSolveWithThisA_(true),
244 gridInitialized_(false),
245 LUStructInitialized_(false)
255 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
256 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
260 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
267 ScalePermstructFree(SPstruct);
269 LUstructFree(LUstruct);
272 if ( options->SolveInitialized )
274 dSolveFinalize(options, SOLVEstruct);
277 if ( options != NULL ) {
delete options; }
278 if ( stat != NULL ) {
delete stat; }
279 if ( SPstruct != NULL ) {
delete SPstruct; }
280 if ( LUstruct != NULL ) {
delete LUstruct; }
281 if ( SOLVEstruct != NULL ) {
delete SOLVEstruct; }
282 if ( grid != NULL ) {
delete grid; }
286 void SuperLUSolver::Init()
298 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
299 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
303 ABORT(
"Malloc fails for berr[].");
307 set_default_options_dist(options);
327 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
329 yes_no_t opt = print_stat?YES:NO;
331 options->PrintStat = opt;
336 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
338 yes_no_t opt = equil?YES:NO;
340 options->Equil = opt;
345 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
347 colperm_t opt = (colperm_t)col_perm;
349 options->ColPerm = opt;
355 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
357 rowperm_t opt = (rowperm_t)row_perm;
359 options->RowPerm = opt;
365 mfem_error(
"SuperLUSolver::SetRowPermutation :"
366 " permutation vector not set!");
371 ABORT(
"Malloc fails for perm_r[].");
373 for (
int i=0; i<perm->
Size(); i++)
382 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
384 trans_t opt = (trans_t)trans;
386 options->Trans = opt;
391 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
393 IterRefine_t opt = (IterRefine_t)iter_ref;
395 options->IterRefine = opt;
400 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
402 yes_no_t opt = rtp?YES:NO;
404 options->ReplaceTinyPivot = opt;
409 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
411 options->num_lookaheads = num_lookaheads;
416 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
418 yes_no_t opt = etree?YES:NO;
420 options->lookahead_etree = opt;
425 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
427 yes_no_t opt = sym?YES:NO;
429 options->SymPattern = opt;
434 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
441 mfem::err <<
"Warning: User specified nprow and npcol are such that "
442 <<
"(nprow * npcol) > numProcs or (nprow * npcol) < 1. "
443 <<
"Using default values for nprow and npcol instead."
466 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
468 superlu_gridexit(grid);
476 MFEM_ASSERT(
APtr_ != NULL,
477 "SuperLU Error: The operator must be set before"
478 " the system can be solved.");
480 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
481 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
487 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
491 options->Fact = FACTORED;
502 SPstruct->DiagScale = NOEQUIL;
512 if ( !(SPstruct->perm_r = intMalloc_dist(A->nrow)) )
514 ABORT(
"Malloc fails for perm_r[].");
517 if ( !(SPstruct->perm_c = intMalloc_dist(A->ncol)) )
519 ABORT(
"Malloc fails for perm_c[].");
522 LUstructInit(A->ncol, LUstruct);
533 int info = -1, locSize = y.
Size();
536 pdgssvx(options, A, SPstruct, yPtr, locSize,
nrhs_, grid,
537 LUstruct, SOLVEstruct,
berr_, stat, &info);
546 MFEM_ABORT(
"SuperLU: SuperLU options are invalid.");
549 MFEM_ABORT(
"SuperLU: Matrix A (in Ax=b) is invalid.");
552 MFEM_ABORT(
"SuperLU: Vector b dimension (in Ax=b) is invalid.");
555 MFEM_ABORT(
"SuperLU: Number of right-hand sides is invalid.");
558 MFEM_ABORT(
"SuperLU: Parameter with index "
559 << -info <<
"invalid. (1-indexed)");
563 else if ( info <= A->ncol )
565 MFEM_ABORT(
"SuperLU: Found a singular matrix, U("
566 << info <<
"," << info <<
") is exactly zero.");
568 else if ( info > A->ncol )
570 MFEM_ABORT(
"SuperLU: Memory allocation error with "
571 << info - A->ncol <<
" bytes already allocated,");
575 MFEM_ABORT(
"Unknown SuperLU Error");
586 mfem_error(
"SuperLUSolver::SetOperator : not SuperLURowLocMatrix!");
605 #endif // MFEM_USE_MPI
606 #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.
HYPRE_BigInt GetGlobalNumColumns() const
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)
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
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)
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
int width
Dimension of the input / number of columns in the matrix.
void SetEquilibriate(bool equil)