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 *);
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 *);
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; /* Not in use */
00092   iparm_[12] = 0; /* Not in use */
00093   iparm_[13] = 0; /* Output: Number of perturbed pivots */
00094   iparm_[14] = 0; /* Not in use */
00095   iparm_[15] = 0; /* Not in use */
00096   iparm_[16] = 0; /* Not in use */
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  // iparm_[21] = 1; /* Pivoting for undefinite symmetric matrices */
00101 
00102   /* -------------------------------------------------------------------- */
00103   /* .. Initialize the internal solver memory pointer. This is only */
00104   /* necessary for the FIRST call of the PARDISO solver. */
00105   /* -------------------------------------------------------------------- */
00106   for (int i = 0; i < 64; i++) {
00107     pt_[i] = 0;
00108   }
00109 }
00110 
00111 //=============================================================================
00112 Amesos_Pardiso::~Amesos_Pardiso() 
00113 {
00114   int phase = -1;                 /* Release internal memory. */
00115   int error = 0;
00116   int idum;
00117   double ddum;
00118 
00119   if (pardiso_initialized_ ) {
00120     int n = SerialMatrix().NumMyRows();
00121     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00122                 &n, &ddum, &ia_[0], &ja_[0], &idum, &nrhs_,
00123                 iparm_, &msglvl_, &ddum, &ddum, &error);
00124   }
00125 
00126   AMESOS_CHK_ERRV(CheckError(error));
00127   // print out some information if required by the user
00128   if ((verbose_ && PrintTiming_) || verbose_ == 2) PrintTiming();
00129   if ((verbose_ && PrintStatus_) || verbose_ == 2) PrintStatus();
00130 }
00131 
00132 //=============================================================================
00133 int Amesos_Pardiso::ConvertToSerial() 
00134 {
00135   ResetTimer();
00136 
00137   int NumGlobalRows = Matrix_->NumGlobalRows();
00138 
00139   // create a serial map
00140   int NumMyRows = 0;
00141   if (Comm().MyPID() == 0) 
00142     NumMyRows = NumGlobalRows;
00143 
00144   SerialMap_ = rcp(new Epetra_Map(-1, NumMyRows, 0, Comm()));
00145   if (SerialMap_.get() == 0)
00146     AMESOS_CHK_ERR(-1);
00147 
00148   Importer_ = rcp(new Epetra_Import(SerialMap(),Map()));
00149   if (Importer_.get() == 0)
00150     AMESOS_CHK_ERR(-1);
00151 
00152   SerialCrsMatrix_ = rcp(new Epetra_CrsMatrix(Copy, SerialMap(), 0));
00153   if (SerialCrsMatrix_.get() == 0)
00154     AMESOS_CHK_ERR(-1);
00155 
00156   AMESOS_CHK_ERR(SerialCrsMatrix().Import(Matrix(), Importer(), Add));
00157 
00158   AMESOS_CHK_ERR(SerialCrsMatrix().FillComplete());
00159 
00160   SerialMatrix_ = rcp(SerialCrsMatrix_.get(), false);
00161 
00162   MtxRedistTime_ = AddTime("Total matrix redistribution time", MtxRedistTime_);
00163 
00164   return 0;
00165 }
00166 
00167 //=============================================================================
00168 int Amesos_Pardiso::ConvertToPardiso()
00169 {
00170   ResetTimer();
00171 
00172   if (Comm().MyPID() == 0) 
00173   {
00174     ia_.resize(SerialMatrix().NumMyRows()+1);
00175     ja_.resize(SerialMatrix().NumMyNonzeros());
00176     aa_.resize(SerialMatrix().NumMyNonzeros());
00177 
00178     int MaxNumEntries = SerialMatrix().MaxNumEntries();
00179     std::vector<int>    Indices(MaxNumEntries);
00180     std::vector<double> Values(MaxNumEntries);
00181 
00182     // Requires FORTRAN numbering (from 1)
00183     ia_[0] = 1;
00184     int count = 0;
00185 
00186     for (int i = 0 ; i < SerialMatrix().NumMyRows() ; ++i)
00187     {
00188       int ierr, NumEntriesThisRow;
00189       ierr = SerialMatrix().ExtractMyRowCopy(i, MaxNumEntries, 
00190                                              NumEntriesThisRow, 
00191                                              &Values[0], &Indices[0]);
00192       if (ierr < 0)
00193         AMESOS_CHK_ERR(ierr);
00194 
00195       ia_[i + 1] = ia_[i] + NumEntriesThisRow;
00196 
00197       for (int j = 0 ; j < NumEntriesThisRow ; ++j)
00198       {
00199         if (Indices[j] == i) 
00200           Values[j] += AddToDiag_;
00201 
00202         ja_[count] = Indices[j] + 1;
00203         aa_[count] = Values[j];
00204         ++count;
00205       }
00206     }
00207     
00208     if (count != SerialMatrix().NumMyNonzeros())
00209       AMESOS_CHK_ERR(-1); // something wrong here
00210   }
00211 
00212   MtxConvTime_ = AddTime("Total matrix conversion time", MtxConvTime_);
00213 
00214   return 0;
00215 }
00216 
00217 //=============================================================================
00218 int Amesos_Pardiso::SetParameters( Teuchos::ParameterList &ParameterList) 
00219 {
00220   // retrive general parameters
00221 
00222   SetStatusParameters( ParameterList );
00223 
00224   SetControlParameters( ParameterList );
00225 
00226   // retrive PARDISO's specific parameters
00227 
00228   if (ParameterList.isSublist("pardiso")) 
00229   {
00230     const Teuchos::ParameterList& PardisoList = ParameterList.sublist("Pardiso");
00231 
00232     if (PardisoList.isParameter("MSGLVL"))
00233       msglvl_ = PardisoList.get<int>("MSGLVL");
00234     else
00235       if ( debug_ ) msglvl_ = 1 ; //  msglvl prints statistical information, but is the closest 
00236     //  thing I found to debug print statements - KSS
00237 
00238     if (PardisoList.isParameter("IPARM(1)"))
00239       iparm_[0] = PardisoList.get<int>("IPARM(1)");
00240 
00241     if (PardisoList.isParameter("IPARM(2)"))
00242       iparm_[1] = PardisoList.get<int>("IPARM(2)");
00243 
00244     if (PardisoList.isParameter("IPARM(3)"))
00245       iparm_[2] = PardisoList.get<int>("IPARM(3)");
00246 
00247     if (PardisoList.isParameter("IPARM(4)"))
00248       iparm_[3] = PardisoList.get<int>("IPARM(4)");
00249 
00250     if (PardisoList.isParameter("IPARM(8)"))
00251       iparm_[7] = PardisoList.get<int>("IPARM(8)");
00252 
00253     if (PardisoList.isParameter("IPARM(10)"))
00254       iparm_[9] = PardisoList.get<int>("IPARM(10)");
00255 
00256     if (PardisoList.isParameter("IPARM(11)"))
00257       iparm_[10] = PardisoList.get<int>("IPARM(11)");
00258 
00259     if (PardisoList.isParameter("IPARM(18)"))
00260       iparm_[17] = PardisoList.get<int>("IPARM(18)");
00261 
00262     if (PardisoList.isParameter("IPARM(19)"))
00263       iparm_[18] = PardisoList.get<int>("IPARM(19)");
00264 
00265     if (PardisoList.isParameter("IPARM(21)"))
00266       iparm_[20] = PardisoList.get<int>("IPARM(21)");
00267   }
00268   
00269   return 0;
00270 }
00271 
00272 //=============================================================================
00273 int Amesos_Pardiso::PerformSymbolicFactorization() 
00274 {
00275   ResetTimer();
00276 
00277   if (Comm().MyPID() == 0) 
00278   {
00279     // at this point only read unsym matrix
00280     mtype_ = 11; 
00281 
00282     // ============================================================== //
00283     // Setup Pardiso control parameters und initialize the solvers    //
00284     // internal adress pointers. This is only necessary for the FIRST //
00285     // call of the PARDISO solver.                                    // 
00286     // The number of processors is specified by IPARM(2), in the      //
00287     // Pardiso sublist.                                               //
00288     // ============================================================== //
00289 #ifndef HAVE_AMESOS_PARDISO_MKL
00290     F77_PARDISOINIT(pt_,  &mtype_, iparm_);
00291 #endif
00292     pardiso_initialized_ = true; 
00293 
00294     int num_procs = 1;
00295     char* var = getenv("OMP_NUM_THREADS");
00296     if(var != NULL)
00297       sscanf( var, "%d", &num_procs );
00298     IPARM(3) = num_procs;
00299 
00300     maxfct_ = 1;         /* Maximum number of numerical factorizations.  */
00301     mnum_   = 1;         /* Which factorization to use. */
00302 
00303     int phase = 11; 
00304     int error = 0;
00305     int n = SerialMatrix().NumMyRows();
00306     int idum;
00307     double ddum;
00308 
00309     F77_PARDISO(pt_, &maxfct_, &mnum_, &mtype_, &phase,
00310                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00311                        iparm_, &msglvl_, &ddum, &ddum, &error);
00312 
00313     AMESOS_CHK_ERR(CheckError(error));
00314   }
00315 
00316   SymFactTime_ = AddTime("Total symbolic factorization time", SymFactTime_);
00317 
00318   return 0;
00319 }
00320 
00321 //=============================================================================
00322 int Amesos_Pardiso::PerformNumericFactorization( ) 
00323 {
00324   ResetTimer();
00325 
00326   if (Comm().MyPID() == 0) 
00327   {
00328     int phase = 22;
00329     int error;
00330     int n = SerialMatrix().NumMyRows();
00331     int idum;
00332     double ddum;
00333 
00334     F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00335                        &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00336                        iparm_, &msglvl_, &ddum, &ddum, &error);
00337 
00338     AMESOS_CHK_ERR(CheckError(error));
00339   }
00340 
00341   NumFactTime_ = AddTime("Total numeric factorization time", NumFactTime_);
00342 
00343   return 0;
00344 }
00345 
00346 //=============================================================================
00347 bool Amesos_Pardiso::MatrixShapeOK() const 
00348 {
00349   bool OK = true;
00350 
00351   if (GetProblem()->GetOperator()->OperatorRangeMap().NumGlobalPoints() !=
00352       GetProblem()->GetOperator()->OperatorDomainMap().NumGlobalPoints() ) 
00353   {
00354     OK = false;
00355   }
00356   return OK;
00357 }
00358 
00359 //=============================================================================
00360 int Amesos_Pardiso::SymbolicFactorization() 
00361 {
00362   IsSymbolicFactorizationOK_ = false;
00363   IsNumericFactorizationOK_ = false;
00364 
00365   CreateTimer(Comm());
00366 
00367   ++NumSymbolicFact_;
00368 
00369   Matrix_ = dynamic_cast<Epetra_RowMatrix*>(Problem_->GetOperator());
00370   Map_ = &(Matrix_->RowMatrixRowMap());
00371 
00372   // =========================================================== //
00373   // redistribute and create all import/export objects only      //
00374   // if more than one processor is used. Otherwise simply set    //
00375   // dummy pointers to Matrix() and Map(), without giving the    //
00376   // ownership to the smart pointer.                             //
00377   // =========================================================== //
00378 
00379   if (Comm().NumProc() != 1) 
00380     ConvertToSerial();
00381   else
00382   {
00383     SerialMap_ = rcp(const_cast<Epetra_Map*>(&Map()), false);
00384     SerialMatrix_ = rcp(const_cast<Epetra_RowMatrix*>(&Matrix()), false);
00385   }
00386 
00387   // =========================================================== //
00388   // Only on processor zero, convert the matrix into CSR format, //
00389   // as required by PARDISO.                                     //
00390   // =========================================================== //
00391 
00392   ConvertToPardiso();
00393 
00394   PerformSymbolicFactorization();
00395 
00396   IsSymbolicFactorizationOK_ = true;
00397 
00398   return(0);
00399 }
00400 
00401 //=============================================================================
00402 int Amesos_Pardiso::NumericFactorization() 
00403 {
00404   IsNumericFactorizationOK_ = false;
00405 
00406   if (IsSymbolicFactorizationOK_ == false)
00407     AMESOS_CHK_ERR(SymbolicFactorization());
00408 
00409   ++NumNumericFact_;
00410 
00411   // FIXME: this must be checked, now all the matrix is shipped twice here
00412   ConvertToSerial();
00413   ConvertToPardiso();
00414 
00415   PerformNumericFactorization();
00416 
00417   IsNumericFactorizationOK_ = true;
00418 
00419   return(0);
00420 }
00421 
00422 //=============================================================================
00423 int Amesos_Pardiso::Solve() 
00424 {
00425   if (IsNumericFactorizationOK_ == false)
00426     AMESOS_CHK_ERR(NumericFactorization());
00427 
00428   Epetra_MultiVector* X = Problem_->GetLHS();
00429   Epetra_MultiVector* B = Problem_->GetRHS();
00430 
00431   if ((X == 0) || (B == 0))
00432     AMESOS_CHK_ERR(-1); 
00433 
00434   int NumVectors = X->NumVectors();
00435   if (NumVectors != B->NumVectors())
00436     AMESOS_CHK_ERR(-1); 
00437 
00438   // vectors with SerialMap_
00439   Epetra_MultiVector* SerialB;
00440   Epetra_MultiVector* SerialX;
00441 
00442   ResetTimer();
00443 
00444   if (Comm().NumProc() == 1) 
00445   {
00446     SerialB = B;
00447     SerialX = X;
00448   } 
00449   else 
00450   {
00451     SerialX = new Epetra_MultiVector(SerialMap(),NumVectors);
00452     SerialB = new Epetra_MultiVector(SerialMap(),NumVectors);
00453 
00454     SerialB->Import(*B,Importer(),Insert);
00455   }
00456 
00457   VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
00458 
00459   ResetTimer();
00460 
00461   if (Comm().MyPID() == 0) 
00462   {
00463     double* SerialXValues;
00464     double* SerialBValues;
00465     int LDA;
00466 
00467     AMESOS_CHK_ERR(SerialX->ExtractView(&SerialXValues,&LDA));
00468 
00469     // FIXME: check LDA
00470     AMESOS_CHK_ERR(SerialB->ExtractView(&SerialBValues,&LDA));
00471 
00472     int error;
00473     int idum = 0;
00474     int n = SerialMatrix().NumMyRows();
00475     int phase = 33;
00476 
00477     for (int i = 0 ; i < NumVectors ; ++i)
00478       F77_PARDISO (pt_, &maxfct_, &mnum_, &mtype_, &phase,
00479                          &n, &aa_[0], &ia_[0], &ja_[0], &idum, &nrhs_,
00480                          iparm_, &msglvl_, 
00481                          SerialBValues + i * n,
00482                          SerialXValues + i * n,
00483                          &error);
00484 
00485     AMESOS_CHK_ERR(CheckError(error));
00486   }
00487 
00488   SolveTime_ = AddTime("Total solve time", SolveTime_);
00489 
00490   //  Copy X back to the original vector
00491 
00492   ResetTimer();
00493 
00494   if (Comm().NumProc() != 1) 
00495   {
00496     X->Export(*SerialX, Importer(), Insert);
00497     delete SerialB;
00498     delete SerialX;
00499   } // otherwise we are already in place.
00500 
00501   VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
00502 
00503   if (ComputeTrueResidual_)
00504     ComputeTrueResidual(Matrix(), *X, *B, UseTranspose(), "Amesos_Pardiso");
00505 
00506   if (ComputeVectorNorms_)
00507     ComputeVectorNorms(*X, *B, "Amesos_Pardiso");
00508 
00509   ++NumSolve_;
00510 
00511   return(0) ;
00512 }
00513 
00514 // ====================================================================== 
00515 void Amesos_Pardiso::PrintStatus() const
00516 {
00517   if (Problem_->GetOperator() == 0 || Comm().MyPID() != 0)
00518     return;
00519 
00520   std::string p = "Amesos_Pardiso : ";
00521   PrintLine();
00522 
00523   int n = Matrix().NumGlobalRows();
00524   int nnz = Matrix().NumGlobalNonzeros();
00525 
00526   std::cout << p << "Matrix has " << n << " rows"
00527        << " and " << nnz << " nonzeros" << std::endl;
00528   std::cout << p << "Nonzero elements per row       = "
00529        << 1.0 *  nnz / n << std::endl;
00530   std::cout << p << "Percentage of nonzero elements = "
00531        << 100.0 * nnz /(pow(n,2.0)) << std::endl;
00532   std::cout << p << "Use transpose                  = " << UseTranspose_ << std::endl;
00533   std::cout << p << "Number of performed iterative ref. steps = " << IPARM(9) << std::endl;
00534   std::cout << p << "Peak memory symbolic factorization       = " << IPARM(15) << std::endl;
00535   std::cout << p << "Permanent memory symbolic factorization  = " << IPARM(16) << std::endl;
00536   std::cout << p << "Memory numerical fact. and solution      = " << IPARM(17) << std::endl;
00537   std::cout << p << "Number of nonzeros in factors            = " << IPARM(18) << std::endl;
00538   std::cout << p << "MFlops of factorization                  = " << IPARM(19) << std::endl;
00539   std::cout << p << "CG/CGS diagnostic                        = " << IPARM(20) << std::endl;
00540   std::cout << p << "Inertia: Number of positive eigenvalues  = " << IPARM(22) << std::endl;
00541   std::cout << p << "Inertia: Number of negative eigenvalues  = " << IPARM(23) << std::endl;
00542 
00543   PrintLine();
00544 
00545   return;
00546 }
00547 
00548 // ====================================================================== 
00549 void Amesos_Pardiso::PrintTiming() const
00550 {
00551   if (Problem_->GetOperator() == 0 || Comm().MyPID() != 0)
00552     return;
00553 
00554   double ConTime = GetTime(MtxConvTime_);
00555   double MatTime = GetTime(MtxRedistTime_);
00556   double VecTime = GetTime(VecRedistTime_);
00557   double SymTime = GetTime(SymFactTime_);
00558   double NumTime = GetTime(NumFactTime_);
00559   double SolTime = GetTime(SolveTime_);
00560 
00561   if (NumSymbolicFact_)
00562     SymTime /= NumSymbolicFact_;
00563 
00564   if (NumNumericFact_)
00565     NumTime /= NumNumericFact_;
00566 
00567   if (NumSolve_)
00568     SolTime /= NumSolve_;
00569 
00570   std::string p = "Amesos_Pardiso : ";
00571   PrintLine();
00572 
00573   std::cout << p << "Time to convert matrix to Pardiso format = "
00574        << ConTime << " (s)" << std::endl;
00575   std::cout << p << "Time to redistribute matrix = "
00576        << MatTime << " (s)" << std::endl;
00577   std::cout << p << "Time to redistribute vectors = "
00578        << VecTime << " (s)" << std::endl;
00579   std::cout << p << "Number of symbolic factorizations = "
00580        << NumSymbolicFact_ << std::endl;
00581   std::cout << p << "Time for sym fact = "
00582        << SymTime << " (s), avg = " << SymTime << " (s)" << std::endl;
00583   std::cout << p << "Number of numeric factorizations = "
00584        << NumNumericFact_ << std::endl;
00585   std::cout << p << "Time for num fact = "
00586        << NumTime << " (s), avg = " << NumTime << " (s)" << std::endl;
00587   std::cout << p << "Number of solve phases = "
00588        << NumSolve_ << std::endl;
00589   std::cout << p << "Time for solve = "
00590        << SolTime << " (s), avg = " << SolTime << " (s)" << std::endl;
00591 
00592   PrintLine();
00593 
00594   return;
00595 }
00596 
00597 // ====================================================================== 
00598 int Amesos_Pardiso::CheckError(const int error) const
00599 {
00600   if (!error)
00601     return 0;
00602   
00603   std::cerr << "Amesos: PARDISO returned error code " << error << std::endl;
00604   std::cerr << "Amesos: Related message from manual is:" << std::endl;
00605 
00606   switch(error)
00607   {
00608   case -1:
00609     std::cerr << "Input inconsistent" << std::endl;
00610     break;
00611   case -2:
00612     std::cerr << "Not enough memory" << std::endl;
00613     break;
00614   case -3:
00615     std::cerr << "Reordering problems" << std::endl;
00616     break;
00617   case -4:
00618     std::cerr << "Zero pivot, numerical fact. or iterative refinement problem. " << std::endl;
00619     break;
00620   case -5:
00621     std::cerr << "Unclassified (internal) error" << std::endl;
00622     break;
00623   case -6:
00624     std::cerr << "Preordering failed (matrix types 11, 13 only)" << std::endl;
00625     break;
00626   case -7:
00627     std::cerr << "Diagonal matrix problem." << std::endl;
00628     break;
00629   }
00630 
00631   AMESOS_RETURN(error);
00632 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines