ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
pztreecomb.f
Go to the documentation of this file.
00001       SUBROUTINE PZTREECOMB( ICTXT, SCOPE, N, MINE, RDEST0, CDEST0,
00002      $                       SUBPTR )
00003 *
00004 *  -- ScaLAPACK tools routine (version 1.7) --
00005 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
00006 *     and University of California, Berkeley.
00007 *     May 1, 1997
00008 *
00009 *     .. Scalar Arguments ..
00010       CHARACTER          SCOPE
00011       INTEGER            CDEST0, ICTXT, N, RDEST0
00012 *     ..
00013 *     .. Array Arguments ..
00014       COMPLEX*16         MINE( * )
00015 *     ..
00016 *     .. Subroutine Arguments ..
00017       EXTERNAL           SUBPTR
00018 *     ..
00019 *
00020 *  Purpose
00021 *  =======
00022 *
00023 *  PZTREECOMB does a 1-tree parallel combine operation on scalars,
00024 *  using the subroutine indicated by SUBPTR to perform the required
00025 *  computation.
00026 *
00027 *  Arguments
00028 *  =========
00029 *
00030 *  ICTXT   (global input) INTEGER
00031 *          The BLACS context handle, indicating the global context of
00032 *          the operation. The context itself is global.
00033 *
00034 *  SCOPE   (global input) CHARACTER
00035 *          The scope of the operation:  'Rowwise', 'Columnwise', or
00036 *          'All'.
00037 *
00038 *  N       (global input) INTEGER
00039 *          The number of elements in MINE.  N = 1 for the norm-2
00040 *          computation and 2 for the sum of square.
00041 *
00042 *  MINE    (local input/global output) COMPLEX*16 array of
00043 *          dimension at least equal to N. The local data to use in the
00044 *          combine.
00045 *
00046 *  RDEST0  (global input) INTEGER
00047 *          The process row to receive the answer. If RDEST0 = -1,
00048 *          every process in the scope gets the answer.
00049 *
00050 *  CDEST0  (global input) INTEGER
00051 *          The process column to receive the answer. If CDEST0 = -1,
00052 *          every process in the scope gets the answer.
00053 *
00054 *  SUBPTR  (local input) Pointer to the subroutine to call to perform
00055 *          the required combine.
00056 *
00057 *  =====================================================================
00058 *
00059 *     .. Local Scalars ..
00060       LOGICAL            BCAST, RSCOPE, CSCOPE
00061       INTEGER            CMSSG, DEST, DIST, HISDIST, I, IAM, MYCOL,
00062      $                   MYROW, MYDIST, MYDIST2, NP, NPCOL, NPROW,
00063      $                   RMSSG, TCDEST, TRDEST
00064 *     ..
00065 *     .. Local Arrays ..
00066       COMPLEX*16         HIS( 2 )
00067 *     ..
00068 *     .. External Subroutines ..
00069       EXTERNAL           BLACS_GRIDINFO, ZGEBR2D, ZGEBS2D,
00070      $                   ZGERV2D, ZGESD2D
00071 *     ..
00072 *     .. External Functions ..
00073       LOGICAL            LSAME
00074       EXTERNAL           LSAME
00075 *     ..
00076 *     .. Intrinsic Functions ..
00077       INTRINSIC          MOD
00078 *     ..
00079 *     .. Executable Statements ..
00080 *
00081         DEST = 0
00082 *       
00083 *     See if everyone wants the answer (need to broadcast the answer)
00084 *
00085       BCAST = ( ( RDEST0.EQ.-1 ).OR.( CDEST0.EQ.-1 ) )
00086       IF( BCAST ) THEN
00087          TRDEST = 0
00088          TCDEST = 0
00089       ELSE
00090          TRDEST = RDEST0
00091          TCDEST = CDEST0
00092       END IF
00093 *
00094 *     Get grid parameters.
00095 *
00096       CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
00097 *
00098 *     Figure scope-dependant variables, or report illegal scope
00099 *
00100       RSCOPE = LSAME( SCOPE, 'R' )
00101       CSCOPE = LSAME( SCOPE, 'C' )
00102 *
00103       IF( RSCOPE ) THEN
00104          IF( BCAST ) THEN
00105             TRDEST = MYROW
00106          ELSE IF( MYROW.NE.TRDEST ) THEN
00107             RETURN
00108          END IF
00109          NP = NPCOL
00110          MYDIST = MOD( NPCOL + MYCOL - TCDEST, NPCOL )
00111       ELSE IF( CSCOPE ) THEN
00112          IF( BCAST ) THEN
00113             TCDEST = MYCOL
00114          ELSE IF( MYCOL.NE.TCDEST ) THEN
00115             RETURN
00116          END IF
00117          NP = NPROW
00118          MYDIST = MOD( NPROW + MYROW - TRDEST, NPROW )
00119       ELSE IF( LSAME( SCOPE, 'A' ) ) THEN
00120          NP = NPROW * NPCOL
00121          IAM = MYROW*NPCOL + MYCOL
00122          DEST = TRDEST*NPCOL + TCDEST
00123          MYDIST = MOD( NP + IAM - DEST, NP )
00124       ELSE
00125          RETURN
00126       END IF
00127 *
00128       IF( NP.LT.2 )
00129      $   RETURN
00130 *
00131       MYDIST2 = MYDIST
00132       RMSSG = MYROW
00133       CMSSG = MYCOL
00134       I = 1
00135 *
00136    10 CONTINUE
00137 *
00138          IF( MOD( MYDIST, 2 ).NE.0 ) THEN
00139 *
00140 *           If I am process that sends information
00141 *
00142             DIST = I * ( MYDIST - MOD( MYDIST, 2 ) )
00143 *
00144 *           Figure coordinates of dest of message
00145 *
00146             IF( RSCOPE ) THEN
00147                CMSSG = MOD( TCDEST + DIST, NP )
00148             ELSE IF( CSCOPE ) THEN
00149                RMSSG = MOD( TRDEST + DIST, NP )
00150             ELSE
00151                CMSSG = MOD( DEST + DIST, NP )
00152                RMSSG = CMSSG / NPCOL
00153                CMSSG = MOD( CMSSG, NPCOL )
00154             END IF
00155 *
00156             CALL ZGESD2D( ICTXT, N, 1, MINE, N, RMSSG, CMSSG )
00157 *
00158             GO TO 20
00159 *
00160          ELSE
00161 *
00162 *           If I am a process receiving information, figure coordinates
00163 *           of source of message
00164 *
00165             DIST = MYDIST2 + I
00166             IF( RSCOPE ) THEN
00167                CMSSG = MOD( TCDEST + DIST, NP )
00168                HISDIST = MOD( NP + CMSSG - TCDEST, NP )
00169             ELSE IF( CSCOPE ) THEN
00170                RMSSG = MOD( TRDEST + DIST, NP )
00171                HISDIST = MOD( NP + RMSSG - TRDEST, NP )
00172             ELSE
00173                CMSSG = MOD( DEST + DIST, NP )
00174                RMSSG = CMSSG / NPCOL
00175                CMSSG = MOD( CMSSG, NPCOL )
00176                HISDIST = MOD( NP + RMSSG*NPCOL+CMSSG - DEST, NP )
00177             END IF
00178 *
00179             IF( MYDIST2.LT.HISDIST ) THEN
00180 *
00181 *              If I have anyone sending to me
00182 *
00183                CALL ZGERV2D( ICTXT, N, 1, HIS, N, RMSSG, CMSSG )
00184                CALL SUBPTR( MINE, HIS )
00185 *
00186             END IF
00187             MYDIST = MYDIST / 2
00188 *
00189          END IF
00190          I = I * 2
00191 *
00192       IF( I.LT.NP )
00193      $   GO TO 10
00194 *
00195    20 CONTINUE
00196 *
00197       IF( BCAST ) THEN
00198          IF( MYDIST2.EQ.0 ) THEN
00199             CALL ZGEBS2D( ICTXT, SCOPE, ' ', N, 1, MINE, N )
00200          ELSE
00201             CALL ZGEBR2D( ICTXT, SCOPE, ' ', N, 1, MINE, N,
00202      $                    TRDEST, TCDEST )
00203          END IF
00204       END IF
00205 *
00206       RETURN
00207 *
00208 *     End of PZTREECOMB
00209 *
00210       END
00211 *
00212       SUBROUTINE ZCOMBAMAX( V1, V2 )
00213 *
00214 *  -- ScaLAPACK tools routine (version 1.7) --
00215 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
00216 *     and University of California, Berkeley.
00217 *     May 1, 1997
00218 *
00219 *     .. Array Arguments ..
00220       COMPLEX*16         V1( 2 ), V2( 2 )
00221 *     ..
00222 *
00223 *  Purpose
00224 *  =======
00225 *
00226 *  ZCOMBAMAX finds the element having max. absolute value as well
00227 *  as its corresponding globl index.
00228 *
00229 *  Arguments
00230 *  =========
00231 *
00232 *  V1        (local input/local output) COMPLEX*16 array of
00233 *            dimension 2.  The first maximum absolute value element and
00234 *            its global index. V1(1) = AMAX, V1(2) = INDX.
00235 *
00236 *  V2        (local input) COMPLEX*16 array of dimension 2.
00237 *            The second maximum absolute value element and its global
00238 *            index. V2(1) = AMAX, V2(2) = INDX.
00239 *
00240 *  =====================================================================
00241 *
00242 *     .. Intrinsic Functions ..
00243       INTRINSIC          ABS, DBLE, DIMAG
00244 *     ..
00245 *     .. Statement Functions ..
00246       COMPLEX*16         ZDUM
00247       DOUBLE PRECISION   CABS1
00248       CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
00249 *     ..
00250 *     .. Executable Statements ..
00251 *
00252       IF( CABS1( V1( 1 ) ).LT.CABS1( V2( 1 ) ) ) THEN
00253          V1( 1 ) = V2( 1 )
00254          V1( 2 ) = V2( 2 )
00255       END IF
00256 *
00257       RETURN
00258 *
00259 *     End of ZCOMBAMAX
00260 *
00261       END