|
ScaLAPACK
2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
|
00001 SUBROUTINE PCBMATGEN( ICTXT, AFORM, AFORM2, BWL, BWU, N, 00002 $ MB, NB, A, 00003 $ LDA, IAROW, IACOL, ISEED, 00004 $ MYROW, MYCOL, NPROW, NPCOL ) 00005 * 00006 * 00007 * 00008 * -- ScaLAPACK routine (version 1.7) -- 00009 * University of Tennessee, Knoxville, Oak Ridge National Laboratory, 00010 * and University of California, Berkeley. 00011 * November 15, 1997 00012 * 00013 * .. Scalar Arguments .. 00014 * .. Scalar Arguments .. 00015 CHARACTER*1 AFORM, AFORM2 00016 INTEGER IACOL, IAROW, ICTXT, 00017 $ ISEED, LDA, MB, MYCOL, MYROW, N, 00018 $ NB, NPCOL, NPROW, BWL, BWU 00019 * .. 00020 * .. Array Arguments .. 00021 COMPLEX A( LDA, * ) 00022 * .. 00023 * 00024 * Purpose 00025 * ======= 00026 * 00027 * PCBMATGEN : Parallel Complex Single precision Band MATrix GENerator. 00028 * (Re)Generate a distributed Band matrix A (or sub-matrix of A). 00029 * 00030 * Arguments 00031 * ========= 00032 * 00033 * ICTXT (global input) INTEGER 00034 * The BLACS context handle, indicating the global context of 00035 * the operation. The context itself is global. 00036 * 00037 * AFORM (global input) CHARACTER*1 00038 * if AFORM = 'L' : A is returned as a hermitian lower 00039 * triangular matrix, and is diagonally dominant. 00040 * if AFORM = 'U' : A is returned as a hermitian upper 00041 * triangular matrix, and is diagonally dominant. 00042 * if AFORM = 'G' : A is returned as a general matrix. 00043 * if AFORM = 'T' : A is returned as a general matrix in 00044 * tridiagonal-compatible form. 00045 * 00046 * AFORM2 (global input) CHARACTER*1 00047 * if the matrix is general: 00048 * if AFORM2 = 'D' : A is returned diagonally dominant. 00049 * if AFORM2 != 'D' : A is not returned diagonally dominant. 00050 * if the matrix is symmetric or hermitian: 00051 * if AFORM2 = 'T' : A is returned in tridiagonally-compatible 00052 * form (a transpose form). 00053 * if AFORM2 != 'T' : A is returned in banded-compatible form. 00054 * 00055 * M (global input) INTEGER 00056 * The number of nonzero rows in the generated distributed 00057 * band matrix. 00058 * 00059 * N (global input) INTEGER 00060 * The number of columns in the generated distributed 00061 * matrix. 00062 * 00063 * MB (global input) INTEGER 00064 * The row blocking factor of the distributed matrix A. 00065 * 00066 * NB (global input) INTEGER 00067 * The column blocking factor of the distributed matrix A. 00068 * 00069 * A (local output) COMPLEX, pointer into the local memory to 00070 * an array of dimension ( LDA, * ) containing the local 00071 * pieces of the distributed matrix. 00072 * 00073 * LDA (local input) INTEGER 00074 * The leading dimension of the array containing the local 00075 * pieces of the distributed matrix A. 00076 * 00077 * IAROW (global input) INTEGER 00078 * The row processor coordinate which holds the first block 00079 * of the distributed matrix A. 00080 * A( DIAG_INDEX, I ) = A( DIAG_INDEX, I ) + BWL+BWU 00081 * 00082 * IACOL (global input) INTEGER 00083 * The column processor coordinate which holds the first 00084 * block of the distributed matrix A. 00085 * 00086 * ISEED (global input) INTEGER 00087 * The seed number to generate the distributed matrix A. 00088 * 00089 * MYROW (local input) INTEGER 00090 * The row process coordinate of the calling process. 00091 * 00092 * MYCOL (local input) INTEGER 00093 * The column process coordinate of the calling process. 00094 * 00095 * NPROW (global input) INTEGER 00096 * The number of process rows in the grid. 00097 * 00098 * NPCOL (global input) INTEGER 00099 * The number of process columns in the grid. 00100 * 00101 * Notes 00102 * ===== 00103 * 00104 * This code is a simple wrapper around PCMATGEN, for band matrices. 00105 * 00106 * ===================================================================== 00107 * 00108 * Code Developer: Andrew J. Cleary, University of Tennessee. 00109 * Current address: Lawrence Livermore National Labs. 00110 * This version released: August, 2001. 00111 * 00112 * ===================================================================== 00113 * 00114 * .. 00115 * .. Parameters .. 00116 REAL ONE, ZERO 00117 PARAMETER ( ONE = 1.0E+0 ) 00118 PARAMETER ( ZERO = 0.0E+0 ) 00119 COMPLEX CONE, CZERO 00120 PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) ) 00121 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ) ) 00122 * .. 00123 * .. Local Scalars .. 00124 INTEGER DIAG_INDEX, I, J, M_MATGEN, NQ, N_MATGEN, 00125 $ START_INDEX 00126 * .. 00127 * .. External Subroutines .. 00128 EXTERNAL PCMATGEN 00129 * .. 00130 * .. External Functions .. 00131 LOGICAL LSAME 00132 INTEGER ICEIL, NUMROC 00133 EXTERNAL ICEIL, NUMROC, LSAME 00134 * .. 00135 * .. Executable Statements .. 00136 * 00137 * 00138 IF( LSAME( AFORM, 'L' ).OR.LSAME( AFORM, 'U' ) ) THEN 00139 M_MATGEN = BWL + 1 00140 N_MATGEN = N 00141 START_INDEX = 1 00142 IF( LSAME( AFORM, 'L' ) ) THEN 00143 DIAG_INDEX = 1 00144 ELSE 00145 DIAG_INDEX = BWL + 1 00146 ENDIF 00147 ELSE 00148 M_MATGEN = BWL + BWU + 1 00149 N_MATGEN = N 00150 DIAG_INDEX = BWU + 1 00151 START_INDEX = 1 00152 ENDIF 00153 * 00154 NQ = NUMROC( N, NB, MYCOL, IACOL, NPCOL ) 00155 * 00156 * 00157 * Generate a random matrix initially 00158 * 00159 IF( LSAME( AFORM, 'T' ) .OR. 00160 $ ( LSAME( AFORM2, 'T' ) ) ) THEN 00161 * 00162 CALL PCMATGEN( ICTXT, 'T', 'N', 00163 $ N_MATGEN, M_MATGEN, 00164 $ NB, M_MATGEN, A( START_INDEX, 1 ), 00165 $ LDA, IAROW, IACOL, 00166 $ ISEED, 0, NQ, 0, M_MATGEN, 00167 $ MYCOL, MYROW, NPCOL, NPROW ) 00168 * 00169 ELSE 00170 * 00171 CALL PCMATGEN( ICTXT, 'N', 'N', 00172 $ M_MATGEN, N_MATGEN, 00173 $ M_MATGEN, NB, A( START_INDEX, 1 ), 00174 $ LDA, IAROW, IACOL, 00175 $ ISEED, 0, M_MATGEN, 0, NQ, 00176 $ MYROW, MYCOL, NPROW, NPCOL ) 00177 * 00178 * Zero out padding at tops of columns 00179 * 00180 DO 1000 J=1,NB 00181 * 00182 DO 2000 I=1, LDA-M_MATGEN 00183 * 00184 * Indexing goes negative; BMATGEN assumes that space 00185 * has been preallocated above the first column as it 00186 * has to be if the matrix is to be input to 00187 * Scalapack's band solvers. 00188 * 00189 A( I-LDA+M_MATGEN, J ) = CZERO 00190 * 00191 2000 CONTINUE 00192 * 00193 1000 CONTINUE 00194 * 00195 ENDIF 00196 * 00197 IF( LSAME( AFORM2, 'D' ).OR. 00198 $ ( LSAME( AFORM, 'L' ).OR.LSAME( AFORM, 'U' ) ) ) THEN 00199 * 00200 * Loop over diagonal elements stored on this processor. 00201 * 00202 * 00203 DO 330 I=1, NQ 00204 IF( LSAME( AFORM, 'T' ) .OR. 00205 $ ( LSAME( AFORM2, 'T' ) ) ) THEN 00206 IF( NPROW .EQ. 1 ) THEN 00207 A( I, DIAG_INDEX ) = CMPLX( REAL( A( I, DIAG_INDEX ) ) 00208 $ + REAL( 2*( BWL+BWU+1 ) ) ) 00209 ENDIF 00210 ELSE 00211 IF( NPROW .EQ. 1 ) THEN 00212 A( DIAG_INDEX, I ) = CMPLX( REAL( A( DIAG_INDEX, I ) ) 00213 $ + REAL( 2*( BWL+BWU+1 ) ) ) 00214 ENDIF 00215 END IF 00216 330 CONTINUE 00217 * 00218 * 00219 ELSE 00220 * 00221 * Must add elements to keep condition of matrix in check 00222 * 00223 DO 380 I=1, NQ 00224 * 00225 IF( NPROW .EQ. 1 ) THEN 00226 * 00227 IF( MOD(I+MYCOL*NB,2) .EQ. 1 ) THEN 00228 A( DIAG_INDEX+1, I ) = 00229 $ CMPLX( REAL( A( DIAG_INDEX+1, I ) ) 00230 $ + REAL( 2*( BWL+BWU+1 ) ) ) 00231 * 00232 ELSE 00233 * 00234 A( DIAG_INDEX-1, I ) = 00235 $ CMPLX( REAL( A( DIAG_INDEX-1, I ) ) 00236 $ + REAL( 2*( BWL+BWU+1 ) ) ) 00237 ENDIF 00238 * 00239 ENDIF 00240 * 00241 380 CONTINUE 00242 * 00243 END IF 00244 * 00245 RETURN 00246 * 00247 * End of PCBMATGEN 00248 * 00249 END