|
ScaLAPACK
2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
|
00001 PROGRAM PSLLTDRIVER 00002 * 00003 * -- ScaLAPACK testing driver (version 1.7) -- 00004 * University of Tennessee, Knoxville, Oak Ridge National Laboratory, 00005 * and University of California, Berkeley. 00006 * May 1, 1997 00007 * 00008 * Purpose 00009 * ======= 00010 * 00011 * PSLLTDRIVER is the main test program for the REAL 00012 * ScaLAPACK Cholesky routines. This test driver performs an 00013 * A = L*L**T or A = U**T*U factorization and solve, and optionally 00014 * performs condition estimation and iterative refinement. 00015 * 00016 * The program must be driven by a short data file. An annotated 00017 * example of a data file can be obtained by deleting the first 3 00018 * characters from the following 18 lines: 00019 * 'ScaLAPACK LLt factorization input file' 00020 * 'Intel iPSC/860 hypercube, gamma model.' 00021 * 'LLT.out' output file name (if any) 00022 * 6 device out 00023 * 'U' define Lower or Upper 00024 * 1 number of problems sizes 00025 * 31 100 200 values of N 00026 * 1 number of NB's 00027 * 2 10 24 values of NB 00028 * 1 number of NRHS's 00029 * 1 values of NRHS 00030 * 1 Number of NBRHS's 00031 * 1 values of NBRHS 00032 * 1 number of process grids (ordered pairs of P & Q) 00033 * 2 values of P 00034 * 2 values of Q 00035 * 1.0 threshold 00036 * T (T or F) Test Cond. Est. and Iter. Ref. Routines 00037 * 00038 * 00039 * Internal Parameters 00040 * =================== 00041 * 00042 * TOTMEM INTEGER, default = 2000000 00043 * TOTMEM is a machine-specific parameter indicating the 00044 * maximum amount of available memory in bytes. 00045 * The user should customize TOTMEM to his platform. Remember 00046 * to leave room in memory for the operating system, the BLACS 00047 * buffer, etc. For example, on a system with 8 MB of memory 00048 * per process (e.g., one processor on an Intel iPSC/860), the 00049 * parameters we use are TOTMEM=6200000 (leaving 1.8 MB for OS, 00050 * code, BLACS buffer, etc). However, for PVM, we usually set 00051 * TOTMEM = 2000000. Some experimenting with the maximum value 00052 * of TOTMEM may be required. 00053 * 00054 * INTGSZ INTEGER, default = 4 bytes. 00055 * REALSZ INTEGER, default = 4 bytes. 00056 * INTGSZ and REALSZ indicate the length in bytes on the 00057 * given platform for an integer and a single precision real. 00058 * MEM REAL array, dimension ( TOTMEM / REALSZ ) 00059 * 00060 * All arrays used by SCALAPACK routines are allocated from 00061 * this array and referenced by pointers. The integer IPA, 00062 * for example, is a pointer to the starting element of MEM for 00063 * the matrix A. 00064 * 00065 * ===================================================================== 00066 * 00067 * .. Parameters .. 00068 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_, 00069 $ LLD_, MB_, M_, NB_, N_, RSRC_ 00070 PARAMETER ( BLOCK_CYCLIC_2D = 1, DLEN_ = 9, DTYPE_ = 1, 00071 $ CTXT_ = 2, M_ = 3, N_ = 4, MB_ = 5, NB_ = 6, 00072 $ RSRC_ = 7, CSRC_ = 8, LLD_ = 9 ) 00073 INTEGER INTGSZ, MEMSIZ, NTESTS, REALSZ, TOTMEM 00074 REAL PADVAL, ZERO 00075 PARAMETER ( INTGSZ = 4, REALSZ = 4, TOTMEM = 2000000, 00076 $ MEMSIZ = TOTMEM / REALSZ, NTESTS = 20, 00077 $ PADVAL = -9923.0E+0, ZERO = 0.0E+0 ) 00078 * .. 00079 * .. Local Scalars .. 00080 LOGICAL CHECK, EST 00081 CHARACTER UPLO 00082 CHARACTER*6 PASSED 00083 CHARACTER*80 OUTFILE 00084 INTEGER HH, I, IAM, IASEED, IBSEED, ICTXT, IMIDPAD, 00085 $ INFO, IPA, IPA0, IPB, IPB0, IPBERR, IPFERR, 00086 $ IPREPAD, IPOSTPAD, IPW, IPW2, ITEMP, J, K, 00087 $ KFAIL, KK, KPASS, KSKIP, KTESTS, LCM, LCMQ, 00088 $ LIWORK, LWORK, LW2, MYCOL, MYRHS, MYROW, N, NB, 00089 $ NBRHS, NGRIDS, NMAT, NNB, NNBR, NNR, NOUT, NP, 00090 $ NPCOL, NPROCS, NPROW, NQ, NRHS, WORKSIZ 00091 REAL ANORM, ANORM1, FRESID, RCOND, SRESID, SRESID2, 00092 $ THRESH 00093 DOUBLE PRECISION NOPS, TMFLOPS 00094 * .. 00095 * .. Local Arrays .. 00096 INTEGER DESCA( DLEN_ ), DESCB( DLEN_ ), IERR( 1 ), 00097 $ NBRVAL( NTESTS ), NBVAL( NTESTS ), 00098 $ NRVAL( NTESTS ), NVAL( NTESTS ), 00099 $ PVAL( NTESTS ), QVAL( NTESTS ) 00100 REAL MEM( MEMSIZ ) 00101 DOUBLE PRECISION CTIME( 2 ), WTIME( 2 ) 00102 * .. 00103 * .. External Subroutines .. 00104 EXTERNAL BLACS_BARRIER, BLACS_EXIT, BLACS_GRIDEXIT, 00105 $ BLACS_GRIDINFO, BLACS_GRIDINIT, DESCINIT, 00106 $ IGSUM2D, BLACS_PINFO, PSCHEKPAD, PSFILLPAD, 00107 $ PSLAFCHK, PSLASCHK, PSLLTINFO, 00108 $ PSMATGEN, PSPOCON, PSPORFS, 00109 $ PSPOTRF, PSPOTRRV, PSPOTRS, SLBOOT, 00110 $ SLCOMBINE, SLTIMER 00111 * .. 00112 * .. External Functions .. 00113 LOGICAL LSAME 00114 INTEGER ICEIL, ILCM, NUMROC 00115 REAL PSLANSY 00116 EXTERNAL ICEIL, ILCM, LSAME, NUMROC, PSLANSY 00117 * .. 00118 * .. Intrinsic Functions .. 00119 INTRINSIC DBLE, MAX, MIN 00120 * .. 00121 * .. Data Statements .. 00122 DATA KFAIL, KPASS, KSKIP, KTESTS / 4*0 / 00123 * .. 00124 * .. Executable Statements .. 00125 * 00126 * Get starting information 00127 * 00128 CALL BLACS_PINFO( IAM, NPROCS ) 00129 IASEED = 100 00130 IBSEED = 200 00131 CALL PSLLTINFO( OUTFILE, NOUT, UPLO, NMAT, NVAL, NTESTS, NNB, 00132 $ NBVAL, NTESTS, NNR, NRVAL, NTESTS, NNBR, NBRVAL, 00133 $ NTESTS, NGRIDS, PVAL, NTESTS, QVAL, NTESTS, 00134 $ THRESH, EST, MEM, IAM, NPROCS ) 00135 CHECK = ( THRESH.GE.0.0E+0 ) 00136 * 00137 * Print headings 00138 * 00139 IF( IAM.EQ.0 ) THEN 00140 WRITE( NOUT, FMT = * ) 00141 WRITE( NOUT, FMT = 9995 ) 00142 WRITE( NOUT, FMT = 9994 ) 00143 WRITE( NOUT, FMT = * ) 00144 END IF 00145 * 00146 * Loop over different process grids 00147 * 00148 DO 50 I = 1, NGRIDS 00149 * 00150 NPROW = PVAL( I ) 00151 NPCOL = QVAL( I ) 00152 * 00153 * Make sure grid information is correct 00154 * 00155 IERR( 1 ) = 0 00156 IF( NPROW.LT.1 ) THEN 00157 IF( IAM.EQ.0 ) 00158 $ WRITE( NOUT, FMT = 9999 ) 'GRID', 'nprow', NPROW 00159 IERR( 1 ) = 1 00160 ELSE IF( NPCOL.LT.1 ) THEN 00161 IF( IAM.EQ.0 ) 00162 $ WRITE( NOUT, FMT = 9999 ) 'GRID', 'npcol', NPCOL 00163 IERR( 1 ) = 1 00164 ELSE IF( NPROW*NPCOL.GT.NPROCS ) THEN 00165 IF( IAM.EQ.0 ) 00166 $ WRITE( NOUT, FMT = 9998 ) NPROW*NPCOL, NPROCS 00167 IERR( 1 ) = 1 00168 END IF 00169 * 00170 IF( IERR( 1 ).GT.0 ) THEN 00171 IF( IAM.EQ.0 ) 00172 $ WRITE( NOUT, FMT = 9997 ) 'grid' 00173 KSKIP = KSKIP + 1 00174 GO TO 50 00175 END IF 00176 * 00177 * Define process grid 00178 * 00179 CALL BLACS_GET( -1, 0, ICTXT ) 00180 CALL BLACS_GRIDINIT( ICTXT, 'Row-major', NPROW, NPCOL ) 00181 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL ) 00182 * 00183 * Go to bottom of process grid loop if this case doesn't use my 00184 * process 00185 * 00186 IF( MYROW.GE.NPROW .OR. MYCOL.GE.NPCOL ) 00187 $ GO TO 50 00188 * 00189 DO 40 J = 1, NMAT 00190 * 00191 N = NVAL( J ) 00192 * 00193 * Make sure matrix information is correct 00194 * 00195 IERR( 1 ) = 0 00196 IF( N.LT.1 ) THEN 00197 IF( IAM.EQ.0 ) 00198 $ WRITE( NOUT, FMT = 9999 ) 'MATRIX', 'N', N 00199 IERR( 1 ) = 1 00200 ELSE IF( N.LT.1 ) THEN 00201 IF( IAM.EQ.0 ) 00202 $ WRITE( NOUT, FMT = 9999 ) 'MATRIX', 'N', N 00203 IERR( 1 ) = 1 00204 END IF 00205 * 00206 * Check all processes for an error 00207 * 00208 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 ) 00209 * 00210 IF( IERR( 1 ).GT.0 ) THEN 00211 IF( IAM.EQ.0 ) 00212 $ WRITE( NOUT, FMT = 9997 ) 'matrix' 00213 KSKIP = KSKIP + 1 00214 GO TO 40 00215 END IF 00216 * 00217 DO 30 K = 1, NNB 00218 * 00219 NB = NBVAL( K ) 00220 * 00221 * Make sure nb is legal 00222 * 00223 IERR( 1 ) = 0 00224 IF( NB.LT.1 ) THEN 00225 IERR( 1 ) = 1 00226 IF( IAM.EQ.0 ) 00227 $ WRITE( NOUT, FMT = 9999 ) 'NB', 'NB', NB 00228 END IF 00229 * 00230 * Check all processes for an error 00231 * 00232 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 ) 00233 * 00234 IF( IERR( 1 ).GT.0 ) THEN 00235 IF( IAM.EQ.0 ) 00236 $ WRITE( NOUT, FMT = 9997 ) 'NB' 00237 KSKIP = KSKIP + 1 00238 GO TO 30 00239 END IF 00240 * 00241 * Padding constants 00242 * 00243 NP = NUMROC( N, NB, MYROW, 0, NPROW ) 00244 NQ = NUMROC( N, NB, MYCOL, 0, NPCOL ) 00245 IF( CHECK ) THEN 00246 IPREPAD = MAX( NB, NP ) 00247 IMIDPAD = NB 00248 IPOSTPAD = MAX( NB, NQ ) 00249 ELSE 00250 IPREPAD = 0 00251 IMIDPAD = 0 00252 IPOSTPAD = 0 00253 END IF 00254 * 00255 * Initialize the array descriptor for the matrix A 00256 * 00257 CALL DESCINIT( DESCA, N, N, NB, NB, 0, 0, ICTXT, 00258 $ MAX( 1, NP )+IMIDPAD, IERR( 1 ) ) 00259 * 00260 * Check all processes for an error 00261 * 00262 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 ) 00263 * 00264 IF( IERR( 1 ).LT.0 ) THEN 00265 IF( IAM.EQ.0 ) 00266 $ WRITE( NOUT, FMT = 9997 ) 'descriptor' 00267 KSKIP = KSKIP + 1 00268 GO TO 30 00269 END IF 00270 * 00271 * Assign pointers into MEM for SCALAPACK arrays, A is 00272 * allocated starting at position MEM( IPREPAD+1 ) 00273 * 00274 IPA = IPREPAD+1 00275 IF( EST ) THEN 00276 IPA0 = IPA + DESCA( LLD_ )*NQ + IPOSTPAD + IPREPAD 00277 IPW = IPA0 + DESCA( LLD_ )*NQ + IPOSTPAD + IPREPAD 00278 ELSE 00279 IPW = IPA + DESCA( LLD_ )*NQ + IPOSTPAD + IPREPAD 00280 END IF 00281 * 00282 * 00283 IF( CHECK ) THEN 00284 * 00285 * Calculate the amount of workspace required by 00286 * the checking routines PSLAFCHK, PSPOTRRV, and 00287 * PSLANSY 00288 * 00289 WORKSIZ = NP * DESCA( NB_ ) 00290 * 00291 WORKSIZ = MAX( WORKSIZ, DESCA( MB_ ) * DESCA( NB_ ) ) 00292 * 00293 LCM = ILCM( NPROW, NPCOL ) 00294 ITEMP = MAX( 2, 2 * NQ ) + NP 00295 IF( NPROW.NE.NPCOL ) THEN 00296 ITEMP = ITEMP + 00297 $ NB * ICEIL( ICEIL( NP, NB ), LCM / NPROW ) 00298 END IF 00299 WORKSIZ = MAX( WORKSIZ, ITEMP ) 00300 WORKSIZ = WORKSIZ + IPOSTPAD 00301 * 00302 ELSE 00303 * 00304 WORKSIZ = IPOSTPAD 00305 * 00306 END IF 00307 * 00308 * Check for adequate memory for problem size 00309 * 00310 IERR( 1 ) = 0 00311 IF( IPW+WORKSIZ.GT.MEMSIZ ) THEN 00312 IF( IAM.EQ.0 ) 00313 $ WRITE( NOUT, FMT = 9996 ) 'factorization', 00314 $ ( IPW+WORKSIZ )*REALSZ 00315 IERR( 1 ) = 1 00316 END IF 00317 * 00318 * Check all processes for an error 00319 * 00320 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 ) 00321 * 00322 IF( IERR( 1 ).GT.0 ) THEN 00323 IF( IAM.EQ.0 ) 00324 $ WRITE( NOUT, FMT = 9997 ) 'MEMORY' 00325 KSKIP = KSKIP + 1 00326 GO TO 30 00327 END IF 00328 * 00329 * Generate a symmetric positive definite matrix A 00330 * 00331 CALL PSMATGEN( ICTXT, 'Symm', 'Diag', DESCA( M_ ), 00332 $ DESCA( N_ ), DESCA( MB_ ), DESCA( NB_ ), 00333 $ MEM( IPA ), DESCA( LLD_ ), DESCA( RSRC_ ), 00334 $ DESCA( CSRC_ ), IASEED, 0, NP, 0, NQ, 00335 $ MYROW, MYCOL, NPROW, NPCOL ) 00336 * 00337 * Calculate inf-norm of A for residual error-checking 00338 * 00339 IF( CHECK ) THEN 00340 CALL PSFILLPAD( ICTXT, NP, NQ, MEM( IPA-IPREPAD ), 00341 $ DESCA( LLD_ ), IPREPAD, IPOSTPAD, 00342 $ PADVAL ) 00343 CALL PSFILLPAD( ICTXT, WORKSIZ-IPOSTPAD, 1, 00344 $ MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD, 00345 $ IPREPAD, IPOSTPAD, PADVAL ) 00346 ANORM = PSLANSY( 'I', UPLO, N, MEM( IPA ), 1, 1, 00347 $ DESCA, MEM( IPW ) ) 00348 ANORM1 = PSLANSY( '1', UPLO, N, MEM( IPA ), 1, 1, 00349 $ DESCA, MEM( IPW ) ) 00350 CALL PSCHEKPAD( ICTXT, 'PSLANSY', NP, NQ, 00351 $ MEM( IPA-IPREPAD ), DESCA( LLD_ ), 00352 $ IPREPAD, IPOSTPAD, PADVAL ) 00353 CALL PSCHEKPAD( ICTXT, 'PSLANSY', 00354 $ WORKSIZ-IPOSTPAD, 1, 00355 $ MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD, 00356 $ IPREPAD, IPOSTPAD, PADVAL ) 00357 END IF 00358 * 00359 IF( EST ) THEN 00360 CALL PSMATGEN( ICTXT, 'Symm', 'Diag', DESCA( M_ ), 00361 $ DESCA( N_ ), DESCA( MB_ ), 00362 $ DESCA( NB_ ), MEM( IPA0 ), 00363 $ DESCA( LLD_ ), DESCA( RSRC_ ), 00364 $ DESCA( CSRC_ ), IASEED, 0, NP, 0, NQ, 00365 $ MYROW, MYCOL, NPROW, NPCOL ) 00366 IF( CHECK ) 00367 $ CALL PSFILLPAD( ICTXT, NP, NQ, 00368 $ MEM( IPA0-IPREPAD ), DESCA( LLD_ ), 00369 $ IPREPAD, IPOSTPAD, PADVAL ) 00370 END IF 00371 * 00372 CALL SLBOOT() 00373 CALL BLACS_BARRIER( ICTXT, 'All' ) 00374 * 00375 * Perform LLt factorization 00376 * 00377 CALL SLTIMER( 1 ) 00378 * 00379 CALL PSPOTRF( UPLO, N, MEM( IPA ), 1, 1, DESCA, INFO ) 00380 * 00381 CALL SLTIMER( 1 ) 00382 * 00383 IF( INFO.NE.0 ) THEN 00384 IF( IAM.EQ.0 ) 00385 $ WRITE( NOUT, FMT = * ) 'PSPOTRF INFO=', INFO 00386 KFAIL = KFAIL + 1 00387 RCOND = ZERO 00388 GO TO 60 00389 END IF 00390 * 00391 IF( CHECK ) THEN 00392 * 00393 * Check for memory overwrite in LLt factorization 00394 * 00395 CALL PSCHEKPAD( ICTXT, 'PSPOTRF', NP, NQ, 00396 $ MEM( IPA-IPREPAD ), DESCA( LLD_ ), 00397 $ IPREPAD, IPOSTPAD, PADVAL ) 00398 END IF 00399 * 00400 IF( EST ) THEN 00401 * 00402 * Calculate workspace required for PSPOCON 00403 * 00404 LWORK = MAX( 1, 2*NP ) + MAX( 1, 2*NQ ) + 00405 $ MAX( 2, DESCA( NB_ )* 00406 $ MAX( 1, ICEIL( NPROW-1, NPCOL ) ), 00407 $ NQ + DESCA( NB_ )* 00408 $ MAX( 1, ICEIL( NPCOL-1, NPROW ) ) ) 00409 IPW2 = IPW + LWORK + IPOSTPAD + IPREPAD 00410 LIWORK = MAX( 1, NP ) 00411 LW2 = ICEIL( LIWORK*INTGSZ, REALSZ ) + IPOSTPAD 00412 * 00413 IERR( 1 ) = 0 00414 IF( IPW2+LW2.GT.MEMSIZ ) THEN 00415 IF( IAM.EQ.0 ) 00416 $ WRITE( NOUT, FMT = 9996 )'cond est', 00417 $ ( IPW2+LW2 )*REALSZ 00418 IERR( 1 ) = 1 00419 END IF 00420 * 00421 * Check all processes for an error 00422 * 00423 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, 00424 $ -1, 0 ) 00425 * 00426 IF( IERR( 1 ).GT.0 ) THEN 00427 IF( IAM.EQ.0 ) 00428 $ WRITE( NOUT, FMT = 9997 ) 'MEMORY' 00429 KSKIP = KSKIP + 1 00430 GO TO 60 00431 END IF 00432 * 00433 IF( CHECK ) THEN 00434 CALL PSFILLPAD( ICTXT, LWORK, 1, 00435 $ MEM( IPW-IPREPAD ), LWORK, 00436 $ IPREPAD, IPOSTPAD, PADVAL ) 00437 CALL PSFILLPAD( ICTXT, LW2-IPOSTPAD, 1, 00438 $ MEM( IPW2-IPREPAD ), 00439 $ LW2-IPOSTPAD, IPREPAD, 00440 $ IPOSTPAD, PADVAL ) 00441 END IF 00442 * 00443 * Compute condition number of the matrix 00444 * 00445 CALL PSPOCON( UPLO, N, MEM( IPA ), 1, 1, DESCA, 00446 $ ANORM1, RCOND, MEM( IPW ), LWORK, 00447 $ MEM( IPW2 ), LIWORK, INFO ) 00448 * 00449 IF( CHECK ) THEN 00450 CALL PSCHEKPAD( ICTXT, 'PSPOCON', NP, NQ, 00451 $ MEM( IPA-IPREPAD ), DESCA( LLD_ ), 00452 $ IPREPAD, IPOSTPAD, PADVAL ) 00453 CALL PSCHEKPAD( ICTXT, 'PSPOCON', 00454 $ LWORK, 1, MEM( IPW-IPREPAD ), 00455 $ LWORK, IPREPAD, IPOSTPAD, 00456 $ PADVAL ) 00457 CALL PSCHEKPAD( ICTXT, 'PSPOCON', 00458 $ LW2-IPOSTPAD, 1, 00459 $ MEM( IPW2-IPREPAD ), LW2-IPOSTPAD, 00460 $ IPREPAD, IPOSTPAD, PADVAL ) 00461 END IF 00462 END IF 00463 * 00464 * Loop over the different values for NRHS 00465 * 00466 DO 20 HH = 1, NNR 00467 * 00468 NRHS = NRVAL( HH ) 00469 * 00470 DO 10 KK = 1, NNBR 00471 * 00472 NBRHS = NBRVAL( KK ) 00473 * 00474 * Initialize Array Descriptor for rhs 00475 * 00476 CALL DESCINIT( DESCB, N, NRHS, NB, NBRHS, 0, 0, 00477 $ ICTXT, MAX( 1, NP )+IMIDPAD, 00478 $ IERR( 1 ) ) 00479 * 00480 * move IPW to allow room for RHS 00481 * 00482 MYRHS = NUMROC( DESCB( N_ ), DESCB( NB_ ), MYCOL, 00483 $ DESCB( CSRC_ ), NPCOL ) 00484 IPB = IPW 00485 * 00486 IF( EST ) THEN 00487 IPB0 = IPB + DESCB( LLD_ )*MYRHS + IPOSTPAD + 00488 $ IPREPAD 00489 IPFERR = IPB0 + DESCB( LLD_ )*MYRHS + IPOSTPAD 00490 $ + IPREPAD 00491 IPBERR = MYRHS + IPFERR + IPOSTPAD + IPREPAD 00492 IPW = MYRHS + IPBERR + IPOSTPAD + IPREPAD 00493 ELSE 00494 IPW = IPB + DESCB( LLD_ )*MYRHS + IPOSTPAD + 00495 $ IPREPAD 00496 END IF 00497 * 00498 IF( CHECK ) THEN 00499 * 00500 * Calculate the amount of workspace required by 00501 * the checking routines PSLASCHK 00502 * 00503 LCMQ = LCM / NPCOL 00504 WORKSIZ = MAX( WORKSIZ-IPOSTPAD, 00505 $ NQ * NBRHS + NP * NBRHS + 00506 $ MAX( MAX( NQ*NB, 2*NBRHS ), 00507 $ NBRHS * NUMROC( NUMROC(N,NB,0,0,NPCOL),NB, 00508 $ 0,0,LCMQ ) ) ) 00509 WORKSIZ = IPOSTPAD + WORKSIZ 00510 ELSE 00511 WORKSIZ = IPOSTPAD 00512 END IF 00513 * 00514 IERR( 1 ) = 0 00515 IF( IPW+WORKSIZ.GT.MEMSIZ ) THEN 00516 IF( IAM.EQ.0 ) 00517 $ WRITE( NOUT, FMT = 9996 )'solve', 00518 $ ( IPW+WORKSIZ )*REALSZ 00519 IERR( 1 ) = 1 00520 END IF 00521 * 00522 * Check all processes for an error 00523 * 00524 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, 00525 $ -1, 0 ) 00526 * 00527 IF( IERR( 1 ).GT.0 ) THEN 00528 IF( IAM.EQ.0 ) 00529 $ WRITE( NOUT, FMT = 9997 ) 'MEMORY' 00530 KSKIP = KSKIP + 1 00531 GO TO 10 00532 END IF 00533 * 00534 * Generate RHS 00535 * 00536 CALL PSMATGEN( ICTXT, 'No', 'No', DESCB( M_ ), 00537 $ DESCB( N_ ), DESCB( MB_ ), 00538 $ DESCB( NB_ ), MEM( IPB ), 00539 $ DESCB( LLD_ ), DESCB( RSRC_ ), 00540 $ DESCB( CSRC_ ), IBSEED, 0, NP, 0, 00541 $ MYRHS, MYROW, MYCOL, NPROW, NPCOL ) 00542 * 00543 IF( CHECK ) 00544 $ CALL PSFILLPAD( ICTXT, NP, MYRHS, 00545 $ MEM( IPB-IPREPAD ), 00546 $ DESCB( LLD_ ), 00547 $ IPREPAD, IPOSTPAD, PADVAL ) 00548 * 00549 IF( EST ) THEN 00550 CALL PSMATGEN( ICTXT, 'No', 'No', DESCB( M_ ), 00551 $ DESCB( N_ ), DESCB( MB_ ), 00552 $ DESCB( NB_ ), MEM( IPB0 ), 00553 $ DESCB( LLD_ ), DESCB( RSRC_ ), 00554 $ DESCB( CSRC_ ), IBSEED, 0, NP, 0, 00555 $ MYRHS, MYROW, MYCOL, NPROW, 00556 $ NPCOL ) 00557 * 00558 IF( CHECK ) THEN 00559 CALL PSFILLPAD( ICTXT, NP, MYRHS, 00560 $ MEM( IPB0-IPREPAD ), 00561 $ DESCB( LLD_ ), IPREPAD, 00562 $ IPOSTPAD, PADVAL ) 00563 CALL PSFILLPAD( ICTXT, 1, MYRHS, 00564 $ MEM( IPFERR-IPREPAD ), 1, 00565 $ IPREPAD, IPOSTPAD, 00566 $ PADVAL ) 00567 CALL PSFILLPAD( ICTXT, 1, MYRHS, 00568 $ MEM( IPBERR-IPREPAD ), 1, 00569 $ IPREPAD, IPOSTPAD, 00570 $ PADVAL ) 00571 END IF 00572 END IF 00573 * 00574 CALL BLACS_BARRIER( ICTXT, 'All' ) 00575 CALL SLTIMER( 2 ) 00576 * 00577 * Solve linear system via Cholesky factorization 00578 * 00579 CALL PSPOTRS( UPLO, N, NRHS, MEM( IPA ), 1, 1, 00580 $ DESCA, MEM( IPB ), 1, 1, DESCB, 00581 $ INFO ) 00582 * 00583 CALL SLTIMER( 2 ) 00584 * 00585 IF( CHECK ) THEN 00586 * 00587 * check for memory overwrite 00588 * 00589 CALL PSCHEKPAD( ICTXT, 'PSPOTRS', NP, NQ, 00590 $ MEM( IPA-IPREPAD ), 00591 $ DESCA( LLD_ ), 00592 $ IPREPAD, IPOSTPAD, PADVAL ) 00593 CALL PSCHEKPAD( ICTXT, 'PSPOTRS', NP, 00594 $ MYRHS, MEM( IPB-IPREPAD ), 00595 $ DESCB( LLD_ ), IPREPAD, 00596 $ IPOSTPAD, PADVAL ) 00597 * 00598 CALL PSFILLPAD( ICTXT, WORKSIZ-IPOSTPAD, 1, 00599 $ MEM( IPW-IPREPAD ), 00600 $ WORKSIZ-IPOSTPAD, IPREPAD, 00601 $ IPOSTPAD, PADVAL ) 00602 * 00603 * check the solution to rhs 00604 * 00605 CALL PSLASCHK( 'Symm', 'Diag', N, NRHS, 00606 $ MEM( IPB ), 1, 1, DESCB, 00607 $ IASEED, 1, 1, DESCA, IBSEED, 00608 $ ANORM, SRESID, MEM( IPW ) ) 00609 * 00610 IF( IAM.EQ.0 .AND. SRESID.GT.THRESH ) 00611 $ WRITE( NOUT, FMT = 9985 ) SRESID 00612 * 00613 * check for memory overwrite 00614 * 00615 CALL PSCHEKPAD( ICTXT, 'PSLASCHK', NP, 00616 $ MYRHS, MEM( IPB-IPREPAD ), 00617 $ DESCB( LLD_ ), IPREPAD, 00618 $ IPOSTPAD, PADVAL ) 00619 CALL PSCHEKPAD( ICTXT, 'PSLASCHK', 00620 $ WORKSIZ-IPOSTPAD, 1, 00621 $ MEM( IPW-IPREPAD ), 00622 $ WORKSIZ-IPOSTPAD, IPREPAD, 00623 $ IPOSTPAD, PADVAL ) 00624 * 00625 * The second test is a NaN trap 00626 * 00627 IF( ( SRESID.LE.THRESH ).AND. 00628 $ ( (SRESID-SRESID).EQ.0.0E+0 ) ) THEN 00629 KPASS = KPASS + 1 00630 PASSED = 'PASSED' 00631 ELSE 00632 KFAIL = KFAIL + 1 00633 PASSED = 'FAILED' 00634 END IF 00635 ELSE 00636 KPASS = KPASS + 1 00637 SRESID = SRESID - SRESID 00638 PASSED = 'BYPASS' 00639 END IF 00640 * 00641 IF( EST ) THEN 00642 * 00643 * Calculate workspace required for PSPORFS 00644 * 00645 LWORK = MAX( 1, 3*NP ) 00646 IPW2 = IPW + LWORK + IPOSTPAD + IPREPAD 00647 LIWORK = MAX( 1, NP ) 00648 LW2 = ICEIL( LIWORK*INTGSZ, REALSZ ) + 00649 $ IPOSTPAD 00650 * 00651 IERR( 1 ) = 0 00652 IF( IPW2+LW2.GT.MEMSIZ ) THEN 00653 IF( IAM.EQ.0 ) 00654 $ WRITE( NOUT, FMT = 9996 ) 00655 $ 'iter ref', ( IPW2+LW2 )*REALSZ 00656 IERR( 1 ) = 1 00657 END IF 00658 * 00659 * Check all processes for an error 00660 * 00661 CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 00662 $ 1, -1, 0 ) 00663 * 00664 IF( IERR( 1 ).GT.0 ) THEN 00665 IF( IAM.EQ.0 ) 00666 $ WRITE( NOUT, FMT = 9997 ) 00667 $ 'MEMORY' 00668 KSKIP = KSKIP + 1 00669 GO TO 10 00670 END IF 00671 * 00672 IF( CHECK ) THEN 00673 CALL PSFILLPAD( ICTXT, LWORK, 1, 00674 $ MEM( IPW-IPREPAD ), 00675 $ LWORK, IPREPAD, IPOSTPAD, 00676 $ PADVAL ) 00677 CALL PSFILLPAD( ICTXT, LW2-IPOSTPAD, 00678 $ 1, MEM( IPW2-IPREPAD ), 00679 $ LW2-IPOSTPAD, 00680 $ IPREPAD, IPOSTPAD, 00681 $ PADVAL ) 00682 END IF 00683 * 00684 * Use iterative refinement to improve the 00685 * computed solution 00686 * 00687 CALL PSPORFS( UPLO, N, NRHS, MEM( IPA0 ), 00688 $ 1, 1, DESCA, MEM( IPA ), 1, 1, 00689 $ DESCA, MEM( IPB0 ), 1, 1, 00690 $ DESCB, MEM( IPB ), 1, 1, DESCB, 00691 $ MEM( IPFERR ), MEM( IPBERR ), 00692 $ MEM( IPW ), LWORK, MEM( IPW2 ), 00693 $ LIWORK, INFO ) 00694 * 00695 * check for memory overwrite 00696 * 00697 IF( CHECK ) THEN 00698 CALL PSCHEKPAD( ICTXT, 'PSPORFS', NP, 00699 $ NQ, MEM( IPA0-IPREPAD ), 00700 $ DESCA( LLD_ ), IPREPAD, 00701 $ IPOSTPAD, PADVAL ) 00702 CALL PSCHEKPAD( ICTXT, 'PSPORFS', NP, 00703 $ NQ, MEM( IPA-IPREPAD ), 00704 $ DESCA( LLD_ ), IPREPAD, 00705 $ IPOSTPAD, PADVAL ) 00706 CALL PSCHEKPAD( ICTXT, 'PSPORFS', NP, 00707 $ MYRHS, MEM( IPB-IPREPAD ), 00708 $ DESCB( LLD_ ), IPREPAD, 00709 $ IPOSTPAD, PADVAL ) 00710 CALL PSCHEKPAD( ICTXT, 'PSPORFS', NP, 00711 $ MYRHS, 00712 $ MEM( IPB0-IPREPAD ), 00713 $ DESCB( LLD_ ), IPREPAD, 00714 $ IPOSTPAD, PADVAL ) 00715 CALL PSCHEKPAD( ICTXT, 'PSPORFS', 1, 00716 $ MYRHS, 00717 $ MEM( IPFERR-IPREPAD ), 1, 00718 $ IPREPAD, IPOSTPAD, 00719 $ PADVAL ) 00720 CALL PSCHEKPAD( ICTXT, 'PSPORFS', 1, 00721 $ MYRHS, 00722 $ MEM( IPBERR-IPREPAD ), 1, 00723 $ IPREPAD, IPOSTPAD, 00724 $ PADVAL ) 00725 CALL PSCHEKPAD( ICTXT, 'PSPORFS', LWORK, 00726 $ 1, MEM( IPW-IPREPAD ), 00727 $ LWORK, IPREPAD, IPOSTPAD, 00728 $ PADVAL ) 00729 CALL PSCHEKPAD( ICTXT, 'PSPORFS', 00730 $ LW2-IPOSTPAD, 1, 00731 $ MEM( IPW2-IPREPAD ), 00732 $ LW2-IPOSTPAD, 00733 $ IPREPAD, IPOSTPAD, 00734 $ PADVAL ) 00735 * 00736 CALL PSFILLPAD( ICTXT, WORKSIZ-IPOSTPAD, 00737 $ 1, MEM( IPW-IPREPAD ), 00738 $ WORKSIZ-IPOSTPAD, IPREPAD, 00739 $ IPOSTPAD, PADVAL ) 00740 * 00741 * check the solution to rhs 00742 * 00743 CALL PSLASCHK( 'Symm', 'Diag', N, NRHS, 00744 $ MEM( IPB ), 1, 1, DESCB, 00745 $ IASEED, 1, 1, DESCA, 00746 $ IBSEED, ANORM, SRESID2, 00747 $ MEM( IPW ) ) 00748 * 00749 IF( IAM.EQ.0 .AND. SRESID2.GT.THRESH ) 00750 $ WRITE( NOUT, FMT = 9985 ) SRESID2 00751 * 00752 * check for memory overwrite 00753 * 00754 CALL PSCHEKPAD( ICTXT, 'PSLASCHK', NP, 00755 $ MYRHS, MEM( IPB-IPREPAD ), 00756 $ DESCB( LLD_ ), IPREPAD, 00757 $ IPOSTPAD, PADVAL ) 00758 CALL PSCHEKPAD( ICTXT, 'PSLASCHK', 00759 $ WORKSIZ-IPOSTPAD, 1, 00760 $ MEM( IPW-IPREPAD ), 00761 $ WORKSIZ-IPOSTPAD, 00762 $ IPREPAD, IPOSTPAD, 00763 $ PADVAL ) 00764 END IF 00765 END IF 00766 * 00767 * Gather maximum of all CPU and WALL clock timings 00768 * 00769 CALL SLCOMBINE( ICTXT, 'All', '>', 'W', 2, 1, 00770 $ WTIME ) 00771 CALL SLCOMBINE( ICTXT, 'All', '>', 'C', 2, 1, 00772 $ CTIME ) 00773 * 00774 * Print results 00775 * 00776 IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN 00777 * 00778 * 1/3 N^3 + 1/2 N^2 flops for LLt factorization 00779 * 00780 NOPS = (DBLE(N)**3)/3.0D+0 + 00781 $ (DBLE(N)**2)/2.0D+0 00782 * 00783 * nrhs * 2 N^2 flops for LLt solve. 00784 * 00785 NOPS = NOPS + 2.0D+0*(DBLE(N)**2)*DBLE(NRHS) 00786 * 00787 * Calculate total megaflops -- factorization and 00788 * solve -- for WALL and CPU time, and print output 00789 * 00790 * Print WALL time if machine supports it 00791 * 00792 IF( WTIME( 1 ) + WTIME( 2 ) .GT. 0.0D+0 ) THEN 00793 TMFLOPS = NOPS / 00794 $ ( ( WTIME( 1 )+WTIME( 2 ) ) * 1.0D+6 ) 00795 ELSE 00796 TMFLOPS = 0.0D+0 00797 END IF 00798 * 00799 IF( WTIME( 2 ).GE.0.0D+0 ) 00800 $ WRITE( NOUT, FMT = 9993 ) 'WALL', UPLO, N, 00801 $ NB, NRHS, NBRHS, NPROW, NPCOL, 00802 $ WTIME( 1 ), WTIME( 2 ), TMFLOPS, 00803 $ PASSED 00804 * 00805 * Print CPU time if machine supports it 00806 * 00807 IF( CTIME( 1 )+CTIME( 2 ).GT.0.0D+0 ) THEN 00808 TMFLOPS = NOPS / 00809 $ ( ( CTIME( 1 )+CTIME( 2 ) ) * 1.0D+6 ) 00810 ELSE 00811 TMFLOPS = 0.0D+0 00812 END IF 00813 * 00814 IF( CTIME( 2 ).GE.0.0D+0 ) 00815 $ WRITE( NOUT, FMT = 9993 ) 'CPU ', UPLO, N, 00816 $ NB, NRHS, NBRHS, NPROW, NPCOL, 00817 $ CTIME( 1 ), CTIME( 2 ), TMFLOPS, 00818 $ PASSED 00819 * 00820 END IF 00821 10 CONTINUE 00822 20 CONTINUE 00823 * 00824 IF( CHECK .AND. SRESID.GT.THRESH ) THEN 00825 * 00826 * Compute FRESID = ||A - LL'|| / (||A|| * N * eps) 00827 * 00828 CALL PSPOTRRV( UPLO, N, MEM( IPA ), 1, 1, DESCA, 00829 $ MEM( IPW ) ) 00830 CALL PSLAFCHK( 'Symm', 'Diag', N, N, MEM( IPA ), 1, 1, 00831 $ DESCA, IASEED, ANORM, FRESID, 00832 $ MEM( IPW ) ) 00833 * 00834 * Check for memory overwrite 00835 * 00836 CALL PSCHEKPAD( ICTXT, 'PSPOTRRV', NP, NQ, 00837 $ MEM( IPA-IPREPAD ), DESCA( LLD_ ), 00838 $ IPREPAD, IPOSTPAD, PADVAL ) 00839 CALL PSCHEKPAD( ICTXT, 'PSGETRRV', 00840 $ WORKSIZ-IPOSTPAD, 1, 00841 $ MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD, 00842 $ IPREPAD, IPOSTPAD, PADVAL ) 00843 * 00844 IF( IAM.EQ.0 ) THEN 00845 IF( LSAME( UPLO, 'L' ) ) THEN 00846 WRITE( NOUT, FMT = 9986 ) 'L*L''', FRESID 00847 ELSE 00848 WRITE( NOUT, FMT = 9986 ) 'U''*U', FRESID 00849 END IF 00850 END IF 00851 END IF 00852 * 00853 30 CONTINUE 00854 40 CONTINUE 00855 CALL BLACS_GRIDEXIT( ICTXT ) 00856 50 CONTINUE 00857 * 00858 * Print ending messages and close output file 00859 * 00860 60 CONTINUE 00861 IF( IAM.EQ.0 ) THEN 00862 KTESTS = KPASS + KFAIL + KSKIP 00863 WRITE( NOUT, FMT = * ) 00864 WRITE( NOUT, FMT = 9992 ) KTESTS 00865 IF( CHECK ) THEN 00866 WRITE( NOUT, FMT = 9991 ) KPASS 00867 WRITE( NOUT, FMT = 9989 ) KFAIL 00868 ELSE 00869 WRITE( NOUT, FMT = 9990 ) KPASS 00870 END IF 00871 WRITE( NOUT, FMT = 9988 ) KSKIP 00872 WRITE( NOUT, FMT = * ) 00873 WRITE( NOUT, FMT = * ) 00874 WRITE( NOUT, FMT = 9987 ) 00875 IF( NOUT.NE.6 .AND. NOUT.NE.0 ) 00876 $ CLOSE ( NOUT ) 00877 END IF 00878 * 00879 CALL BLACS_EXIT( 0 ) 00880 * 00881 9999 FORMAT( 'ILLEGAL ', A6, ': ', A5, ' = ', I3, 00882 $ '; It should be at least 1' ) 00883 9998 FORMAT( 'ILLEGAL GRID: nprow*npcol = ', I4, '. It can be at most', 00884 $ I4 ) 00885 9997 FORMAT( 'Bad ', A6, ' parameters: going on to next test case.' ) 00886 9996 FORMAT( 'Unable to perform ', A, ': need TOTMEM of at least', 00887 $ I11 ) 00888 9995 FORMAT( 'TIME UPLO N NB NRHS NBRHS P Q LLt Time ', 00889 $ 'Slv Time MFLOPS CHECK' ) 00890 9994 FORMAT( '---- ---- ----- --- ---- ----- ---- ---- -------- ', 00891 $ '-------- -------- ------' ) 00892 9993 FORMAT( A4, 4X, A1, 1X, I5, 1X, I3, 1X, I4, 1X, I5, 1X, I4, 1X, 00893 $ I4, 1X, F8.2, 1X, F8.2, 1X, F8.2, 1X, A6 ) 00894 9992 FORMAT( 'Finished ', I6, ' tests, with the following results:' ) 00895 9991 FORMAT( I5, ' tests completed and passed residual checks.' ) 00896 9990 FORMAT( I5, ' tests completed without checking.' ) 00897 9989 FORMAT( I5, ' tests completed and failed residual checks.' ) 00898 9988 FORMAT( I5, ' tests skipped because of illegal input values.' ) 00899 9987 FORMAT( 'END OF TESTS.' ) 00900 9986 FORMAT( '||A - ', A4, '|| / (||A|| * N * eps) = ', G25.7 ) 00901 9985 FORMAT( '||Ax-b||/(||x||*||A||*eps*N) ', F25.7 ) 00902 * 00903 STOP 00904 * 00905 * End of PSLLTDRIVER 00906 * 00907 END