Amesos Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
Amesos_TestDriver.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Amesos: Direct Sparse Solver Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// This library is free software; you can redistribute it and/or modify
11// it under the terms of the GNU Lesser General Public License as
12// published by the Free Software Foundation; either version 2.1 of the
13// License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23// USA
24// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
25//
26// ***********************************************************************
27// @HEADER
28
29//
30// Amesos_TestDriver
31//
32// usage:
33// Amesos_TestDriver.exe Solver InputMatrix MatrixType Special Numsolves Transpose MaxError MaxResid
34// Where solver is: SuperLU, SuperLUdist, SuperLUdist2,
35// UMFPACK, SPOOLES, DSCPACK, DSCPACKOLD, KLU,
36// SPOOLESERIAL, MUMPS, SUPERLU, SCALAPACK or AZTEC
37// special is, at present, only used in SuperLU, where 0 means dgssv
38// and 1 means dgssvx
39// examples:
40// Amesos_TestDriver.exe SPOOLES ImpcolA.rua 0 1 1 0 1e-10 1e-10
41// source SmallTest.csh
42//
43// output:
44// SST.log (append)
45// SST.summary (append)
46//
47// exits with 0 if test completed (does not imply that the test passed)
48// exits with -1 if command line options or file permissions are wrong
49//
50#include "Amesos_ConfigDefs.h"
51#include <stdio.h>
52
54
55// #undef HAVE_TIME_H
56// #undef HAVE_SYS_UTSNAME_H
57
58#ifdef HAVE_TIME_H
59#include <time.h>
60#endif
61//
62// utsname does not work on Paunchy (SunOS) so I disabled this
63//
64#ifdef HAVE_SYS_UTSNAME_WORKS_H
65#include "utsname.h"
66#endif
67
68
69//
70// There is undoubtedly a cleaner way to do this. But, I hope that this
71// will allow this test code to port.
72//
73#ifdef HAVE_IOMANIP
74#include <iomanip>
75#define USE_IOMANP
76#elif defined HAVE_IOMANIP_H
77#include <iomanip.h>
78#define USE_IOMANIP
79#endif
80#ifndef USE_IOMANIP
81#define setw(a) ("")
82#define setprecision(a) ("")
83#endif
84
85#ifdef EPETRA_MPI
86#include "mpi.h"
87#include "Epetra_MpiComm.h"
88#else
89#include "Epetra_SerialComm.h"
90#endif
91
92#include "Epetra_Comm.h"
93
95#include "Amesos_TestSolver.h"
96
97// #ifdef SOLARIS
98// #include <unistd.h>
99// #endif
100
101#if 0
102extern "C" {
103#include "BridgeMPI.h"
104}
105#endif
106
107// #include "TSF.h"
108// using std::exception ;
109
110int main(int argc, char **argv)
111{
112
113 std::vector <double> BBval ;
114 BBval.resize(12);
115 //
116 // The following are the values returned from the tester
117 //
118#ifdef EPETRA_MPI
119 MPI_Init(&argc,&argv);
120 Epetra_MpiComm Comm (MPI_COMM_WORLD);
121#else
122 Epetra_SerialComm Comm;
123#endif
124
125 Epetra_Object::SetTracebackMode( 2 ); // Turns EPETRA_CHK_ERR() on
126 int MyPID = Comm.MyPID();
127 int NumMpiProcs = Comm.NumProc();
128
129#if 0
130 if (MyPID == 0 ) {
131 char junk;
132 std::cin >> junk ; // Wait for character input to give time to attach debuuger
133 }
134#endif
135
136 const int MAX_TOLERANCE_RATIO = 10000 ;
137 int exit_value = 0 ;
138 const int MAXNAMELENGTH = 800;
139
140#ifdef HAVE_SYS_UTSNAME_WORKS_H
141 utsname uname_buf;
142#endif
143 char timebuffer[MAXNAMELENGTH];
144
145 std::string Sprogram ;
146 if ( argc >1 ) Sprogram = argv[1] ;
147 const int NUM_PARAMS = 9 ;
148 const int NUM_SUPERLU_PARAMS = NUM_PARAMS + 1 ;
149 const int NUM_SPOOLES_PARAMS = NUM_PARAMS + 6 ;
150 bool argc_ok = ( argc == NUM_PARAMS ) ;
151 if ( argc == NUM_SPOOLES_PARAMS && Sprogram == "SPOOLES" ) argc_ok = true ;
152 if ( argc == NUM_SPOOLES_PARAMS && Sprogram == "SPOOLESSERIAL" )
153 argc_ok = true ;
154
155 if ( argc == NUM_SUPERLU_PARAMS && Sprogram == "SuperLU" )
156 argc_ok = true ;
157
158//
159// The usage print should be a subroutine and printed everywhere
160// that we find a problem with the command line arguments
161//
162 if ( ! argc_ok ) {
163 if ( MyPID == 0 ) {
164 std::cerr << " argc = " << argc << " Sprogam= " << Sprogram <<
165 " SPOOLES? " << (int) (Sprogram=="SPOOLES") << std::endl ;
166 std::cerr << "Usage: " << argv[0] <<" SolverName InputMatrix special numsolves transpose maxerror maxresid" << std::endl ;
167 std::cerr << " Solvername = UMFPACK, SUPERLUDIST, TAUCS, PARDISO, PARAKLETE, MUMPS, KLU, SUPERLU" << std::endl;
168 std::cerr << " InputMatrix must be a file in Harwell Boeing format"<< std::endl;
169 std::cerr << " special = number of repeats (0 means run just once) " << std::endl ;
170 std::cerr << " numsolves = number of right hand sidess (<0 means MRHS, >1 means BRHS) " << std::endl ;
171 std::cerr << " transpose = 1 means test A^T x = b instead of Ax = b" << std::endl ;
172 std::cerr << " maxerror = maximum allowed error < 0 == no check " << std::endl ;
173 std::cerr << " maxresid = maximum allowed residual < 0 == no check" << std::endl ;
174 std::cerr << " if maxerror == -2 and maxresid == -2, failure (hang or abort) is expected" << std::endl ;
175 std::cerr << " if maxerror == 1e30 and maxresid == 1e30, the solver is expected to finish but produce incorrect results" << std::endl ;
176
177 }
178#ifdef EPETRA_MPI
179 MPI_Finalize();
180#endif
181 exit( -1 ) ;
182 }
183
184 if ( MyPID == 0 ) {
185#ifdef HAVE_SYS_UTSNAME_WORKS_H
186 int uname_stat = uname( &uname_buf ) ;
187#endif
188
189#ifdef HAVE_TIME_H
190 time_t now = time( NULL ) ;
191 tm *localnow = localtime( &now ) ;
192 (void) strftime( timebuffer, MAXNAMELENGTH, "20%g%b%d@%H:%M:%S", localnow ) ;
193#else
194 strcpy( timebuffer, "unknown date" ) ;
195#endif
196 }
197
198 //
199 // Open SST.log and SST.summary
200 //
201 char *ShortOutputFileName = (char *) "SST.summary" ;
202 char *LongOutputFileName = (char *) "SST.log" ;
203
204 bool summary = MyPID == 0 ;
205#ifdef AMESOS_TEST_VERBOSE
206 bool verbose = ( MyPID == 0 ) && true ;
207#else
208 bool verbose = ( MyPID == 0 ) && false ;
209#endif
210 bool log = MyPID == 0 ;
211#ifdef SOLARIS
212 // log = false ; // On Solaris mpich, the second ofstream.open fails
213#endif
214
215 FILE *matrix_fd;
216 std::ofstream summary_file;
217
218 if ( ( MyPID == 0 ) ) {
219 matrix_fd = fopen( argv[2], "r" ) ;
220 if ( matrix_fd == NULL ) {
221 std::cerr << "Unable to open " << argv[2] << " for reading" << std::endl ;
222 exit_value = - 1;
223 } else {
224 fclose( matrix_fd ) ;
225 }
226
227 if ( log ) {
228 SparseDirectTimingVars::log_file.open( LongOutputFileName, std::ios::app ) ;
230 std::cerr << "Unable to open " << LongOutputFileName << " for writing" << std::endl ;
231 exit_value = - 1;
232 }
233 }
234
235 if ( summary ) {
236 summary_file.open( ShortOutputFileName, std::ios::app ) ;
237 if ( summary_file.fail() ) {
238 std::cerr << "Unable to open " << ShortOutputFileName << " for writing" << std::endl ;
239 exit_value = - 1;
240 }
241 }
242 }
243
244 //
245 // Check command line parameters
246 //
247 SparseSolverType SparseSolver ;
248
249 int MatType = atoi( argv[3] ) ;
250 int special = atoi( argv[4] ) ;
251 int numsolves = atoi( argv[5] ) ;
252 int transpose = atoi( argv[6] ) ;
253 double maxerror = atof( argv[7] ) ; // Bump up the error margin for the release (but keep it lower for the dev branch )
254 double maxresid = atof( argv[8] ) ; // Bump up the error margin for the release (but keep it lower for the dev branch )
255
256 if ( Sprogram == "LAPACK" )
257 SparseSolver = LAPACK ;
258 else if ( Sprogram == "KLU" )
259 SparseSolver = KLU ;
260 else if ( Sprogram == "UMFPACK" )
261 SparseSolver = UMFPACK ;
262 else if ( Sprogram == "SUPERLU" )
263 SparseSolver = SUPERLU ;
264 else if ( Sprogram == "SUPERLUDIST" )
265 SparseSolver = SUPERLUDIST ;
266 else if ( Sprogram == "DSCPACK" )
267 SparseSolver = DSCPACK ;
268 else if ( Sprogram == "TAUCS" )
269 SparseSolver = TAUCS ;
270 else if ( Sprogram == "PARDISO" )
271 SparseSolver = PARDISO ;
272 else if ( Sprogram == "PARAKLETE" )
273 SparseSolver = PARAKLETE ;
274 else if ( Sprogram == "MUMPS" )
275 SparseSolver = MUMPS ;
276 else if ( Sprogram == "SCALAPACK" )
277 SparseSolver = SCALAPACK ;
278 else {
279 if (( MyPID == 0 ) ) std::cerr << "Unknown program: " << Sprogram << std::endl ;
280 exit( -1 ) ;
281 }
282
283 // return ok because I don't want to break the tests
284 // if the solver is not available
285#ifndef HAVE_AMESOS_KLU
286 if (SparseSolver == KLU) {
287 std::cerr << "KLU is not installed..." << std::endl;
288 exit(EXIT_SUCCESS);
289 }
290#endif
291#ifndef HAVE_AMESOS_UMFPACK
292 if (SparseSolver == UMFPACK) {
293 std::cerr << "UMFPACK is not installed..." << std::endl;
294 exit(EXIT_SUCCESS);
295 }
296#endif
297#ifndef HAVE_AMESOS_SUPERLU
298 if (SparseSolver == SUPERLU) {
299 std::cerr << "SUPERLU is not installed..." << std::endl;
300 exit(EXIT_SUCCESS);
301 }
302#endif
303#ifndef HAVE_AMESOS_SUPERLUDIST
304 if (SparseSolver == SUPERLUDIST) {
305 std::cerr << "SUPERLUDIST is not installed..." << std::endl;
306 exit(EXIT_SUCCESS);
307 }
308#endif
309#ifndef HAVE_AMESOS_TAUCS
310 if (SparseSolver == TAUCS) {
311 std::cerr << "TAUCS is not installed..." << std::endl;
312 exit(EXIT_SUCCESS);
313 }
314#endif
315#ifndef HAVE_AMESOS_PARDISO
316 if (SparseSolver == PARDISO) {
317 std::cerr << "PARDISO is not installed..." << std::endl;
318 exit(EXIT_SUCCESS);
319 }
320#endif
321#ifndef HAVE_AMESOS_PARAKLETE
322 if (SparseSolver == PARAKLETE) {
323 std::cerr << "PARAKLETE is not installed..." << std::endl;
324 exit(EXIT_SUCCESS);
325 }
326#endif
327#ifndef HAVE_AMESOS_MUMPS
328 if (SparseSolver == MUMPS) {
329 std::cerr << "MUMPS is not installed..." << std::endl;
330 exit(EXIT_SUCCESS);
331 }
332#endif
333#ifndef HAVE_AMESOS_SCALAPACK
334 if (SparseSolver == SCALAPACK) {
335 std::cerr << "SCALAPACK is not installed..." << std::endl;
336 exit(EXIT_SUCCESS);
337 }
338#endif
339#ifndef HAVE_AMESOS_DSCPACK
340 if (SparseSolver == DSCPACK) {
341 std::cerr << "DSCPACK is not installed..." << std::endl;
342 exit(EXIT_SUCCESS);
343 }
344#endif
345
346 SuperLU_permc = 1 ; // Set the default to MMD on A'*A
347 if ( argc == NUM_SUPERLU_PARAMS &&
348 ( Sprogram == "SuperLU" || Sprogram == "SuperLUdist" ) ) {
349 SuperLU_permc = atoi( argv[8] );
350 assert( SuperLU_permc >= 0 && SuperLU_permc <= 3 ) ;
351 }
352
353 const int MaxNumSolves = 3200 ;
354 if ( MatType < 0 || MatType > 1 ) {
355 if ( ( MyPID == 0 ) )
356 std::cerr << " MatType must be 0 or 1, is: "
357 << MatType << std::endl ;
358 exit_value = -1 ;
359 }
360 if ( special < 0 || special > 10000 ) {
361 if ( ( MyPID == 0 ) )
362 std::cerr << " No more than 10000 repeats allowed"
363 << special << std::endl ;
364 exit_value = -1 ;
365 }
366 if ( numsolves< -MaxNumSolves || numsolves > MaxNumSolves ) {
367 if ( ( MyPID == 0 ) )
368 std::cerr << "The number of solves must be between 0 and " << MaxNumSolves
369 << " is: "
370 << numsolves << std::endl ;
371 exit_value = -1 ;
372 }
373 if ( transpose< 0 || transpose > 1) {
374 if ( ( MyPID == 0 ) )
375 std::cerr << "transpose must be 0 (no trans) or 1"
376 << ", it is: "
377 << transpose << std::endl ;
378 exit_value = -1 ;
379 }
380 if ( transpose != 0 && SparseSolver == SUPERLUDIST ) {
381 if ( ( MyPID == 0 ) )
382 std::cerr << "Our use of SUPERLUDIST does not support transpose yet" << std::endl ;
383 exit_value = -1 ;
384 }
385 if ( numsolves != 1 &&
386 SparseSolver != LAPACK &&
387 SparseSolver != SUPERLUDIST &&
388 SparseSolver != DSCPACK &&
389 SparseSolver != UMFPACK &&
390 SparseSolver != KLU &&
391 SparseSolver != TAUCS &&
392 SparseSolver != PARDISO &&
393 SparseSolver != PARAKLETE &&
394 SparseSolver != MUMPS &&
395 SparseSolver != SCALAPACK &&
396 SparseSolver != SUPERLU ) {
397 if ( ( MyPID == 0 ) )
398 std::cerr << "Only LAPACK, SUPERLUDIST, UMFPACK, TAUCS, PARDISO, PARAKLETE, MUMPS, SCALAPACK, KLU and DSCPACK support MRHS and BRHS" << std::endl ;
399 exit_value = -1 ;
400 }
401
402
403#ifdef HAVE_SYS_UTSNAME_WORKS_H
404 char *hostname = uname_buf.nodename ;
405 char *releasenum = uname_buf.release;
406#else
407 char *hostname = (char *) "";
408#endif
409
410
411
412 Comm.Broadcast( &exit_value, 1, 0 ) ;
413
414 if ( exit_value == 0 ) {
415
416 AMESOS_MatrixType MatrixType = AMESOS_Serial ;
417 if ( MatType == 1 ) MatrixType = AMESOS_Distributed ;
418
419 if ( log ) {
420 //
421 // Log time stamp and machine information
422 //
423
424 SparseDirectTimingVars::log_file << std::endl << "TIMESTAMP:" << hostname << " "
425 << argv[1] << " " << timebuffer
426 << " BEGIN RUN" << std::endl ;
427#ifdef HAVE_SYS_UTSNAME_WORKS_H
428 SparseDirectTimingVars::log_file << uname_buf.sysname <<
429 hostname << releasenum << uname_buf.version <<
430 uname_buf.machine << std::endl ;
431#endif
432 }
433 if (summary ) {
434 summary_file << std::endl << setw(12) << hostname << " "
435 << setw(12) << argv[1]
436 << " " << setw(-1) << timebuffer << " "
437 << setw(15) << argv[2] << setw(6) << " "
438 << MatType << " "
439 << special << " "
440 << NumMpiProcs << setw(6) << " "
441 << numsolves << setw(3) << " " << transpose << setprecision(12) ;
442 if ( maxresid == -2 && maxerror == -2 ) summary_file << "Failure OK" ;
443 flush( summary_file ) ;
444 }
445 if (MyPID == 0 ) {
446 if ( verbose ) {
447 std::cerr << std::endl << setw(12) << hostname
448 << setw(12) << argv[1]
449 << " " << setw(-1) << timebuffer
450 << setw(15) << argv[2] << setw(6)
451 << MatType << " "
452 << special << " "
453 << NumMpiProcs << setw(6) << " "
454 << numsolves << setw(3) << " " << transpose << setprecision(12) ;
455 if ( maxresid == -2 && maxerror == -2 ) std::cerr << "Failure OK" ;
456 flush( std::cerr ) ;
457 }
458 }
459 //
460 // Perform the test
461 //
463
464 try {
465
466 if ( numsolves < 0 ) {
467 Amesos_TestMrhsSolver( Comm, argv[2], - numsolves, SparseSolver, (transpose==1), special, MatrixType ) ;
468 } else {
469 if ( numsolves > 1 ) {
470 Amesos_TestMultiSolver( Comm, argv[2], numsolves, SparseSolver, (transpose==1), special, MatrixType ) ;
471 } else {
472 Amesos_TestSolver( Comm, argv[2], SparseSolver, (transpose==1), special, MatrixType ) ;
473 }
474 }
475 //
476 // Log time and memory estimates
477 //
478 if ( log ) {
480
481 //
482 // Print a single line to the summary file (and a copy of same to
483 // the log file (details_fd) then print a final line to the log
484 // file.
485 //
486 SparseDirectTimingVars::log_file << std::endl << "TIMESTAMP:" << hostname
487 << argv[1] << timebuffer
488 << " END RUN" << std::endl ;
489
491 << setw(12) << hostname << setw(9) << argv[1]
492 << " " << setw(-1) << timebuffer
493 << setw(15) << argv[2] << setw(6) << NumMpiProcs << setw(6)
494 << special << " "
495 << numsolves << setw(6)
496 << transpose << setprecision(12) ;
498 SparseDirectTimingVars::log_file << "SS_Result = "
500 << std::endl ;
501
502 }
503 if (summary ) {
505 if ( verbose )
507 bool ErrorOK = maxerror <= -1 ||
509 bool ResidualOK = maxresid <= -1 ||
511 if ( ErrorOK && ResidualOK ) summary_file << " OK" ;
512 if ( ErrorOK && ResidualOK && verbose ) std::cerr << " OK" ;
513 if ( ! ErrorOK ) {
514 summary_file << " Error too large is: " <<
516 " should be < " << maxerror ;
517 std::cerr << " Error too large is: " <<
519 " should be < " << maxerror ;
520 }
521 //
522 // Here we check to see if the answer is better than we expect.
523 //
524 // 1e30 means that the code promises to complete but makes no
525 // promise about the answer
526 // If maxerror is 1e30, we set it to 10, meaning that if the actual
527 // answer is good to 10/ MAX_TOLERANCE_RATIO (presently 10/1000 = .01)
528 // we print a TOLERANCE is too large message.
529 //
530 if (maxerror == 1e30 ) maxerror = 10 ;
531 if (SparseDirectTimingVars::SS_Result.Get_Error() < maxerror / MAX_TOLERANCE_RATIO &&
532 maxerror > 1.1e-14 ) {
533 summary_file << " Error TOLERANCE is too large: " <<
535 " is allowed to be " << maxerror ;
536 if ( verbose ) {
537 std::cerr << " Error TOLERANCE is too large: " <<
539 " is allowed to be " << maxerror ;
540 }
541 }
542 if ( ! ResidualOK ) {
543 summary_file << " Residual too large is:" <<
545 " should be < " << maxresid ;
546 std::cerr << " Residual too large is:" <<
548 " should be < " << maxresid ;
549 }
550
551 if (maxresid == 1e30 ) maxresid = 10 ;
552 if (SparseDirectTimingVars::SS_Result.Get_Residual() < maxresid / MAX_TOLERANCE_RATIO &&
553 maxresid > 1.1e-14 ) {
554 summary_file << " Residual TOLERANCE is too large: " <<
556 " is allowed to be " << maxresid ;
557 if ( verbose ) {
558 std::cerr << " Residual TOLERANCE is too large: " <<
560 " is allowed to be " << maxresid ;
561 }
562 }
563
564 flush( summary_file ) ;
565 if ( verbose ) {
566 std::cerr << std::endl ; // Atlantis won't print anything without this.
567 flush( std::cerr ) ;
568 }
569 }
570 }
571 catch(const std::string &errormsg)
572 {
573 if ( summary ) { summary_file << errormsg ; }
574 if ( log ) SparseDirectTimingVars::log_file << errormsg ;
575 if ( ( verbose ) || summary ) std::cerr << errormsg << std::endl;
576 }
577
578 }
579
580 if ( summary ) summary_file.close() ;
581 if ( log ) SparseDirectTimingVars::log_file.close() ;
582
583#ifdef EPETRA_MPI
584 MPI_Finalize();
585#endif
586 exit( exit_value ) ;
587}
588
589
590
static bool verbose
Definition: Amesos.cpp:67
#define setw(a)
int main(int argc, char **argv)
int SuperLU_permc
#define setprecision(a)
int Amesos_TestMrhsSolver(Epetra_Comm &Comm, char *matrix_file, int numsolves, SparseSolverType SparseSolver, bool transpose, int special, AMESOS_MatrixType matrix_type)
int Amesos_TestMultiSolver(Epetra_Comm &Comm, char *matrix_file, int numsolves, SparseSolverType SparseSolver, bool transpose, int special, AMESOS_MatrixType matrix_type)
int Amesos_TestSolver(Epetra_Comm &Comm, char *matrix_file, SparseSolverType SparseSolver, bool transpose, int special, AMESOS_MatrixType matrix_type)
AMESOS_MatrixType
@ AMESOS_Distributed
@ AMESOS_Serial
SparseSolverType
@ TAUCS
@ PARAKLETE
@ SCALAPACK
@ LAPACK
@ UMFPACK
@ SUPERLUDIST
@ MUMPS
@ KLU
@ DSCPACK
@ SUPERLU
@ PARDISO
static std::ofstream log_file
static SparseSolverResult SS_Result
virtual void PrintSummary(std::ostream &os) const