|
ScaLAPACK
2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
|
00001 * 00002 * 00003 SUBROUTINE PDGSEPCHK( IBTYPE, MS, NV, A, IA, JA, DESCA, B, IB, JB, 00004 $ DESCB, THRESH, Q, IQ, JQ, DESCQ, C, IC, JC, 00005 $ DESCC, W, WORK, LWORK, TSTNRM, RESULT ) 00006 * 00007 * -- ScaLAPACK routine (version 1.7) -- 00008 * University of Tennessee, Knoxville, Oak Ridge National Laboratory, 00009 * and University of California, Berkeley. 00010 * April 15, 1997 00011 * 00012 * .. Scalar Arguments .. 00013 INTEGER IA, IB, IBTYPE, IC, IQ, JA, JB, JC, JQ, LWORK, 00014 $ MS, NV, RESULT 00015 DOUBLE PRECISION THRESH, TSTNRM 00016 * .. 00017 * .. Array Arguments .. 00018 * 00019 INTEGER DESCA( * ), DESCB( * ), DESCC( * ), DESCQ( * ) 00020 DOUBLE PRECISION A( * ), B( * ), C( * ), Q( * ), W( * ), 00021 $ WORK( * ) 00022 * .. 00023 * 00024 * 00025 * Purpose 00026 * ======= 00027 * 00028 * PDGSEPCHK checks a decomposition of the form 00029 * 00030 * A Q = B Q D or 00031 * A B Q = Q D or 00032 * B A Q = Q D 00033 * 00034 * where A is a symmetric matrix, B is 00035 * symmetric positive definite, Q is orthogonal, and D is diagonal. 00036 * 00037 * One of the following test ratios is computed: 00038 * 00039 * IBTYPE = 1: TSTNRM = | A Q - B Q D | / ( |A| |Q| n ulp ) 00040 * 00041 * IBTYPE = 2: TSTNRM = | A B Q - Q D | / ( |A| |Q| n ulp ) 00042 * 00043 * IBTYPE = 3: TSTNRM = | B A Q - Q D | / ( |A| |Q| n ulp ) 00044 * 00045 * 00046 * Notes 00047 * ===== 00048 * 00049 * 00050 * Each global data object is described by an associated description 00051 * vector. This vector stores the information required to establish 00052 * the mapping between an object element and its corresponding process 00053 * and memory location. 00054 * 00055 * Let A be a generic term for any 2D block cyclicly distributed array. 00056 * Such a global array has an associated description vector DESCA. 00057 * In the following comments, the character _ should be read as 00058 * "of the global array". 00059 * 00060 * NOTATION STORED IN EXPLANATION 00061 * --------------- -------------- -------------------------------------- 00062 * DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case, 00063 * DTYPE_A = 1. 00064 * CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating 00065 * the BLACS process grid A is distribu- 00066 * ted over. The context itself is glo- 00067 * bal, but the handle (the integer 00068 * value) may vary. 00069 * M_A (global) DESCA( M_ ) The number of rows in the global 00070 * array A. 00071 * N_A (global) DESCA( N_ ) The number of columns in the global 00072 * array A. 00073 * MB_A (global) DESCA( MB_ ) The blocking factor used to distribute 00074 * the rows of the array. 00075 * NB_A (global) DESCA( NB_ ) The blocking factor used to distribute 00076 * the columns of the array. 00077 * RSRC_A (global) DESCA( RSRC_ ) The process row over which the first 00078 * row of the array A is distributed. 00079 * CSRC_A (global) DESCA( CSRC_ ) The process column over which the 00080 * first column of the array A is 00081 * distributed. 00082 * LLD_A (local) DESCA( LLD_ ) The leading dimension of the local 00083 * array. LLD_A >= MAX(1,LOCr(M_A)). 00084 * 00085 * Let K be the number of rows or columns of a distributed matrix, 00086 * and assume that its process grid has dimension p x q. 00087 * LOCr( K ) denotes the number of elements of K that a process 00088 * would receive if K were distributed over the p processes of its 00089 * process column. 00090 * Similarly, LOCc( K ) denotes the number of elements of K that a 00091 * process would receive if K were distributed over the q processes of 00092 * its process row. 00093 * The values of LOCr() and LOCc() may be determined via a call to the 00094 * ScaLAPACK tool function, NUMROC: 00095 * LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ), 00096 * LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ). 00097 * An upper bound for these quantities may be computed by: 00098 * LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A 00099 * LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A 00100 * 00101 * 00102 * Arguments 00103 * ========= 00104 * 00105 * MP = number of local rows in A, B and Q 00106 * MQ = number of local columns in A 00107 * NQ = number of local columns in B and Q 00108 * 00109 * IBTYPE (input) INTEGER 00110 * The form of the symmetric generalized eigenproblem. 00111 * = 1: A*Q = (lambda)*B*Q 00112 * = 2: A*B*Q = (lambda)*Q 00113 * = 3: B*A*Q = (lambda)*Q 00114 * 00115 * MS (global input) INTEGER 00116 * Matrix size. 00117 * The number of global rows in A, B, C and Q 00118 * Also, the number of columns in A 00119 * 00120 * NV (global input) INTEGER 00121 * Number of eigenvectors 00122 * The number of global columns in C and Q. 00123 * 00124 * A (local input) REAL pointer to an 00125 * array in local memory of dimension (LLD_A, LOCc(JA+N-1)). 00126 * This array contains the local pieces of the M-by-N 00127 * distributed test matrix A 00128 * 00129 * IA (global input) INTEGER 00130 * A's global row index, which points to the beginning of the 00131 * submatrix which is to be operated on. 00132 * 00133 * JA (global input) INTEGER 00134 * A's global column index, which points to the beginning of 00135 * the submatrix which is to be operated on. 00136 * 00137 * DESCA (global and local input) INTEGER array of dimension 8 00138 * The array descriptor for the distributed matrix A. 00139 * 00140 * B (local input) REAL pointer to an 00141 * array in local memory of dimension (LLD_B, LOCc(JB+N-1)). 00142 * This array contains the local pieces of the M-by-N 00143 * distributed test matrix B 00144 * 00145 * IB (global input) INTEGER 00146 * B's global row index, which points to the beginning of the 00147 * submatrix which is to be operated on. 00148 * 00149 * JB (global input) INTEGER 00150 * B's global column index, which points to the beginning of 00151 * the submatrix which is to be operated on. 00152 * 00153 * DESCB (global and local input) INTEGER array of dimension 8 00154 * The array descriptor for the distributed matrix B. 00155 * 00156 * THRESH (input) REAL 00157 * A test will count as "failed" if the "error", computed as 00158 * described below, exceeds THRESH. Note that the error 00159 * is scaled to be O(1), so THRESH should be a reasonably 00160 * small multiple of 1, e.g., 10 or 100. In particular, 00161 * it should not depend on the precision (single vs. double) 00162 * or the size of the matrix. It must be at least zero. 00163 * 00164 * Q (local input) REAL array 00165 * global dimension (MS, NV), 00166 * local dimension (DESCA( DLEN_ ), NQ) 00167 * 00168 * Contains the eigenvectors as computed by PSSYEVX 00169 * 00170 * IQ (global input) INTEGER 00171 * Q's global row index, which points to the beginning of the 00172 * submatrix which is to be operated on. 00173 * 00174 * JQ (global input) INTEGER 00175 * Q's global column index, which points to the beginning of 00176 * the submatrix which is to be operated on. 00177 * 00178 * DESCQ (global and local input) INTEGER array of dimension 8 00179 * The array descriptor for the distributed matrix Q. 00180 * 00181 * C (local workspace) REAL array, 00182 * global dimension (MS, NV), 00183 * local dimension (DESCA( DLEN_ ), MQ) 00184 * 00185 * Accumulator for computing AQ -QL 00186 * 00187 * IC (global input) INTEGER 00188 * C's global row index, which points to the beginning of the 00189 * submatrix which is to be operated on. 00190 * 00191 * JC (global input) INTEGER 00192 * C's global column index, which points to the beginning of 00193 * the submatrix which is to be operated on. 00194 * 00195 * DESCC (global and local input) INTEGER array of dimension 8 00196 * The array descriptor for the distributed matrix C. 00197 * 00198 * W (global input) REAL array, dimension (NV) 00199 * 00200 * Contains the computed eigenvalues 00201 * 00202 * WORK (local workspace) REAL array, 00203 * dimension (LWORK) 00204 * 00205 * LWORK (local input) INTEGER 00206 * The length of the array WORK. 00207 * LWORK >= NUMROC( NV, DESCA( NB_ ), MYCOL, 0, NPCOL ) 00208 * 00209 * TSTNRM (global output) REAL 00210 * 00211 * RESULT (global output) INTEGER 00212 * 0 if the test passes 00213 * 1 if the test fails 00214 * 00215 * .. Local Scalars .. 00216 * 00217 INTEGER I, INFO, MYCOL, MYROW, NPCOL, NPROW, NQ 00218 DOUBLE PRECISION ANORM, ULP 00219 * .. 00220 * .. Parameters .. 00221 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_, 00222 $ MB_, NB_, RSRC_, CSRC_, LLD_ 00223 PARAMETER ( BLOCK_CYCLIC_2D = 1, DLEN_ = 9, DTYPE_ = 1, 00224 $ CTXT_ = 2, M_ = 3, N_ = 4, MB_ = 5, NB_ = 6, 00225 $ RSRC_ = 7, CSRC_ = 8, LLD_ = 9 ) 00226 DOUBLE PRECISION ONE, ZERO 00227 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) 00228 DOUBLE PRECISION CONE, CNEGONE, CZERO 00229 PARAMETER ( CONE = 1.0D+0, CNEGONE = -1.0D+0, 00230 $ CZERO = 0.0D+0 ) 00231 * .. 00232 * .. External Functions .. 00233 INTEGER NUMROC 00234 DOUBLE PRECISION DLAMCH, PDLANGE 00235 EXTERNAL NUMROC, DLAMCH, PDLANGE 00236 * .. 00237 * .. External Subroutines .. 00238 EXTERNAL BLACS_GRIDINFO, CHK1MAT, PDGEMM, PDSCAL, 00239 $ PXERBLA 00240 * .. 00241 * .. Intrinsic Functions .. 00242 INTRINSIC MAX 00243 * .. 00244 * .. Executable Statements .. 00245 * This is just to keep ftnchek happy 00246 IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_* 00247 $ RSRC_.LT.0 )RETURN 00248 * 00249 RESULT = 0 00250 * 00251 CALL BLACS_GRIDINFO( DESCA( CTXT_ ), NPROW, NPCOL, MYROW, MYCOL ) 00252 * 00253 INFO = 0 00254 CALL CHK1MAT( MS, 1, MS, 2, IA, JA, DESCA, 7, INFO ) 00255 CALL CHK1MAT( MS, 1, MS, 2, IB, JB, DESCB, 11, INFO ) 00256 CALL CHK1MAT( MS, 1, NV, 2, IQ, JQ, DESCQ, 16, INFO ) 00257 CALL CHK1MAT( MS, 1, NV, 2, IB, JB, DESCB, 20, INFO ) 00258 * 00259 IF( INFO.EQ.0 ) THEN 00260 * 00261 NQ = NUMROC( NV, DESCA( NB_ ), MYCOL, 0, NPCOL ) 00262 * 00263 IF( IQ.NE.1 ) THEN 00264 INFO = -14 00265 ELSE IF( JQ.NE.1 ) THEN 00266 INFO = -15 00267 ELSE IF( IA.NE.1 ) THEN 00268 INFO = -5 00269 ELSE IF( JA.NE.1 ) THEN 00270 INFO = -6 00271 ELSE IF( IB.NE.1 ) THEN 00272 INFO = -9 00273 ELSE IF( JB.NE.1 ) THEN 00274 INFO = -10 00275 ELSE IF( LWORK.LT.NQ ) THEN 00276 INFO = -23 00277 END IF 00278 END IF 00279 * 00280 IF( INFO.NE.0 ) THEN 00281 CALL PXERBLA( DESCA( CTXT_ ), 'PDGSEPCHK', -INFO ) 00282 RETURN 00283 END IF 00284 * 00285 RESULT = 0 00286 ULP = DLAMCH( 'Epsilon' ) 00287 * 00288 * Compute product of Max-norms of A and Q. 00289 * 00290 ANORM = PDLANGE( 'M', MS, MS, A, IA, JA, DESCA, WORK )* 00291 $ PDLANGE( 'M', MS, NV, Q, IQ, JQ, DESCQ, WORK ) 00292 IF( ANORM.EQ.ZERO ) 00293 $ ANORM = ONE 00294 * 00295 IF( IBTYPE.EQ.1 ) THEN 00296 * 00297 * Norm of AQ - BQD 00298 * 00299 * C = AQ 00300 * 00301 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, A, IA, JA, DESCA, Q, 00302 $ IQ, JQ, DESCQ, CZERO, C, IC, JC, DESCC ) 00303 * 00304 * Q = QD 00305 * 00306 DO 10 I = 1, NV 00307 CALL PDSCAL( MS, W( I ), Q, IQ, JQ+I-1, DESCQ, 1 ) 00308 10 CONTINUE 00309 * 00310 * C = C - BQ (i.e. AQ-BQD) 00311 * 00312 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, B, IB, JB, DESCB, Q, 00313 $ IQ, JQ, DESCQ, CNEGONE, C, IC, JC, DESCC ) 00314 * 00315 TSTNRM = ( PDLANGE( 'M', MS, NV, C, IC, JC, DESCC, WORK ) / 00316 $ ANORM ) / ( MAX( MS, 1 )*ULP ) 00317 * 00318 * 00319 ELSE IF( IBTYPE.EQ.2 ) THEN 00320 * 00321 * Norm of ABQ - QD 00322 * 00323 * 00324 * C = BQ 00325 * 00326 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, B, IB, JB, DESCB, Q, 00327 $ IQ, JQ, DESCQ, CZERO, C, IC, JC, DESCC ) 00328 * 00329 * Q = QD 00330 * 00331 DO 20 I = 1, NV 00332 CALL PDSCAL( MS, W( I ), Q, IQ, JQ+I-1, DESCQ, 1 ) 00333 20 CONTINUE 00334 * 00335 * Q = AC - Q 00336 * 00337 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, A, IA, JA, DESCA, C, 00338 $ IC, JC, DESCC, CNEGONE, Q, IQ, JQ, DESCQ ) 00339 * 00340 TSTNRM = ( PDLANGE( 'M', MS, NV, Q, IQ, JQ, DESCQ, WORK ) / 00341 $ ANORM ) / ( MAX( MS, 1 )*ULP ) 00342 * 00343 ELSE IF( IBTYPE.EQ.3 ) THEN 00344 * 00345 * Norm of BAQ - QD 00346 * 00347 * 00348 * C = AQ 00349 * 00350 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, A, IA, JA, DESCA, Q, 00351 $ IQ, JQ, DESCQ, CZERO, C, IC, JC, DESCC ) 00352 * 00353 * Q = QD 00354 * 00355 DO 30 I = 1, NV 00356 CALL PDSCAL( MS, W( I ), Q, IQ, JQ+I-1, DESCQ, 1 ) 00357 30 CONTINUE 00358 * 00359 * Q = BC - Q 00360 * 00361 CALL PDGEMM( 'N', 'N', MS, NV, MS, CONE, B, IB, JB, DESCB, C, 00362 $ IC, JC, DESCC, CNEGONE, Q, IQ, JQ, DESCQ ) 00363 * 00364 TSTNRM = ( PDLANGE( 'M', MS, NV, Q, IQ, JQ, DESCQ, WORK ) / 00365 $ ANORM ) / ( MAX( MS, 1 )*ULP ) 00366 * 00367 END IF 00368 * 00369 IF( TSTNRM.GT.THRESH .OR. ( TSTNRM-TSTNRM.NE.0.0D0 ) ) THEN 00370 RESULT = 1 00371 END IF 00372 RETURN 00373 * 00374 * End of PDGSEPCHK 00375 * 00376 END