Amesos Package Browser (Single Doxygen Collection) Development
Amesos_Pardiso.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                Amesos: Direct Sparse Solver Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Amesos_Pardiso.h"
00030 #include "Epetra_Map.h"
00031 #include "Epetra_Import.h"
00032 #include "Epetra_CrsMatrix.h"
00033 #include "Epetra_Vector.h"
00034 #include "Epetra_Util.h"
00035 
00036 #ifdef HAVE_AMESOS_PARDISO_MKL
00037 
00038 #include "mkl_pardiso.h"
00039 #define F77_PARDISO PARDISO
00040 
00041 #else
00042 
00043 #define F77_PARDISOINIT F77_FUNC(pardisoinit, PARDISOINIT)
00044 #define F77_PARDISO F77_FUNC(pardiso, PARDISO)
00045 
00046 /* PARDISO prototype. */
00047 extern "C" int F77_PARDISOINIT
00048     (void *, int *, int *, int *, double *, int *);
00049 
00050 extern "C" int F77_PARDISO
00051     (void *, int *, int *, int *, int *, int *, 
00052      double *, int *, int *, int *, int *, int *, 
00053      int *, double *, double *, int *, double *);
00054 #endif
00055 
00056 #define IPARM(i) iparm_[i-1]
00057 
00058 using namespace Teuchos;
00059 
00060 //=============================================================================
00061 Amesos_Pardiso::Amesos_Pardiso(const Epetra_LinearProblem &prob) :
00062   UseTranspose_(false),
00063   Problem_(&prob),
00064   MtxConvTime_(-1),
00065   MtxRedistTime_(-1),
00066   VecRedistTime_(-1),
00067   SymFactTime_(-1),
00068   NumFactTime_(-1),
00069   SolveTime_(-1),
00070   maxfct_(1),
00071   mnum_(1),
00072   msglvl_(0),
00073   nrhs_(1),
00074   pardiso_initialized_(false)
00075 {
00076   for (int i = 0; i < 64; i++) {
00077     iparm_[i] = 0;
00078   }
00079   iparm_[0] = 1; /* No solver default */
00080   iparm_[1] = 2; /* Fill-in reordering from METIS */
00081   /* Numbers of processors, value of OMP_NUM_THREADS */
00082   iparm_[2] = 1;
00083   iparm_[3] = 0; /* No iterative-direct algorithm */
00084   iparm_[4] = 0; /* No user fill-in reducing permutation */
00085   iparm_[5] = 0; /* Write solution into x */
00086   iparm_[6] = 0; /* Not in use */
00087   iparm_[7] = 0; /* Max numbers of iterative refinement steps */
00088   iparm_[8] = 0; /* Not in use */
00089   iparm_[9] = 13; /* Perturb the pivot elements with 1E-13 */
00090   iparm_[10] = 1; /* Use nonsymmetric permutation and scaling MPS */
00091   iparm_[11] = 0; /* Normal solve (0), or a transpose solve (1) */
00092   iparm_[12] = 0; /* Do not use (non-)symmetric matchings */
00093   iparm_[13] = 0; /* Output: Number of perturbed pivots */
00094   iparm_[14] = 0; /* Peak memory in KB during analysis */
00095   iparm_[15] = 0; /* Permanent mem in KB from anal. that is used in ph 2&3 */
00096   iparm_[16] = 0; /* Peak double prec  mem in KB incl one LU factor */
00097   iparm_[17] = -1; /* Output: Number of nonzeros in the factor LU */
00098   iparm_[18] = -1; /* Output: Mflops for LU factorization */
00099   iparm_[19] = 0; /* Output: Numbers of CG Iterations */
00100 
00101   /* -------------------------------------------------------------------- */
00102   /* .. Initialize the internal solver memory pointer. This is only */
00103   /* necessary for the FIRST call of the PARDISO solver. */
00104   /* -------------------------------------------------------------------- */
00105   for (int i = 0; i < 64; i++) {
00106     pt_[i] = 0;
00107   }
00108 }
00109 
00110 //=============================================================================
00111 Amesos_Pardiso::~Amesos_Pardiso() 
00112 {
00113   int phase = -1;                 /* Release internal memory. */
00114   int error = 0;
00115   int idum;
00116   double ddum;
00117 
00118   if (pardiso_initialized_ ) {
00119     int n = SerialMatrix().NumMyRows();
00120 #ifdef HAVE_AMESOS_PARDISO_MKL
00121     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00122                 &n, &ddum, &ia_[0], &ja_[0], &idum, &nrhs_,
00123                 iparm_, &msglvl_, &ddum, &ddum, &error);
00124 #else
00125     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00126                 &n, &ddum, &ia_[0], &ja_[0], &idum, &nrhs_,
00127                 iparm_, &msglvl_, &ddum, &ddum, &error, dparm_);
00128 #endif
00129   }
00130 
00131   AMESOS_CHK_ERRV(CheckError(error));
00132   // print out some information if required by the user
00133   if ((verbose_ && PrintTiming_) || verbose_ == 2) PrintTiming();
00134   if ((verbose_ && PrintStatus_) || verbose_ == 2) PrintStatus();
00135 }
00136 
00137 //=============================================================================
00138 int Amesos_Pardiso::ConvertToSerial() 
00139 {
00140   ResetTimer();
00141 
00142   int NumGlobalRows = Matrix_->NumGlobalRows();
00143 
00144   // create a serial map
00145   int NumMyRows = 0;
00146   if (Comm().MyPID() == 0) 
00147     NumMyRows = NumGlobalRows;
00148 
00149   SerialMap_ = rcp(new Epetra_Map(-1, NumMyRows, 0, Comm()));
00150   if (SerialMap_.get() == 0)
00151     AMESOS_CHK_ERR(-1);
00152 
00153   Importer_ = rcp(new Epetra_Import(SerialMap(),Map()));
00154   if (Importer_.get() == 0)
00155     AMESOS_CHK_ERR(-1);
00156 
00157   SerialCrsMatrix_ = rcp(new Epetra_CrsMatrix(Copy, SerialMap(), 0));
00158   if (SerialCrsMatrix_.get() == 0)
00159     AMESOS_CHK_ERR(-1);
00160 
00161   AMESOS_CHK_ERR(SerialCrsMatrix().Import(Matrix(), Importer(), Add));
00162 
00163   AMESOS_CHK_ERR(SerialCrsMatrix().FillComplete());
00164 
00165   SerialMatrix_ = rcp(SerialCrsMatrix_.get(), false);
00166 
00167   MtxRedistTime_ = AddTime("Total matrix redistribution time", MtxRedistTime_);
00168 
00169   return 0;
00170 }
00171 
00172 //=============================================================================
00173 int Amesos_Pardiso::ConvertToPardiso()
00174 {
00175   ResetTimer();
00176 
00177   if (Comm().MyPID() == 0) 
00178   {
00179     ia_.resize(SerialMatrix().NumMyRows()+1);
00180     ja_.resize(SerialMatrix().NumMyNonzeros());
00181     aa_.resize(SerialMatrix().NumMyNonzeros());
00182 
00183     int MaxNumEntries = SerialMatrix().MaxNumEntries();
00184     std::vector<int>    Indices(MaxNumEntries);
00185     std::vector<double> Values(MaxNumEntries);
00186 
00187     // Requires FORTRAN numbering (from 1)
00188     ia_[0] = 1;
00189     int count = 0;
00190 
00191     for (int i = 0 ; i < SerialMatrix().NumMyRows() ; ++i)
00192     {
00193       int ierr, NumEntriesThisRow;
00194       ierr = SerialMatrix().ExtractMyRowCopy(i, MaxNumEntries, 
00195                                              NumEntriesThisRow, 
00196                                              &Values[0], &Indices[0]);
00197       if (ierr < 0)
00198         AMESOS_CHK_ERR(ierr);
00199 
00200       ia_[i + 1] = ia_[i] + NumEntriesThisRow;
00201 
00202       for (int j = 0 ; j < NumEntriesThisRow ; ++j)
00203       {
00204         if (Indices[j] == i) 
00205           Values[j] += AddToDiag_;
00206 
00207         ja_[count] = Indices[j] + 1;
00208         aa_[count] = Values[j];
00209         ++count;
00210       }
00211     }
00212     
00213     if (count != SerialMatrix().NumMyNonzeros())
00214       AMESOS_CHK_ERR(-1); // something wrong here
00215   }
00216 
00217   MtxConvTime_ = AddTime("Total matrix conversion time", MtxConvTime_);
00218 
00219   return 0;
00220 }
00221 
00222 //=============================================================================
00223 int Amesos_Pardiso::SetParameters( Teuchos::ParameterList &ParameterList) 
00224 {
00225   // retrive general parameters
00226 
00227   SetStatusParameters( ParameterList );
00228 
00229   SetControlParameters( ParameterList );
00230 
00231   // We fill iparm_ using named parameters
00232   if (ParameterList.isSublist("Pardiso"))
00233   {
00234   param_ = ParameterList.sublist("Pardiso");
00235   }
00236 
00237   msglvl_ = param_.get<int>("Message level", static_cast<int>(debug_));
00238   iparm_[0] = param_.get<int>("No default parameters", 1);
00239   iparm_[1] = param_.get<int>("Use METIS reordering" , 2);
00240   iparm_[2] = param_.get<int>("Number of processors", 1);
00241   iparm_[3] = param_.get<int>("Do preconditioned CGS iterations", 0);
00242   iparm_[4] = param_.get<int>("Use user permutation", 0);
00243   iparm_[5] = param_.get<int>("Solution on X/B", 0);
00244   iparm_[7] = param_.get<int>("Max num of iterative refinement steps", 0);
00245   iparm_[9] = param_.get<int>("Perturbation for pivot elements 10^-k", 13);
00246   iparm_[10] = param_.get<int>("Use (non-)symmetric scaling vectors", 1);
00247   iparm_[11] = param_.get<int>("Solve transposed", 0);
00248   iparm_[12] = param_.get<int>("Use (non-)symmetric matchings", 0);
00249   iparm_[17] = param_.get<int>("Number of non-zeros in LU; -1 to compute", -1);
00250   iparm_[18] = param_.get<int>("Mflops for LU fact; -1 to compute", -1);
00251 
00252   return 0;
00253 }
00254 
00255 //=============================================================================
00256 int Amesos_Pardiso::PerformSymbolicFactorization() 
00257 {
00258   ResetTimer();
00259 
00260   if (Comm().MyPID() == 0) 
00261   {
00262     // at this point only read unsym matrix
00263     mtype_ = 11; 
00264     int error = 0;
00265     int solver = 0;
00266 
00267     // ============================================================== //
00268     // Setup Pardiso control parameters und initialize the solvers    //
00269     // internal adress pointers. This is only necessary for the FIRST //
00270     // call of the PARDISO solver.                                    // 
00271     // The number of processors is specified by IPARM(2), in the      //
00272     // Pardiso sublist.                                               //
00273     // ============================================================== //
00274 #ifndef HAVE_AMESOS_PARDISO_MKL
00275     F77_PARDISOINIT(pt_,  &mtype_, &solver, iparm_, dparm_, &error);
00276 #endif
00277     pardiso_initialized_ = true;
00278 
00279     int num_procs = 1;
00280     char* var = getenv("OMP_NUM_THREADS");
00281     if(var != NULL)
00282       sscanf( var, "%d", &num_procs );
00283     IPARM(3) = num_procs;
00284 
00285     maxfct_ = 1;         /* Maximum number of numerical factorizations.  */
00286     mnum_   = 1;         /* Which factorization to use. */
00287 
00288     int phase = 11; 
00289     error = 0;
00290     int n = SerialMatrix().NumMyRows();
00291     int idum;
00292     double ddum;
00293 
00294 #ifdef HAVE_AMESOS_PARDISO_MKL
00295     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00296                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00297                        iparm_, &msglvl_, &ddum, &ddum, &error);
00298 #else
00299     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00300                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00301                        iparm_, &msglvl_, &ddum, &ddum, &error, dparm_);
00302 #endif
00303     AMESOS_CHK_ERR(CheckError(error));
00304   }
00305 
00306   SymFactTime_ = AddTime("Total symbolic factorization time", SymFactTime_);
00307 
00308   return 0;
00309 }
00310 
00311 //=============================================================================
00312 int Amesos_Pardiso::PerformNumericFactorization( ) 
00313 {
00314   ResetTimer();
00315 
00316   if (Comm().MyPID() == 0) 
00317   {
00318     int phase = 22;
00319     int error;
00320     int n = SerialMatrix().NumMyRows();
00321     int idum;
00322     double ddum;
00323 
00324 #ifdef HAVE_AMESOS_PARDISO_MKL
00325     F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00326                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00327                        iparm_, &msglvl_, &ddum, &ddum, &error);
00328 #else
00329     F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00330                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00331                        iparm_, &msglvl_, &ddum, &ddum, &error, dparm_);
00332 #endif
00333 
00334     AMESOS_CHK_ERR(CheckError(error));
00335   }
00336 
00337   NumFactTime_ = AddTime("Total numeric factorization time", NumFactTime_);
00338 
00339   return 0;
00340 }
00341 
00342 //=============================================================================
00343 bool Amesos_Pardiso::MatrixShapeOK() const 
00344 {
00345   bool OK = true;
00346 
00347   if (GetProblem()->GetOperator()->OperatorRangeMap().NumGlobalPoints() !=
00348       GetProblem()->GetOperator()->OperatorDomainMap().NumGlobalPoints() ) 
00349   {
00350     OK = false;
00351   }
00352   return OK;
00353 }
00354 
00355 //=============================================================================
00356 int Amesos_Pardiso::SymbolicFactorization() 
00357 {
00358   IsSymbolicFactorizationOK_ = false;
00359   IsNumericFactorizationOK_ = false;
00360 
00361   CreateTimer(Comm());
00362 
00363   ++NumSymbolicFact_;
00364 
00365   Matrix_ = dynamic_cast<Epetra_RowMatrix*>(Problem_->GetOperator());
00366   Map_ = &(Matrix_->RowMatrixRowMap());
00367 
00368   // =========================================================== //
00369   // redistribute and create all import/export objects only      //
00370   // if more than one processor is used. Otherwise simply set    //
00371   // dummy pointers to Matrix() and Map(), without giving the    //
00372   // ownership to the smart pointer.                             //
00373   // =========================================================== //
00374 
00375   if (Comm().NumProc() != 1) 
00376     ConvertToSerial();
00377   else
00378   {
00379     SerialMap_ = rcp(const_cast<Epetra_Map*>(&Map()), false);
00380     SerialMatrix_ = rcp(const_cast<Epetra_RowMatrix*>(&Matrix()), false);
00381   }
00382 
00383   // =========================================================== //
00384   // Only on processor zero, convert the matrix into CSR format, //
00385   // as required by PARDISO.                                     //
00386   // =========================================================== //
00387 
00388   ConvertToPardiso();
00389 
00390   PerformSymbolicFactorization();
00391 
00392   IsSymbolicFactorizationOK_ = true;
00393 
00394   return(0);
00395 }
00396 
00397 //=============================================================================
00398 int Amesos_Pardiso::NumericFactorization() 
00399 {
00400   IsNumericFactorizationOK_ = false;
00401 
00402   if (IsSymbolicFactorizationOK_ == false)
00403     AMESOS_CHK_ERR(SymbolicFactorization());
00404 
00405   ++NumNumericFact_;
00406 
00407   // FIXME: this must be checked, now all the matrix is shipped twice here
00408   ConvertToSerial();
00409   ConvertToPardiso();
00410 
00411   PerformNumericFactorization();
00412 
00413   IsNumericFactorizationOK_ = true;
00414 
00415   return(0);
00416 }
00417 
00418 //=============================================================================
00419 int Amesos_Pardiso::Solve() 
00420 {
00421   if (IsNumericFactorizationOK_ == false)
00422     AMESOS_CHK_ERR(NumericFactorization());
00423 
00424   Epetra_MultiVector* X = Problem_->GetLHS();
00425   Epetra_MultiVector* B = Problem_->GetRHS();
00426 
00427   if ((X == 0) || (B == 0))
00428     AMESOS_CHK_ERR(-1); 
00429 
00430   int NumVectors = X->NumVectors();
00431   if (NumVectors != B->NumVectors())
00432     AMESOS_CHK_ERR(-1); 
00433 
00434   // vectors with SerialMap_
00435   Epetra_MultiVector* SerialB;
00436   Epetra_MultiVector* SerialX;
00437 
00438   ResetTimer();
00439 
00440   if (Comm().NumProc() == 1) 
00441   {
00442     SerialB = B;
00443     SerialX = X;
00444   } 
00445   else 
00446   {
00447     SerialX = new Epetra_MultiVector(SerialMap(),NumVectors);
00448     SerialB = new Epetra_MultiVector(SerialMap(),NumVectors);
00449 
00450     SerialB->Import(*B,Importer(),Insert);
00451   }
00452 
00453   VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
00454 
00455   ResetTimer();
00456 
00457   if (Comm().MyPID() == 0) 
00458   {
00459     double* SerialXValues;
00460     double* SerialBValues;
00461     int LDA;
00462 
00463     AMESOS_CHK_ERR(SerialX->ExtractView(&SerialXValues,&LDA));
00464 
00465     // FIXME: check LDA
00466     AMESOS_CHK_ERR(SerialB->ExtractView(&SerialBValues,&LDA));
00467 
00468     int error;
00469     int idum = 0;
00470     int n = SerialMatrix().NumMyRows();
00471     int phase = 33;
00472 
00473     for (int i = 0 ; i < NumVectors ; ++i)
00474 #ifdef HAVE_AMESOS_PARDISO_MKL
00475       F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00476                          &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00477                          iparm_, &msglvl_, 
00478                          SerialBValues + i * n,
00479                          SerialXValues + i * n,
00480                          &error);
00481 #else
00482     F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00483                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00484                        iparm_, &msglvl_,
00485                        SerialBValues + i * n,
00486                        SerialXValues + i * n,
00487                        &error, dparm_);
00488 #endif
00489     AMESOS_CHK_ERR(CheckError(error));
00490   }
00491 
00492   SolveTime_ = AddTime("Total solve time", SolveTime_);
00493 
00494   //  Copy X back to the original vector
00495 
00496   ResetTimer();
00497 
00498   if (Comm().NumProc() != 1) 
00499   {
00500     X->Export(*SerialX, Importer(), Insert);
00501     delete SerialB;
00502     delete SerialX;
00503   } // otherwise we are already in place.
00504 
00505   VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
00506 
00507   if (ComputeTrueResidual_)
00508     ComputeTrueResidual(Matrix(), *X, *B, UseTranspose(), "Amesos_Pardiso");
00509 
00510   if (ComputeVectorNorms_)
00511     ComputeVectorNorms(*X, *B, "Amesos_Pardiso");
00512 
00513   ++NumSolve_;
00514 
00515   return(0) ;
00516 }
00517 
00518 // ====================================================================== 
00519 void Amesos_Pardiso::PrintStatus() const
00520 {
00521   if (Problem_->GetOperator() == 0 || Comm().MyPID() != 0)
00522     return;
00523 
00524   std::string p = "Amesos_Pardiso : ";
00525   PrintLine();
00526 
00527   int n = Matrix().NumGlobalRows();
00528   int nnz = Matrix().NumGlobalNonzeros();
00529 
00530   std::cout << p << "Matrix has " << n << " rows"
00531        << " and " << nnz << " nonzeros" << std::endl;
00532   std::cout << p << "Nonzero elements per row       = "
00533        << 1.0 *  nnz / n << std::endl;
00534   std::cout << p << "Percentage of nonzero elements = "
00535        << 100.0 * nnz /(pow(n,2.0)) << std::endl;
00536   std::cout << p << "Use transpose                  = " << UseTranspose_ << std::endl;
00537   std::cout << p << "Number of performed iterative ref. steps = " << IPARM(9) << std::endl;
00538   std::cout << p << "Peak memory symbolic factorization       = " << IPARM(15) << std::endl;
00539   std::cout << p << "Permanent memory symbolic factorization  = " << IPARM(16) << std::endl;
00540   std::cout << p << "Memory numerical fact. and solution      = " << IPARM(17) << std::endl;
00541   std::cout << p << "Number of nonzeros in factors            = " << IPARM(18) << std::endl;
00542   std::cout << p << "MFlops of factorization                  = " << IPARM(19) << std::endl;
00543   std::cout << p << "CG/CGS diagnostic                        = " << IPARM(20) << std::endl;
00544   std::cout << p << "Inertia: Number of positive eigenvalues  = " << IPARM(22) << std::endl;
00545   std::cout << p << "Inertia: Number of negative eigenvalues  = " << IPARM(23) << std::endl;
00546 
00547   PrintLine();
00548 
00549   return;
00550 }
00551 
00552 // ====================================================================== 
00553 void Amesos_Pardiso::PrintTiming() const
00554 {
00555   if (Problem_->GetOperator() == 0 || Comm().MyPID() != 0)
00556     return;
00557 
00558   double ConTime = GetTime(MtxConvTime_);
00559   double MatTime = GetTime(MtxRedistTime_);
00560   double VecTime = GetTime(VecRedistTime_);
00561   double SymTime = GetTime(SymFactTime_);
00562   double NumTime = GetTime(NumFactTime_);
00563   double SolTime = GetTime(SolveTime_);
00564 
00565   if (NumSymbolicFact_)
00566     SymTime /= NumSymbolicFact_;
00567 
00568   if (NumNumericFact_)
00569     NumTime /= NumNumericFact_;
00570 
00571   if (NumSolve_)
00572     SolTime /= NumSolve_;
00573 
00574   std::string p = "Amesos_Pardiso : ";
00575   PrintLine();
00576 
00577   std::cout << p << "Time to convert matrix to Pardiso format = "
00578        << ConTime << " (s)" << std::endl;
00579   std::cout << p << "Time to redistribute matrix = "
00580        << MatTime << " (s)" << std::endl;
00581   std::cout << p << "Time to redistribute vectors = "
00582        << VecTime << " (s)" << std::endl;
00583   std::cout << p << "Number of symbolic factorizations = "
00584        << NumSymbolicFact_ << std::endl;
00585   std::cout << p << "Time for sym fact = "
00586        << SymTime << " (s), avg = " << SymTime << " (s)" << std::endl;
00587   std::cout << p << "Number of numeric factorizations = "
00588        << NumNumericFact_ << std::endl;
00589   std::cout << p << "Time for num fact = "
00590        << NumTime << " (s), avg = " << NumTime << " (s)" << std::endl;
00591   std::cout << p << "Number of solve phases = "
00592        << NumSolve_ << std::endl;
00593   std::cout << p << "Time for solve = "
00594        << SolTime << " (s), avg = " << SolTime << " (s)" << std::endl;
00595 
00596   PrintLine();
00597 
00598   return;
00599 }
00600 
00601 // ====================================================================== 
00602 int Amesos_Pardiso::CheckError(const int error) const
00603 {
00604   if (!error)
00605     return 0;
00606   
00607   std::cerr << "Amesos: PARDISO returned error code " << error << std::endl;
00608   std::cerr << "Amesos: Related message from manual is:" << std::endl;
00609 
00610   switch(error)
00611   {
00612   case -1:
00613     std::cerr << "Input inconsistent" << std::endl;
00614     break;
00615   case -2:
00616     std::cerr << "Not enough memory" << std::endl;
00617     break;
00618   case -3:
00619     std::cerr << "Reordering problems" << std::endl;
00620     break;
00621   case -4:
00622     std::cerr << "Zero pivot, numerical fact. or iterative refinement problem. " << std::endl;
00623     break;
00624   case -5:
00625     std::cerr << "Unclassified (internal) error" << std::endl;
00626     break;
00627   case -6:
00628     std::cerr << "Preordering failed (matrix types 11, 13 only)" << std::endl;
00629     break;
00630   case -7:
00631     std::cerr << "Diagonal matrix problem." << std::endl;
00632     break;
00633   }
00634 
00635   AMESOS_RETURN(error);
00636 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines