ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
pctrddriver.f
Go to the documentation of this file.
00001       PROGRAM PCTRDDRIVER
00002 *
00003 *  -- ScaLAPACK testing driver (version 1.7) --
00004 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
00005 *     and University of California, Berkeley.
00006 *     October 15, 1999
00007 *
00008 *  Purpose
00009 *  ========
00010 *
00011 *  PCTRDDRIVER is the main test program for the COMPLEX
00012 *  SCALAPACK TRD (symmetric tridiagonal reduction) routines.
00013 *
00014 *  The program must be driven by a short data file.  An annotated
00015 *  example of a data file can be obtained by deleting the first 3
00016 *  characters from the following 13 lines:
00017 *  'ScaLAPACK TRD computation input file'
00018 *  'PVM machine'
00019 *  'TRD.out'       output file name
00020 *  6               device out
00021 *  'L'             define Lower or Upper
00022 *  3               number of problems sizes
00023 *  5 31 201        values of N
00024 *  3               number of NB's
00025 *  2 3 5           values of NB
00026 *  7               number of process grids (ordered pairs of P & Q)
00027 *  1 2 1 4 2 3 8   values of P
00028 *  1 2 4 1 3 2 1   values of Q
00029 *  1.0             threshold
00030 *
00031 *  Internal Parameters
00032 *  ===================
00033 *
00034 *  TOTMEM   INTEGER, default = 2000000
00035 *           TOTMEM is a machine-specific parameter indicating the
00036 *           maximum amount of available memory in bytes.
00037 *           The user should customize TOTMEM to his platform.  Remember
00038 *           to leave room in memory for the operating system, the BLACS
00039 *           buffer, etc.  For example, on a system with 8 MB of memory
00040 *           per process (e.g., one processor on an Intel iPSC/860), the
00041 *           parameters we use are TOTMEM=6200000 (leaving 1.8 MB for OS,
00042 *           code, BLACS buffer, etc).  However, for PVM, we usually set
00043 *           TOTMEM = 2000000.  Some experimenting with the maximum value
00044 *           of TOTMEM may be required.
00045 *
00046 *  INTGSZ   INTEGER, default = 4 bytes.
00047 *  CPLXSZ   INTEGER, default = 8 bytes.
00048 *           INTGSZ and CPLXSZ indicate the length in bytes on the
00049 *           given platform for an integer and a single precision
00050 *           complex.
00051 *  MEM      COMPLEX array, dimension ( TOTMEM / CPLXSZ )
00052 *
00053 *           All arrays used by SCALAPACK routines are allocated from
00054 *           this array and referenced by pointers.  The integer IPA,
00055 *           for example, is a pointer to the starting element of MEM for
00056 *           the matrix A.
00057 *
00058 *  =====================================================================
00059 *
00060 *     .. Parameters ..
00061       INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
00062      $                   LLD_, MB_, M_, NB_, N_, RSRC_
00063       PARAMETER          ( BLOCK_CYCLIC_2D = 1, DLEN_ = 9, DTYPE_ = 1,
00064      $                     CTXT_ = 2, M_ = 3, N_ = 4, MB_ = 5, NB_ = 6,
00065      $                     RSRC_ = 7, CSRC_ = 8, LLD_ = 9 )
00066       INTEGER            CPLXSZ, REALSZ, TOTMEM, MEMSIZ, NTESTS
00067       COMPLEX            PADVAL
00068       PARAMETER          ( CPLXSZ = 8, REALSZ = 4, TOTMEM = 2000000,
00069      $                   MEMSIZ = TOTMEM / CPLXSZ, NTESTS = 20,
00070      $                   PADVAL = ( -9923.0E+0, -9923.0E+0 ) )
00071 *     ..
00072 *     .. Local Scalars ..
00073       LOGICAL            CHECK
00074       CHARACTER          UPLO
00075       CHARACTER*6        PASSED
00076       CHARACTER*80       OUTFILE
00077       INTEGER            I, IAM, IASEED, ICTXT, IMIDPAD, INFO, IPA, IPD,
00078      $                   IPE, IPOSTPAD, IPREPAD, IPT, IPW, ITEMP, J, K,
00079      $                   KFAIL, KPASS, KSKIP, KTESTS, LCM, LWORK, MYCOL,
00080      $                   MYROW, N, NB, NDIAG, NGRIDS, NMAT, NNB, NOFFD,
00081      $                   NOUT, NP, NPCOL, NPROCS, NPROW, NQ, WORKSIZ,
00082      $                   WORKTRD
00083       REAL               ANORM, FRESID, THRESH
00084       DOUBLE PRECISION   NOPS, TMFLOPS
00085 *     ..
00086 *     .. Local Arrays ..
00087       INTEGER            DESCA( DLEN_ ), IERR( 1 ), NBVAL( NTESTS ),
00088      $                   NVAL( NTESTS ), PVAL( NTESTS ), QVAL( NTESTS )
00089       COMPLEX            MEM( MEMSIZ )
00090       DOUBLE PRECISION   CTIME( 1 ), WTIME( 1 )
00091 *     ..
00092 *     .. External Subroutines ..
00093       EXTERNAL           BLACS_BARRIER, BLACS_EXIT, BLACS_GET,
00094      $                   BLACS_GRIDEXIT, BLACS_GRIDINFO, BLACS_GRIDINIT,
00095      $                   BLACS_PINFO, DESCINIT, IGSUM2D, PCCHEKPAD,
00096      $                   PCFILLPAD, PCHETDRV, PCHETRD, PCLAFCHK,
00097      $                   PCMATGEN, PCTRDINFO, PCTTRDTESTER, SLBOOT,
00098      $                   SLCOMBINE, SLTIMER
00099 *     ..
00100 *     .. External Functions ..
00101       LOGICAL            LSAME
00102       INTEGER            ICEIL, ILCM, NUMROC
00103       REAL               PCLANHE
00104       EXTERNAL           LSAME, ICEIL, ILCM, NUMROC, PCLANHE
00105 *     ..
00106 *     .. Intrinsic Functions ..
00107       INTRINSIC          DBLE, MAX
00108 *     ..
00109 *     .. Data statements ..
00110       DATA               KTESTS, KPASS, KFAIL, KSKIP / 4*0 /
00111 *     ..
00112 *     .. Executable Statements ..
00113 *
00114       IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
00115      $    RSRC_.LT.0 )STOP
00116 *     Get starting information
00117 *
00118       CALL BLACS_PINFO( IAM, NPROCS )
00119       IASEED = 100
00120       CALL PCTRDINFO( OUTFILE, NOUT, UPLO, NMAT, NVAL, NTESTS, NNB,
00121      $                NBVAL, NTESTS, NGRIDS, PVAL, NTESTS, QVAL, NTESTS,
00122      $                THRESH, MEM, IAM, NPROCS )
00123       CHECK = ( THRESH.GE.0.0E+0 )
00124 *
00125 *     Print headings
00126 *
00127       IF( IAM.EQ.0 ) THEN
00128          WRITE( NOUT, FMT = * )
00129          WRITE( NOUT, FMT = 9995 )
00130          WRITE( NOUT, FMT = 9994 )
00131          WRITE( NOUT, FMT = * )
00132       END IF
00133 *
00134 *     Loop over different process grids
00135 *
00136       DO 30 I = 1, NGRIDS
00137 *
00138          NPROW = PVAL( I )
00139          NPCOL = QVAL( I )
00140 *
00141 *        Make sure grid information is correct
00142 *
00143          IERR( 1 ) = 0
00144          IF( NPROW.LT.1 ) THEN
00145             IF( IAM.EQ.0 )
00146      $         WRITE( NOUT, FMT = 9999 )'GRID', 'nprow', NPROW
00147             IERR( 1 ) = 1
00148          ELSE IF( NPCOL.LT.1 ) THEN
00149             IF( IAM.EQ.0 )
00150      $         WRITE( NOUT, FMT = 9999 )'GRID', 'npcol', NPCOL
00151             IERR( 1 ) = 1
00152          ELSE IF( NPROW*NPCOL.GT.NPROCS ) THEN
00153             IF( IAM.EQ.0 )
00154      $         WRITE( NOUT, FMT = 9998 )NPROW*NPCOL, NPROCS
00155             IERR( 1 ) = 1
00156          END IF
00157 *
00158          IF( IERR( 1 ).GT.0 ) THEN
00159             IF( IAM.EQ.0 )
00160      $         WRITE( NOUT, FMT = 9997 )'grid'
00161             KSKIP = KSKIP + 1
00162             GO TO 30
00163          END IF
00164 *
00165 *        Define process grid
00166 *
00167          CALL BLACS_GET( -1, 0, ICTXT )
00168          CALL BLACS_GRIDINIT( ICTXT, 'Row-major', NPROW, NPCOL )
00169          CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
00170 *
00171 *        Go to bottom of loop if this case doesn't use my process
00172 *
00173          IF( MYROW.GE.NPROW .OR. MYCOL.GE.NPCOL )
00174      $      GO TO 30
00175 *
00176          DO 20 J = 1, NMAT
00177 *
00178             N = NVAL( J )
00179 *
00180 *           Make sure matrix information is correct
00181 *
00182             IERR( 1 ) = 0
00183             IF( N.LT.1 ) THEN
00184                IF( IAM.EQ.0 )
00185      $            WRITE( NOUT, FMT = 9999 )'MATRIX', 'N', N
00186                IERR( 1 ) = 1
00187             END IF
00188 *
00189 *           Make sure no one had error
00190 *
00191             CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 )
00192 *
00193             IF( IERR( 1 ).GT.0 ) THEN
00194                IF( IAM.EQ.0 )
00195      $            WRITE( NOUT, FMT = 9997 )'matrix'
00196                KSKIP = KSKIP + 1
00197                GO TO 20
00198             END IF
00199 *
00200 *           Loop over different blocking sizes
00201 *
00202             DO 10 K = 1, NNB
00203 *
00204                NB = NBVAL( K )
00205 *
00206 *              Make sure nb is legal
00207 *
00208                IERR( 1 ) = 0
00209                IF( NB.LT.1 ) THEN
00210                   IERR( 1 ) = 1
00211                   IF( IAM.EQ.0 )
00212      $               WRITE( NOUT, FMT = 9999 )'NB', 'NB', NB
00213                END IF
00214 *
00215 *              Check all processes for an error
00216 *
00217                CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 )
00218 *
00219                IF( IERR( 1 ).GT.0 ) THEN
00220                   IF( IAM.EQ.0 )
00221      $               WRITE( NOUT, FMT = 9997 )'NB'
00222                   KSKIP = KSKIP + 1
00223                   GO TO 10
00224                END IF
00225 *
00226 *              Padding constants
00227 *
00228                NP = NUMROC( N, NB, MYROW, 0, NPROW )
00229                NQ = NUMROC( N, NB, MYCOL, 0, NPCOL )
00230                IF( CHECK ) THEN
00231                   IPREPAD = MAX( NB, NP )
00232                   IMIDPAD = NB
00233                   IPOSTPAD = MAX( NB, NQ )
00234                ELSE
00235                   IPREPAD = 0
00236                   IMIDPAD = 0
00237                   IPOSTPAD = 0
00238                END IF
00239 *
00240 *              Initialize the array descriptor for the matrix A
00241 *
00242                CALL DESCINIT( DESCA, N, N, NB, NB, 0, 0, ICTXT,
00243      $                        MAX( 1, NP )+IMIDPAD, IERR( 1 ) )
00244 *
00245 *              Check all processes for an error
00246 *
00247                CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 )
00248 *
00249                IF( IERR( 1 ).LT.0 ) THEN
00250                   IF( IAM.EQ.0 )
00251      $               WRITE( NOUT, FMT = 9997 )'descriptor'
00252                   KSKIP = KSKIP + 1
00253                   GO TO 10
00254                END IF
00255 *
00256 *              Assign pointers into MEM for SCALAPACK arrays, A is
00257 *              allocated starting at position MEM( IPREPAD+1 )
00258 *
00259                NDIAG = NQ
00260                IF( LSAME( UPLO, 'U' ) ) THEN
00261                   NOFFD = NQ
00262                ELSE
00263                   NOFFD = NUMROC( N-1, NB, MYCOL, 0, NPCOL )
00264                END IF
00265                NDIAG = ICEIL( REALSZ*NDIAG, CPLXSZ )
00266                NOFFD = ICEIL( REALSZ*NOFFD, CPLXSZ )
00267 *
00268                IPA = IPREPAD + 1
00269                IPD = IPA + DESCA( LLD_ )*NQ + IPOSTPAD + IPREPAD
00270                IPE = IPD + NDIAG + IPOSTPAD + IPREPAD
00271                IPT = IPE + NOFFD + IPOSTPAD + IPREPAD
00272                IPW = IPT + NQ + IPOSTPAD + IPREPAD
00273 *
00274 *              Calculate the amount of workspace required for the
00275 *              reduction
00276 *
00277                LWORK = MAX( NB*( NP+1 ), 3*NB )
00278                WORKTRD = LWORK + IPOSTPAD
00279                WORKSIZ = WORKTRD
00280 *
00281 *              Figure the amount of workspace required by the check
00282 *
00283                IF( CHECK ) THEN
00284                   ITEMP = 2*NQ + NP
00285                   IF( NPROW.NE.NPCOL ) THEN
00286                      LCM = ILCM( NPROW, NPCOL )
00287                      ITEMP = NB*ICEIL( ICEIL( NP, NB ), LCM / NPROW ) +
00288      $                       ITEMP
00289                   END IF
00290                   ITEMP = MAX( ICEIL( REALSZ*ITEMP, CPLXSZ ),
00291      $                    2*( NB+NP )*NB )
00292                   WORKSIZ = MAX( LWORK, ITEMP ) + IPOSTPAD
00293                END IF
00294 *
00295 *              Check for adequate memory for problem size
00296 *
00297                IERR( 1 ) = 0
00298                IF( IPW+WORKSIZ.GT.MEMSIZ ) THEN
00299                   IF( IAM.EQ.0 )
00300      $               WRITE( NOUT, FMT = 9996 )'Tridiagonal reduction',
00301      $               ( IPW+WORKSIZ )*CPLXSZ
00302                   IERR( 1 ) = 1
00303                END IF
00304 *
00305 *              Check all processes for an error
00306 *
00307                CALL IGSUM2D( ICTXT, 'All', ' ', 1, 1, IERR, 1, -1, 0 )
00308 *
00309                IF( IERR( 1 ).GT.0 ) THEN
00310                   IF( IAM.EQ.0 )
00311      $               WRITE( NOUT, FMT = 9997 )'MEMORY'
00312                   KSKIP = KSKIP + 1
00313                   GO TO 10
00314                END IF
00315 *
00316 *              Generate the matrix A
00317 *
00318                CALL PCMATGEN( ICTXT, 'Hemm', 'N', DESCA( M_ ),
00319      $                        DESCA( N_ ), DESCA( MB_ ), DESCA( NB_ ),
00320      $                        MEM( IPA ), DESCA( LLD_ ), DESCA( RSRC_ ),
00321      $                        DESCA( CSRC_ ), IASEED, 0, NP, 0, NQ,
00322      $                        MYROW, MYCOL, NPROW, NPCOL )
00323 *
00324 *              Need Infinity-norm of A for checking
00325 *
00326                IF( CHECK ) THEN
00327                   CALL PCFILLPAD( ICTXT, NP, NQ, MEM( IPA-IPREPAD ),
00328      $                            DESCA( LLD_ ), IPREPAD, IPOSTPAD,
00329      $                            PADVAL )
00330                   CALL PCFILLPAD( ICTXT, NDIAG, 1, MEM( IPD-IPREPAD ),
00331      $                            NDIAG, IPREPAD, IPOSTPAD, PADVAL )
00332                   CALL PCFILLPAD( ICTXT, NOFFD, 1, MEM( IPE-IPREPAD ),
00333      $                            NOFFD, IPREPAD, IPOSTPAD, PADVAL )
00334                   CALL PCFILLPAD( ICTXT, NQ, 1, MEM( IPT-IPREPAD ), NQ,
00335      $                            IPREPAD, IPOSTPAD, PADVAL )
00336                   CALL PCFILLPAD( ICTXT, WORKSIZ-IPOSTPAD, 1,
00337      $                            MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD,
00338      $                            IPREPAD, IPOSTPAD, PADVAL )
00339                   ANORM = PCLANHE( 'I', UPLO, N, MEM( IPA ), 1, 1,
00340      $                    DESCA, MEM( IPW ) )
00341                   CALL PCCHEKPAD( ICTXT, 'PCLANHE', NP, NQ,
00342      $                            MEM( IPA-IPREPAD ), DESCA( LLD_ ),
00343      $                            IPREPAD, IPOSTPAD, PADVAL )
00344                   CALL PCCHEKPAD( ICTXT, 'PCLANHE', WORKSIZ-IPOSTPAD, 1,
00345      $                            MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD,
00346      $                            IPREPAD, IPOSTPAD, PADVAL )
00347                   CALL PCFILLPAD( ICTXT, WORKTRD-IPOSTPAD, 1,
00348      $                            MEM( IPW-IPREPAD ), WORKTRD-IPOSTPAD,
00349      $                            IPREPAD, IPOSTPAD, PADVAL )
00350                END IF
00351 *
00352                CALL SLBOOT
00353                CALL BLACS_BARRIER( ICTXT, 'All' )
00354                CALL SLTIMER( 1 )
00355 *
00356 *              Reduce to symmetric tridiagonal form
00357 *
00358                CALL PCHETRD( UPLO, N, MEM( IPA ), 1, 1, DESCA,
00359      $                       MEM( IPD ), MEM( IPE ), MEM( IPT ),
00360      $                       MEM( IPW ), LWORK, INFO )
00361 *
00362                CALL SLTIMER( 1 )
00363 *
00364                IF( CHECK ) THEN
00365 *
00366 *                 Check for memory overwrite
00367 *
00368                   CALL PCCHEKPAD( ICTXT, 'PCHETRD', NP, NQ,
00369      $                            MEM( IPA-IPREPAD ), DESCA( LLD_ ),
00370      $                            IPREPAD, IPOSTPAD, PADVAL )
00371                   CALL PCCHEKPAD( ICTXT, 'PCHETRD', NDIAG, 1,
00372      $                            MEM( IPD-IPREPAD ), NDIAG, IPREPAD,
00373      $                            IPOSTPAD, PADVAL )
00374                   CALL PCCHEKPAD( ICTXT, 'PCHETRD', NOFFD, 1,
00375      $                            MEM( IPE-IPREPAD ), NOFFD, IPREPAD,
00376      $                            IPOSTPAD, PADVAL )
00377                   CALL PCCHEKPAD( ICTXT, 'PCHETRD', NQ, 1,
00378      $                            MEM( IPT-IPREPAD ), NQ, IPREPAD,
00379      $                            IPOSTPAD, PADVAL )
00380                   CALL PCCHEKPAD( ICTXT, 'PCHETRD', WORKTRD-IPOSTPAD, 1,
00381      $                            MEM( IPW-IPREPAD ), WORKTRD-IPOSTPAD,
00382      $                            IPREPAD, IPOSTPAD, PADVAL )
00383                   CALL PCFILLPAD( ICTXT, WORKSIZ-IPOSTPAD, 1,
00384      $                            MEM( IPW-IPREPAD ), WORKSIZ-IPOSTPAD,
00385      $                            IPREPAD, IPOSTPAD, PADVAL )
00386 *
00387 *                 Compute fctres = ||A - QTQ'|| / (||A|| * N * eps)
00388 *
00389                   CALL PCHETDRV( UPLO, N, MEM( IPA ), 1, 1, DESCA,
00390      $                           MEM( IPD ), MEM( IPE ), MEM( IPT ),
00391      $                           MEM( IPW ), IERR( 1 ) )
00392                   CALL PCLAFCHK( 'Hemm', 'No', N, N, MEM( IPA ), 1, 1,
00393      $                           DESCA, IASEED, ANORM, FRESID,
00394      $                           MEM( IPW ) )
00395 *
00396 *                 Check for memory overwrite
00397 *
00398                   CALL PCCHEKPAD( ICTXT, 'PCHETDRV', NP, NQ,
00399      $                            MEM( IPA-IPREPAD ), DESCA( LLD_ ),
00400      $                            IPREPAD, IPOSTPAD, PADVAL )
00401                   CALL PCCHEKPAD( ICTXT, 'PCHETDRV', NDIAG, 1,
00402      $                            MEM( IPD-IPREPAD ), NDIAG, IPREPAD,
00403      $                            IPOSTPAD, PADVAL )
00404                   CALL PCCHEKPAD( ICTXT, 'PCHETDRV', NOFFD, 1,
00405      $                            MEM( IPE-IPREPAD ), NOFFD, IPREPAD,
00406      $                            IPOSTPAD, PADVAL )
00407                   CALL PCCHEKPAD( ICTXT, 'PCHETDRV', WORKSIZ-IPOSTPAD,
00408      $                            1, MEM( IPW-IPREPAD ),
00409      $                            WORKSIZ-IPOSTPAD, IPREPAD, IPOSTPAD,
00410      $                            PADVAL )
00411 *
00412 *                 Test residual and detect NaN result
00413 *
00414                   IF( FRESID.LE.THRESH .AND. FRESID-FRESID.EQ.
00415      $                0.0E+0 .AND. IERR( 1 ).EQ.0 ) THEN
00416                      KPASS = KPASS + 1
00417                      PASSED = 'PASSED'
00418                   ELSE
00419                      IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 )
00420      $                  WRITE( NOUT, FMT = 9986 )FRESID
00421                      KFAIL = KFAIL + 1
00422                      PASSED = 'FAILED'
00423                   END IF
00424 *
00425                   IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 .AND. IERR( 1 ).NE.0 )
00426      $               WRITE( NOUT, FMT = * )'D or E copies incorrect ...'
00427                ELSE
00428 *
00429 *                 Don't perform the checking, only the timing operation
00430 *
00431                   KPASS = KPASS + 1
00432                   FRESID = FRESID - FRESID
00433                   PASSED = 'BYPASS'
00434                END IF
00435 *
00436 *              Gather maximum of all CPU and WALL clock timings
00437 *
00438                CALL SLCOMBINE( ICTXT, 'All', '>', 'W', 1, 1, WTIME )
00439                CALL SLCOMBINE( ICTXT, 'All', '>', 'C', 1, 1, CTIME )
00440 *
00441 *              Print results
00442 *
00443                IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN
00444 *
00445 *                 TRD requires 16/3 N^3 floating point operations
00446 *
00447                   NOPS = DBLE( N )
00448 *
00449                   NOPS = ( 4.0D+0 / 3.0D+0 )*NOPS**3
00450                   NOPS = NOPS / 1.0D+6
00451 *
00452 *                 Print WALL time
00453 *
00454                   IF( WTIME( 1 ).GT.0.0D+0 ) THEN
00455                      TMFLOPS = NOPS / WTIME( 1 )
00456                   ELSE
00457                      TMFLOPS = 0.0D+0
00458                   END IF
00459                   IF( WTIME( 1 ).GE.0.0D+0 )
00460      $               WRITE( NOUT, FMT = 9993 )'WALL', UPLO, N, NB,
00461      $               NPROW, NPCOL, WTIME( 1 ), TMFLOPS, FRESID, PASSED
00462 *
00463 *                 Print CPU time
00464 *
00465                   IF( CTIME( 1 ).GT.0.0D+0 ) THEN
00466                      TMFLOPS = NOPS / CTIME( 1 )
00467                   ELSE
00468                      TMFLOPS = 0.0D+0
00469                   END IF
00470                   IF( CTIME( 1 ).GE.0.0D+0 )
00471      $               WRITE( NOUT, FMT = 9993 )'CPU ', UPLO, N, NB,
00472      $               NPROW, NPCOL, CTIME( 1 ), TMFLOPS, FRESID, PASSED
00473                END IF
00474    10       CONTINUE
00475    20    CONTINUE
00476 *
00477          CALL BLACS_GRIDEXIT( ICTXT )
00478    30 CONTINUE
00479 *
00480       CALL PCTTRDTESTER( IAM, NPROCS, CHECK, NOUT, THRESH, NVAL, NMAT,
00481      $                   MEM, TOTMEM, KPASS, KFAIL, KSKIP )
00482 *
00483 *     Print ending messages and close output file
00484 *
00485       IF( IAM.EQ.0 ) THEN
00486          KTESTS = KPASS + KFAIL + KSKIP
00487          WRITE( NOUT, FMT = * )
00488          WRITE( NOUT, FMT = 9992 )KTESTS
00489          IF( CHECK ) THEN
00490             WRITE( NOUT, FMT = 9991 )KPASS
00491             WRITE( NOUT, FMT = 9989 )KFAIL
00492          ELSE
00493             WRITE( NOUT, FMT = 9990 )KPASS
00494          END IF
00495          WRITE( NOUT, FMT = 9988 )KSKIP
00496          WRITE( NOUT, FMT = * )
00497          WRITE( NOUT, FMT = * )
00498          WRITE( NOUT, FMT = 9987 )
00499          IF( NOUT.NE.6 .AND. NOUT.NE.0 )
00500      $      CLOSE ( NOUT )
00501       END IF
00502 *
00503       CALL BLACS_EXIT( 0 )
00504 *
00505  9999 FORMAT( 'ILLEGAL ', A6, ': ', A5, ' = ', I3,
00506      $      '; It should be at least 1' )
00507  9998 FORMAT( 'ILLEGAL GRID: nprow*npcol = ', I4, '. It can be at most',
00508      $      I4 )
00509  9997 FORMAT( 'Bad ', A6, ' parameters: going on to next test case.' )
00510  9996 FORMAT( 'Unable to perform ', A, ': need TOTMEM of at least',
00511      $      I11 )
00512  9995 FORMAT( 'TIME UPLO      N  NB     P     Q  TRD Time ',
00513      $      '     MFLOPS Residual  CHECK' )
00514  9994 FORMAT( '---- ---- ------ --- ----- ----- --------- ',
00515      $      '----------- -------- ------' )
00516  9993 FORMAT( A4, 1X, A4, 1X, I6, 1X, I3, 1X, I5, 1X, I5, 1X, F9.2, 1X,
00517      $      F11.2, 1X, F8.2, 1X, A6 )
00518  9992 FORMAT( 'Finished', I4, ' tests, with the following results:' )
00519  9991 FORMAT( I5, ' tests completed and passed residual checks.' )
00520  9990 FORMAT( I5, ' tests completed without checking.' )
00521  9989 FORMAT( I5, ' tests completed and failed residual checks.' )
00522  9988 FORMAT( I5, ' tests skipped because of illegal input values.' )
00523  9987 FORMAT( 'END OF TESTS.' )
00524  9986 FORMAT( '||A - Q*T*Q''|| / (||A|| * N * eps) = ', G25.7 )
00525 *
00526       STOP
00527 *
00528 *     End of PCTRDDRIVER
00529 *
00530       END