| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 
 |       SUBROUTINE PBDTRGET( ICONTXT, ADIST, M, N, MNB, A, LDA, MCROW,
     $                     MCCOL, IGD, MYROW, MYCOL, NPROW, NPCOL )
*
*  -- PB-BLAS routine (version 2.1) --
*     University of Tennessee, Knoxville, Oak Ridge National Laboratory.
*     April 28, 1996
*
*     .. Scalar Arguments ..
      CHARACTER*1        ADIST
      INTEGER            ICONTXT, IGD, LDA, M, MCCOL, MCROW, MNB, MYCOL,
     $                   MYROW, N, NPCOL, NPROW
*     ..
*     .. Array Arguments ..
      DOUBLE PRECISION   A( LDA, * )
*     ..
*
*  Purpose
*  =======
*
*  PBDTRGET forms a row block of A from scattered row subblocks if
*  ADIST = 'R', or forms a column block of A from scattered column
*  subblocks,  if ADIST = 'C'.
*
*  =====================================================================
*
*     .. Parameters ..
      REAL               ONE, TWO
      PARAMETER          ( ONE = 1.0E+0, TWO = 2.0E+0 )
*     ..
*     .. Local Variables ..
      INTEGER            KINT, KINT2, KLEN, KMOD, KPPOS, NLEN, NNUM,
     $                   NTLEN
      REAL               TEMP
*     ..
*     .. External Functions ..
      LOGICAL            LSAME
      INTEGER            ICEIL, NUMROC
      EXTERNAL           LSAME,  ICEIL, NUMROC
*     ..
*     .. External Subroutines ..
      EXTERNAL           DGERV2D, DGESD2D
*     ..
*     .. Intrinsic Functions ..
      INTRINSIC          MAX, MIN, MOD
*
*     if A is a row block, it needs to communicate columnwise.
*
      IF( LSAME( ADIST, 'R' ) ) THEN
         KPPOS = MOD( NPROW+MYROW-MCROW, NPROW )
         IF( MOD( KPPOS, IGD ).EQ.0 ) THEN
            KINT = IGD
            NLEN = N
            NNUM = MIN( NPROW/IGD, MNB-MCCOL )
            TEMP = REAL( NNUM )
            NTLEN = N * NNUM
            NNUM = IGD * NNUM
            IF( KPPOS.GE.NNUM ) GO TO 30
            KPPOS = MOD( KPPOS, NPROW )
*
   10       CONTINUE
            IF( TEMP.GT.ONE ) THEN
               KINT2 = 2 * KINT
               KMOD = MOD( KPPOS, KINT2 )
*
               IF( KMOD.EQ.0 ) THEN
                  IF( KPPOS+KINT.LT.NNUM ) THEN
                     KLEN = NTLEN - (KPPOS/KINT2)*(KINT2/IGD)*N
                     KLEN = MIN( KLEN-NLEN, NLEN )
                     CALL DGERV2D( ICONTXT, M, KLEN, A(1,NLEN+1), LDA,
     $                             MOD(MYROW+KINT, NPROW), MYCOL )
                     NLEN = NLEN + KLEN
                  END IF
               ELSE
                  CALL DGESD2D( ICONTXT, M, NLEN, A, LDA,
     $                          MOD(NPROW+MYROW-KINT, NPROW), MYCOL )
                  GO TO 30
               END IF
*
               KINT = KINT2
               TEMP = TEMP / TWO
               GO TO 10
            END IF
         END IF
*
*     if A is a column block, it needs to communicate rowwise.
*
      ELSE IF( LSAME( ADIST, 'C' ) ) THEN
*
         KPPOS = MOD( NPCOL+MYCOL-MCCOL, NPCOL )
         IF( MOD( KPPOS, IGD ).EQ.0 ) THEN
            KINT = IGD
            NLEN = N
            NNUM = MIN( NPCOL/IGD, MNB-MCROW )
            TEMP = REAL( NNUM )
            NTLEN = N * NNUM
            NNUM = IGD * NNUM
            IF( KPPOS.GE.NNUM ) GO TO 30
            KPPOS = MOD( KPPOS, NPCOL )
*
   20       CONTINUE
            IF( TEMP.GT.ONE ) THEN
               KINT2 = 2 * KINT
               KMOD = MOD( KPPOS, KINT2 )
*
               IF( KMOD.EQ.0 ) THEN
                  IF( KPPOS+KINT.LT.NNUM ) THEN
                     KLEN = NTLEN - (KPPOS/KINT2)*(KINT2/IGD)*N
                     KLEN = MIN( KLEN-NLEN, NLEN )
                     CALL DGERV2D( ICONTXT, M, KLEN, A(1,NLEN+1), LDA,
     $                             MYROW, MOD(MYCOL+KINT, NPCOL) )
                     NLEN = NLEN + KLEN
                  END IF
               ELSE
                  CALL DGESD2D( ICONTXT, M, NLEN, A, LDA, MYROW,
     $                          MOD(NPCOL+MYCOL-KINT, NPCOL) )
                  GO TO 30
               END IF
*
               KINT = KINT2
               TEMP = TEMP / TWO
               GO TO 20
            END IF
         END IF
      END IF
*
   30 CONTINUE
*
      RETURN
*
*     End of PBDTRGET
*
      END
 |