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");
153 hypre_CSRMatrix * csr_op = hypre_MergeDiagAndOffd(parcsr_op);
155 hypre_CSRMatrixSetDataOwner(csr_op,0);
156 #if MFEM_HYPRE_VERSION >= 21600
161 hypre_CSRMatrixBigJtoJ(csr_op);
164 int m = parcsr_op->global_num_rows;
165 int n = parcsr_op->global_num_cols;
166 int fst_row = parcsr_op->first_row_index;
167 int nnz_loc = csr_op->num_nonzeros;
168 int m_loc = csr_op->num_rows;
173 double * nzval = csr_op->data;
174 int * colind = csr_op->j;
178 if ( !(rowptr = intMalloc_dist(m_loc+1)) )
180 ABORT(
"Malloc fails for rowptr[].");
182 for (
int i=0; i<=m_loc; i++)
184 rowptr[i] = (csr_op->i)[i];
188 hypre_CSRMatrixDestroy(csr_op);
191 dCreate_CompRowLoc_Matrix_dist(A, m, n, nnz_loc, m_loc, fst_row,
192 nzval, colind, rowptr,
193 SLU_NR_loc, SLU_D, SLU_GE);
201 SuperMatrix * A = (SuperMatrix*)rowLocPtr_;
204 Destroy_CompRowLoc_Matrix_dist(A);
207 if ( A != NULL ) {
delete A; }
215 ScalePermstructPtr_(NULL),
217 SOLVEstructPtr_(NULL),
224 firstSolveWithThisA_(false),
225 gridInitialized_(false),
226 LUStructInitialized_(false)
232 : comm_(A.GetComm()),
236 ScalePermstructPtr_(NULL),
238 SOLVEstructPtr_(NULL),
245 firstSolveWithThisA_(true),
246 gridInitialized_(false),
247 LUStructInitialized_(false)
257 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
258 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
262 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
269 ScalePermstructFree(SPstruct);
271 LUstructFree(LUstruct);
274 if ( options->SolveInitialized )
276 dSolveFinalize(options, SOLVEstruct);
279 if ( options != NULL ) {
delete options; }
280 if ( stat != NULL ) {
delete stat; }
281 if ( SPstruct != NULL ) {
delete SPstruct; }
282 if ( LUstruct != NULL ) {
delete LUstruct; }
283 if ( SOLVEstruct != NULL ) {
delete SOLVEstruct; }
284 if ( grid != NULL ) {
delete grid; }
288 void SuperLUSolver::Init()
300 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
301 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
305 ABORT(
"Malloc fails for berr[].");
309 set_default_options_dist(options);
329 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
331 yes_no_t opt = print_stat?YES:NO;
333 options->PrintStat = opt;
338 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
340 yes_no_t opt = equil?YES:NO;
342 options->Equil = opt;
347 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
349 colperm_t opt = (colperm_t)col_perm;
351 options->ColPerm = opt;
357 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
359 rowperm_t opt = (rowperm_t)row_perm;
361 options->RowPerm = opt;
367 mfem_error(
"SuperLUSolver::SetRowPermutation :"
368 " permutation vector not set!");
373 ABORT(
"Malloc fails for perm_r[].");
375 for (
int i=0; i<perm->
Size(); i++)
384 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
386 trans_t opt = (trans_t)trans;
388 options->Trans = opt;
393 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
395 IterRefine_t opt = (IterRefine_t)iter_ref;
397 options->IterRefine = opt;
402 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
404 yes_no_t opt = rtp?YES:NO;
406 options->ReplaceTinyPivot = opt;
411 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
413 options->num_lookaheads = num_lookaheads;
418 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
420 yes_no_t opt = etree?YES:NO;
422 options->lookahead_etree = opt;
427 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
429 yes_no_t opt = sym?YES:NO;
431 options->SymPattern = opt;
436 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
438 yes_no_t opt = par?YES:NO;
440 options->ParSymbFact = opt;
445 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
452 mfem::err <<
"Warning: User specified nprow and npcol are such that "
453 <<
"(nprow * npcol) > numProcs or (nprow * npcol) < 1. "
454 <<
"Using default values for nprow and npcol instead."
477 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
479 superlu_gridexit(grid);
487 MFEM_ASSERT(
APtr_ != NULL,
488 "SuperLU Error: The operator must be set before"
489 " the system can be solved.");
491 superlu_dist_options_t * options = (superlu_dist_options_t*)
optionsPtr_;
492 SuperLUStat_t * stat = (SuperLUStat_t*)
statPtr_;
498 gridinfo_t * grid = (gridinfo_t*)
gridPtr_;
502 options->Fact = FACTORED;
513 SPstruct->DiagScale = NOEQUIL;
523 if ( !(SPstruct->perm_r = intMalloc_dist(A->nrow)) )
525 ABORT(
"Malloc fails for perm_r[].");
528 if ( !(SPstruct->perm_c = intMalloc_dist(A->ncol)) )
530 ABORT(
"Malloc fails for perm_c[].");
533 LUstructInit(A->ncol, LUstruct);
544 int info = -1, locSize = y.
Size();
547 pdgssvx(options, A, SPstruct, yPtr, locSize,
nrhs_, grid,
548 LUstruct, SOLVEstruct,
berr_, stat, &info);
557 MFEM_ABORT(
"SuperLU: SuperLU options are invalid.");
560 MFEM_ABORT(
"SuperLU: Matrix A (in Ax=b) is invalid.");
563 MFEM_ABORT(
"SuperLU: Vector b dimension (in Ax=b) is invalid.");
566 MFEM_ABORT(
"SuperLU: Number of right-hand sides is invalid.");
569 MFEM_ABORT(
"SuperLU: Parameter with index "
570 << -info <<
"invalid. (1-indexed)");
574 else if ( info <= A->ncol )
576 MFEM_ABORT(
"SuperLU: Found a singular matrix, U("
577 << info <<
"," << info <<
") is exactly zero.");
579 else if ( info > A->ncol )
581 MFEM_ABORT(
"SuperLU: Memory allocation error with "
582 << info - A->ncol <<
" bytes already allocated,");
586 MFEM_ABORT(
"Unknown SuperLU Error");
597 mfem_error(
"SuperLUSolver::SetOperator : not SuperLURowLocMatrix!");
616 #endif // MFEM_USE_MPI
617 #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_
void HypreRead() const
Update the internal hypre_ParCSRMatrix object, A, to be in hypre memory space.
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...
void HostRead() const
Update the internal hypre_ParCSRMatrix object, A, to be on host.
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_
void SetParSymbFact(bool par)
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)