Amesos Package Browser (Single Doxygen Collection) Development
Amesos_TestDriver.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 //
00030 //  Amesos_TestDriver 
00031 //
00032 //  usage: 
00033 //     Amesos_TestDriver.exe Solver InputMatrix MatrixType Special Numsolves Transpose MaxError MaxResid 
00034 //     Where solver is:  SuperLU, SuperLUdist, SuperLUdist2, 
00035 //       UMFPACK, SPOOLES, DSCPACK, DSCPACKOLD, KLU, 
00036 //       SPOOLESERIAL, MUMPS, SUPERLU, SCALAPACK or AZTEC 
00037 //     special is, at present, only used in SuperLU, where 0 means dgssv
00038 //     and 1 means dgssvx 
00039 //  examples:
00040 //     Amesos_TestDriver.exe SPOOLES ImpcolA.rua 0 1 1 0 1e-10 1e-10 
00041 //     source SmallTest.csh
00042 //
00043 //  output:  
00044 //    SST.log (append) 
00045 //    SST.summary (append) 
00046 //
00047 //  exits with 0 if test completed (does not imply that the test passed)
00048 //  exits with -1 if command line options or file permissions are wrong 
00049 //
00050 #include "Amesos_ConfigDefs.h"
00051 #include <stdio.h>
00052 
00053   int SuperLU_permc ; 
00054 
00055 // #undef HAVE_TIME_H
00056 // #undef HAVE_SYS_UTSNAME_H
00057 
00058 #ifdef HAVE_TIME_H
00059 #include <time.h>
00060 #endif
00061 //
00062 //  utsname does not work on Paunchy (SunOS) so I disabled this
00063 //
00064 #ifdef HAVE_SYS_UTSNAME_WORKS_H
00065 #include  "utsname.h"
00066 #endif
00067 
00068 
00069 //
00070 //  There is undoubtedly a cleaner way to do this.  But, I hope that this 
00071 //  will allow this test code to port.
00072 //
00073 #ifdef HAVE_IOMANIP
00074 #include <iomanip>
00075 #define USE_IOMANP
00076 #elif defined HAVE_IOMANIP_H
00077 #include <iomanip.h>
00078 #define USE_IOMANIP
00079 #endif
00080 #ifndef USE_IOMANIP
00081 #define setw(a) ("")
00082 #define setprecision(a) ("")
00083 #endif
00084 
00085 #ifdef EPETRA_MPI
00086 #include "mpi.h"
00087 #include "Epetra_MpiComm.h"
00088 #else
00089 #include "Epetra_SerialComm.h"
00090 #endif
00091 
00092 #include "Epetra_Comm.h"
00093 
00094 #include "SparseDirectTimingVars.h"
00095 #include "Amesos_TestSolver.h"
00096 
00097 //  #ifdef SOLARIS
00098 //  #include <unistd.h>
00099 //  #endif
00100 
00101 #if 0
00102 extern "C" {
00103 #include "BridgeMPI.h"
00104 }
00105 #endif
00106 
00107 //  #include "TSF.h"
00108 //  using std::exception ;
00109 
00110 int main(int argc, char **argv)
00111 {
00112 
00113   std::vector <double> BBval ; 
00114   BBval.resize(12);
00115   //
00116   //  The following are the values returned from the tester
00117   //
00118 #ifdef EPETRA_MPI
00119   MPI_Init(&argc,&argv);
00120   Epetra_MpiComm Comm (MPI_COMM_WORLD);
00121 #else
00122   Epetra_SerialComm Comm;
00123 #endif
00124 
00125   Epetra_Object::SetTracebackMode( 2 );   // Turns EPETRA_CHK_ERR() on 
00126   int MyPID = Comm.MyPID();
00127   int NumMpiProcs = Comm.NumProc(); 
00128 
00129 #if 0
00130   if (MyPID == 0 ) {
00131     char junk;
00132     std::cin >> junk ;   // Wait for character input to give time to attach debuuger
00133   }
00134 #endif
00135 
00136   const int MAX_TOLERANCE_RATIO = 10000 ;
00137   int exit_value = 0 ; 
00138   const int MAXNAMELENGTH = 800;
00139 
00140 #ifdef HAVE_SYS_UTSNAME_WORKS_H
00141   utsname uname_buf; 
00142 #endif
00143   char timebuffer[MAXNAMELENGTH];
00144 
00145   std::string Sprogram ;
00146   if ( argc >1 ) Sprogram = argv[1] ;
00147   const int NUM_PARAMS = 9 ; 
00148   const int NUM_SUPERLU_PARAMS = NUM_PARAMS + 1 ; 
00149   const int NUM_SPOOLES_PARAMS = NUM_PARAMS + 6 ; 
00150   bool argc_ok = ( argc == NUM_PARAMS ) ; 
00151   if ( argc == NUM_SPOOLES_PARAMS && Sprogram == "SPOOLES" ) argc_ok = true ; 
00152   if ( argc == NUM_SPOOLES_PARAMS && Sprogram == "SPOOLESSERIAL" ) 
00153     argc_ok = true ; 
00154   
00155   if ( argc == NUM_SUPERLU_PARAMS && Sprogram == "SuperLU" ) 
00156     argc_ok = true ; 
00157 
00158 //
00159 //  The usage print should be a subroutine and printed everywhere 
00160 //  that we find a problem with the command line arguments
00161 //
00162   if ( ! argc_ok ) {
00163     if ( MyPID == 0 ) {
00164       std::cerr << " argc = " << argc << " Sprogam= " << Sprogram << 
00165   " SPOOLES? " << (int) (Sprogram=="SPOOLES") << std::endl ; 
00166       std::cerr << "Usage: " << argv[0] <<" SolverName InputMatrix special numsolves transpose maxerror maxresid" << std::endl ; 
00167       std::cerr << "    Solvername = UMFPACK, SUPERLUDIST, TAUCS, PARDISO, PARAKLETE, MUMPS, KLU, SUPERLU" << std::endl;
00168       std::cerr << "    InputMatrix must be a file in Harwell Boeing format"<< std::endl;
00169       std::cerr << "    special = number of repeats (0 means run just once) " << std::endl ; 
00170       std::cerr << "    numsolves = number of right hand sidess (<0 means MRHS, >1 means BRHS) " << std::endl ; 
00171       std::cerr << "    transpose = 1 means test A^T x = b instead of Ax = b" << std::endl ; 
00172       std::cerr << "    maxerror = maximum allowed error  < 0 == no check " << std::endl ; 
00173       std::cerr << "    maxresid = maximum allowed residual < 0 == no check" << std::endl ; 
00174       std::cerr << "    if maxerror == -2 and maxresid == -2, failure (hang or abort) is expected" << std::endl ; 
00175       std::cerr << "    if maxerror == 1e30 and maxresid == 1e30, the solver is expected to finish but produce incorrect results" << std::endl ; 
00176       
00177     }
00178 #ifdef EPETRA_MPI
00179     MPI_Finalize();
00180 #endif
00181     exit( -1 ) ; 
00182   }
00183  
00184   if ( MyPID == 0 ) {
00185 #ifdef HAVE_SYS_UTSNAME_WORKS_H 
00186     int uname_stat = uname( &uname_buf ) ; 
00187 #endif
00188     
00189 #ifdef HAVE_TIME_H
00190     time_t now = time( NULL ) ; 
00191     tm *localnow = localtime( &now ) ; 
00192     (void) strftime( timebuffer, MAXNAMELENGTH, "20%g%b%d@%H:%M:%S", localnow ) ;
00193 #else
00194     strcpy( timebuffer, "unknown date" ) ; 
00195 #endif
00196   }
00197 
00198   //
00199   //  Open SST.log and SST.summary
00200   //
00201   char *ShortOutputFileName = (char *) "SST.summary" ;
00202   char *LongOutputFileName = (char *) "SST.log" ;
00203 
00204   bool summary = MyPID == 0 ;
00205 #ifdef AMESOS_TEST_VERBOSE
00206   bool verbose = ( MyPID == 0 ) && true ; 
00207 #else
00208   bool verbose = ( MyPID == 0 ) && false ; 
00209 #endif
00210   bool log = MyPID == 0 ; 
00211 #ifdef SOLARIS
00212   //  log = false ;                                     // On Solaris mpich, the second ofstream.open fails 
00213 #endif
00214 
00215   FILE *matrix_fd;
00216   std::ofstream summary_file;
00217 
00218   if ( ( MyPID == 0 )  ) { 
00219     matrix_fd = fopen( argv[2], "r" ) ; 
00220     if ( matrix_fd == NULL ) {
00221       std::cerr << "Unable to open " << argv[2] << " for reading" << std::endl ; 
00222       exit_value = - 1; 
00223     } else {
00224       fclose( matrix_fd ) ; 
00225     }
00226 
00227     if ( log ) { 
00228       SparseDirectTimingVars::log_file.open( LongOutputFileName, std::ios::app ) ; 
00229       if ( SparseDirectTimingVars::log_file.fail() ) {
00230   std::cerr << "Unable to open " << LongOutputFileName << " for writing" << std::endl ; 
00231   exit_value = - 1; 
00232       }
00233     }
00234 
00235     if ( summary ) {
00236       summary_file.open( ShortOutputFileName, std::ios::app ) ; 
00237       if ( summary_file.fail() ) {
00238   std::cerr << "Unable to open " << ShortOutputFileName << " for writing" << std::endl ; 
00239   exit_value = - 1; 
00240       }
00241     }
00242   }
00243 
00244   //
00245   //  Check command line parameters
00246   //
00247   SparseSolverType SparseSolver ; 
00248   
00249   int MatType = atoi( argv[3] ) ; 
00250   int special = atoi( argv[4] ) ; 
00251   int numsolves = atoi( argv[5] ) ; 
00252   int transpose =  atoi( argv[6] ) ; 
00253   double maxerror = atof( argv[7] ) ;    //  Bump up the error margin for the release (but keep it lower for the dev branch )
00254   double maxresid = atof( argv[8] ) ;    //  Bump up the error margin for the release (but keep it lower for the dev branch )
00255 
00256   if  ( Sprogram == "LAPACK" ) 
00257     SparseSolver = LAPACK ; 
00258   else if  ( Sprogram == "KLU" ) 
00259     SparseSolver = KLU ; 
00260   else if ( Sprogram == "UMFPACK" ) 
00261     SparseSolver = UMFPACK ; 
00262   else if  ( Sprogram == "SUPERLU" ) 
00263     SparseSolver = SUPERLU ; 
00264   else if  ( Sprogram == "SUPERLUDIST" ) 
00265     SparseSolver = SUPERLUDIST ; 
00266   else if  ( Sprogram == "DSCPACK" ) 
00267     SparseSolver = DSCPACK ; 
00268   else if  ( Sprogram == "TAUCS" ) 
00269     SparseSolver = TAUCS ; 
00270   else if  ( Sprogram == "PARDISO" ) 
00271     SparseSolver = PARDISO ; 
00272   else if  ( Sprogram == "PARAKLETE" ) 
00273     SparseSolver = PARAKLETE ; 
00274   else if  ( Sprogram == "MUMPS" ) 
00275     SparseSolver = MUMPS ; 
00276   else if  ( Sprogram == "SCALAPACK" ) 
00277     SparseSolver = SCALAPACK ; 
00278   else {
00279     if (( MyPID == 0 ) ) std::cerr << "Unknown program: " << Sprogram << std::endl ; 
00280     exit( -1 ) ; 
00281   }
00282 
00283   // return ok because I don't want to break the tests
00284   // if the solver is not avaiable
00285 #ifndef HAVE_AMESOS_KLU
00286   if (SparseSolver == KLU) {
00287     std::cerr << "KLU is not installed..." << std::endl;
00288     exit(EXIT_SUCCESS);
00289   }
00290 #endif
00291 #ifndef HAVE_AMESOS_UMFPACK
00292   if (SparseSolver == UMFPACK) {
00293     std::cerr << "UMFPACK is not installed..." << std::endl;
00294     exit(EXIT_SUCCESS);
00295   }
00296 #endif
00297 #ifndef HAVE_AMESOS_SUPERLU
00298   if (SparseSolver == SUPERLU) {
00299     std::cerr << "SUPERLU is not installed..." << std::endl;
00300     exit(EXIT_SUCCESS);
00301   }
00302 #endif
00303 #ifndef HAVE_AMESOS_SUPERLUDIST
00304   if (SparseSolver == SUPERLUDIST) {
00305     std::cerr << "SUPERLUDIST is not installed..." << std::endl;
00306     exit(EXIT_SUCCESS);
00307   }
00308 #endif
00309 #ifndef HAVE_AMESOS_TAUCS
00310   if (SparseSolver == TAUCS) {
00311     std::cerr << "TAUCS is not installed..." << std::endl;
00312     exit(EXIT_SUCCESS);
00313   }
00314 #endif
00315 #ifndef HAVE_AMESOS_PARDISO
00316   if (SparseSolver == PARDISO) {
00317     std::cerr << "PARDISO is not installed..." << std::endl;
00318     exit(EXIT_SUCCESS);
00319   }
00320 #endif
00321 #ifndef HAVE_AMESOS_PARAKLETE
00322   if (SparseSolver == PARAKLETE) {
00323     std::cerr << "PARAKLETE is not installed..." << std::endl;
00324     exit(EXIT_SUCCESS);
00325   }
00326 #endif
00327 #ifndef HAVE_AMESOS_MUMPS
00328   if (SparseSolver == MUMPS) {
00329     std::cerr << "MUMPS is not installed..." << std::endl;
00330     exit(EXIT_SUCCESS);
00331   }
00332 #endif
00333 #ifndef HAVE_AMESOS_SCALAPACK
00334   if (SparseSolver == SCALAPACK) {
00335     std::cerr << "SCALAPACK is not installed..." << std::endl;
00336     exit(EXIT_SUCCESS);
00337   }
00338 #endif
00339 #ifndef HAVE_AMESOS_DSCPACK
00340   if (SparseSolver == DSCPACK) {
00341     std::cerr << "DSCPACK is not installed..." << std::endl;
00342     exit(EXIT_SUCCESS);
00343   }
00344 #endif
00345 
00346   SuperLU_permc = 1 ;    // Set the default to MMD on A'*A
00347   if ( argc == NUM_SUPERLU_PARAMS && 
00348        ( Sprogram == "SuperLU" || Sprogram == "SuperLUdist" ) ) { 
00349       SuperLU_permc = atoi( argv[8] );
00350       assert( SuperLU_permc >= 0 && SuperLU_permc <= 3 ) ; 
00351   }
00352 
00353   const int MaxNumSolves = 3200 ; 
00354   if ( MatType < 0 || MatType > 1  ) { 
00355     if ( ( MyPID == 0 )  ) 
00356       std::cerr << " MatType must be 0 or 1, is: " 
00357   << MatType << std::endl ; 
00358     exit_value = -1 ; 
00359   }
00360   if ( special < 0 || special > 10000  ) { 
00361     if ( ( MyPID == 0 )  ) 
00362       std::cerr << " No more than 10000 repeats allowed" 
00363   << special << std::endl ; 
00364     exit_value = -1 ; 
00365   }
00366   if ( numsolves< -MaxNumSolves || numsolves > MaxNumSolves ) { 
00367     if ( ( MyPID == 0 )  ) 
00368       std::cerr << "The number of solves must be between 0 and " << MaxNumSolves 
00369   << " is: "
00370     << numsolves << std::endl ; 
00371     exit_value = -1 ; 
00372   }
00373   if ( transpose< 0 ||  transpose > 1) { 
00374     if ( ( MyPID == 0 )  ) 
00375       std::cerr << "transpose must be 0 (no trans) or 1" 
00376   << ", it is: "
00377     << transpose << std::endl ; 
00378     exit_value = -1 ; 
00379   }
00380   if ( transpose != 0 && SparseSolver == SUPERLUDIST ) { 
00381     if ( ( MyPID == 0 )  ) 
00382       std::cerr << "Our use of SUPERLUDIST does not support transpose yet" << std::endl ;
00383     exit_value = -1 ; 
00384   }
00385   if ( numsolves != 1 && 
00386        SparseSolver != LAPACK  && 
00387        SparseSolver != SUPERLUDIST  && 
00388        SparseSolver != DSCPACK && 
00389        SparseSolver != UMFPACK  && 
00390        SparseSolver != KLU && 
00391        SparseSolver != TAUCS  && 
00392        SparseSolver != PARDISO  && 
00393        SparseSolver != PARAKLETE  && 
00394        SparseSolver != MUMPS  && 
00395        SparseSolver != SCALAPACK  && 
00396        SparseSolver != SUPERLU ) {
00397     if ( ( MyPID == 0 )  ) 
00398       std::cerr << "Only LAPACK, SUPERLUDIST, UMFPACK, TAUCS, PARDISO, PARAKLETE, MUMPS, SCALAPACK, KLU and DSCPACK support MRHS and BRHS" << std::endl ;
00399     exit_value = -1 ; 
00400   }
00401     
00402 
00403 #ifdef HAVE_SYS_UTSNAME_WORKS_H
00404   char *hostname = uname_buf.nodename ; 
00405   char *releasenum = uname_buf.release;
00406 #else
00407   char *hostname = (char *)  "";
00408 #endif
00409   
00410 
00411 
00412  Comm.Broadcast( &exit_value, 1, 0 ) ; 
00413 
00414   if ( exit_value == 0 ) { 
00415 
00416     AMESOS_MatrixType MatrixType = AMESOS_Serial ; 
00417     if ( MatType == 1 ) MatrixType = AMESOS_Distributed ; 
00418 
00419     if ( log ) { 
00420       //
00421       //  Log time stamp and machine information 
00422       //
00423 
00424       SparseDirectTimingVars::log_file << std::endl << "TIMESTAMP:" << hostname << " " 
00425                << argv[1] << " " << timebuffer 
00426                << " BEGIN RUN" << std::endl ; 
00427 #ifdef HAVE_SYS_UTSNAME_WORKS_H     
00428       SparseDirectTimingVars::log_file << uname_buf.sysname << 
00429   hostname << releasenum << uname_buf.version << 
00430     uname_buf.machine << std::endl ;
00431 #endif
00432     }
00433     if (summary ) { 
00434       summary_file << std::endl << setw(12) << hostname << " " 
00435        << setw(12) <<  argv[1] 
00436        << " " << setw(-1) << timebuffer << " " 
00437        << setw(15) << argv[2] << setw(6) << " " 
00438        << MatType << " " 
00439        << special << " " 
00440        << NumMpiProcs <<  setw(6)  << " " 
00441        << numsolves << setw(3) << " " << transpose << setprecision(12) ;
00442       if ( maxresid == -2 && maxerror == -2 ) summary_file << "Failure OK" ; 
00443       flush( summary_file ) ; 
00444     }
00445     if (MyPID == 0 ) { 
00446       if ( verbose ) {
00447   std::cerr << std::endl << setw(12) << hostname
00448        << setw(12) <<  argv[1] 
00449        << " " << setw(-1) << timebuffer
00450        << setw(15) << argv[2] << setw(6)
00451        << MatType << " " 
00452        << special << " " 
00453        << NumMpiProcs <<  setw(6) << " " 
00454        << numsolves << setw(3) << " " << transpose << setprecision(12) ;
00455   if ( maxresid == -2 && maxerror == -2 ) std::cerr << "Failure OK" ; 
00456   flush( std::cerr ) ; 
00457       }
00458     }
00459     //
00460     //  Perform the test
00461     //    
00462     SparseDirectTimingVars::log_file << SparseDirectTimingVars::SS_Result << std::endl ; 
00463 
00464     try { 
00465 
00466   if ( numsolves < 0 ) { 
00467     Amesos_TestMrhsSolver( Comm, argv[2], - numsolves, SparseSolver, (transpose==1), special, MatrixType ) ; 
00468   } else { 
00469     if ( numsolves > 1 ) { 
00470       Amesos_TestMultiSolver( Comm, argv[2], numsolves, SparseSolver, (transpose==1), special, MatrixType ) ; 
00471     } else {
00472       Amesos_TestSolver( Comm, argv[2], SparseSolver, (transpose==1), special, MatrixType ) ; 
00473     }
00474   } 
00475       //
00476       //  Log time and memory estimates
00477       //    
00478       if ( log ) {
00479   SparseDirectTimingVars::log_file << SparseDirectTimingVars::SS_Result << std::endl ; 
00480   
00481   //
00482   //  Print a single line to the summary file (and a copy of same to 
00483   //  the log file (details_fd) then print a final line to the log 
00484   //  file.  
00485   //
00486   SparseDirectTimingVars::log_file << std::endl << "TIMESTAMP:" << hostname 
00487            << argv[1] << timebuffer 
00488            << " END RUN" << std::endl ; 
00489   
00490   SparseDirectTimingVars::log_file 
00491     << setw(12) << hostname << setw(9) <<  argv[1] 
00492     << " " << setw(-1) << timebuffer
00493     << setw(15) << argv[2] << setw(6) <<  NumMpiProcs <<  setw(6) 
00494     << special << " " 
00495     << numsolves << setw(6)
00496     << transpose << setprecision(12) ;
00497   SparseDirectTimingVars::SS_Result.PrintSummary(SparseDirectTimingVars::log_file) ;
00498   SparseDirectTimingVars::log_file << "SS_Result = " 
00499            << SparseDirectTimingVars::SS_Result 
00500            << std::endl ; 
00501 
00502       }
00503       if (summary ) { 
00504   SparseDirectTimingVars::SS_Result.PrintSummary(summary_file) ;
00505   if ( verbose ) 
00506     SparseDirectTimingVars::SS_Result.PrintSummary(std::cerr) ;
00507   bool ErrorOK = maxerror <= -1 ||  
00508     SparseDirectTimingVars::SS_Result.Get_Error() < maxerror ;
00509   bool ResidualOK = maxresid <= -1 ||  
00510     SparseDirectTimingVars::SS_Result.Get_Residual() < maxresid ;
00511   if ( ErrorOK && ResidualOK ) summary_file << " OK" ; 
00512   if ( ErrorOK && ResidualOK && verbose ) std::cerr << " OK" ; 
00513   if ( ! ErrorOK ) {
00514     summary_file << " Error too large is: " << 
00515       SparseDirectTimingVars::SS_Result.Get_Error() <<
00516       " should be < " << maxerror  ; 
00517     std::cerr << " Error too large is: " << 
00518       SparseDirectTimingVars::SS_Result.Get_Error() <<
00519       " should be < " << maxerror  ; 
00520   }
00521   //
00522   //  Here we check to see if the answer is better than we expect.
00523   //
00524   //  1e30 means that the code promises to complete but makes no 
00525   //  promise about the answer
00526   //  If maxerror is 1e30, we set it to 10, meaning that if the actual 
00527   //  answer is good to 10/ MAX_TOLERANCE_RATIO (presently 10/1000 = .01)
00528   //  we print a TOLERANCE is too large message.
00529   //
00530   if (maxerror == 1e30 ) maxerror = 10 ; 
00531   if (SparseDirectTimingVars::SS_Result.Get_Error() < maxerror / MAX_TOLERANCE_RATIO && 
00532       maxerror > 1.1e-14 ) {
00533     summary_file << " Error TOLERANCE is too large: " << 
00534       SparseDirectTimingVars::SS_Result.Get_Error() <<
00535       " is allowed to be " << maxerror  ; 
00536     if ( verbose ) { 
00537       std::cerr << " Error TOLERANCE is too large: " << 
00538         SparseDirectTimingVars::SS_Result.Get_Error() <<
00539         " is allowed to be " << maxerror  ; 
00540     }
00541   }
00542   if ( ! ResidualOK ) {
00543     summary_file << " Residual too large is:" <<
00544       SparseDirectTimingVars::SS_Result.Get_Residual() <<
00545       " should be < " << maxresid  ; 
00546       std::cerr << " Residual too large is:" <<
00547         SparseDirectTimingVars::SS_Result.Get_Residual() <<
00548         " should be < " << maxresid  ; 
00549   }
00550 
00551   if (maxresid == 1e30 ) maxresid = 10 ; 
00552   if (SparseDirectTimingVars::SS_Result.Get_Residual() < maxresid / MAX_TOLERANCE_RATIO && 
00553       maxresid > 1.1e-14 ) {
00554     summary_file << " Residual TOLERANCE is too large: " << 
00555       SparseDirectTimingVars::SS_Result.Get_Residual() <<
00556       " is allowed to be " << maxresid  ; 
00557     if ( verbose ) { 
00558       std::cerr << " Residual TOLERANCE is too large: " << 
00559         SparseDirectTimingVars::SS_Result.Get_Residual() <<
00560         " is allowed to be " << maxresid  ; 
00561     }
00562   }
00563   
00564   flush( summary_file ) ; 
00565   if ( verbose ) { 
00566     std::cerr << std::endl ; // Atlantis won't print anything without this.
00567     flush( std::cerr ) ; 
00568   }
00569       }
00570     }
00571     catch(const std::string &errormsg)
00572       {
00573   if ( summary ) { summary_file << errormsg ; } 
00574   if ( log ) SparseDirectTimingVars::log_file << errormsg ; 
00575   if ( ( verbose )  || summary ) std::cerr << errormsg << std::endl;
00576       }
00577 
00578   }
00579 
00580   if ( summary )   summary_file.close() ; 
00581   if ( log )   SparseDirectTimingVars::log_file.close() ; 
00582 
00583 #ifdef EPETRA_MPI
00584   MPI_Finalize();
00585 #endif
00586   exit( exit_value ) ; 
00587 }
00588 
00589   
00590 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines