3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          SCOPE
   11      INTEGER            CDEST0, ICTXT, N, RDEST0
   12
   13
   14      DOUBLE PRECISION   MINE( * )
   15
   16
   17      EXTERNAL           subptr
   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      LOGICAL            BCAST, RSCOPE, CSCOPE
   61      INTEGER            CMSSG, DEST, DIST, HISDIST, I, IAM, MYCOL,
   62     $                   MYROW, MYDIST, MYDIST2, NP, NPCOL, NPROW,
   63     $                   RMSSG, TCDEST, TRDEST
   64
   65
   66      DOUBLE PRECISION   HIS( 2 )
   67
   68
   69      EXTERNAL           blacs_gridinfo, dgebr2d, dgebs2d,
   70     $                   dgerv2d, dgesd2d
   71
   72
   73      LOGICAL            LSAME
   75
   76
   77      INTRINSIC          mod
   78
   79
   80
   81        dest = 0
   82
   83
   84
   85      bcast = ( ( rdest0.EQ.-1 ).OR.( cdest0.EQ.-1 ) )
   86      IF( bcast ) THEN
   87         trdest = 0
   88         tcdest = 0
   89      ELSE
   90         trdest = rdest0
   91         tcdest = cdest0
   92      END IF
   93
   94
   95
   96      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
   97
   98
   99
  100      rscope = 
lsame( scope, 
'R' )
 
  101      cscope = 
lsame( scope, 
'C' )
 
  102
  103      IF( rscope ) THEN
  104         IF( bcast ) THEN
  105            trdest = myrow
  106         ELSE IF( myrow.NE.trdest ) THEN
  107            RETURN
  108         END IF
  109         np = npcol
  110         mydist = mod( npcol + mycol - tcdest, npcol )
  111      ELSE IF( cscope ) THEN
  112         IF( bcast ) THEN
  113            tcdest = mycol
  114         ELSE IF( mycol.NE.tcdest ) THEN
  115            RETURN
  116         END IF
  117         np = nprow
  118         mydist = mod( nprow + myrow - trdest, nprow )
  119      ELSE IF( 
lsame( scope, 
'A' ) ) 
THEN 
  120         np = nprow * npcol
  121         iam = myrow*npcol + mycol
  122         dest = trdest*npcol + tcdest
  123         mydist = mod( np + iam - dest, np )
  124      ELSE
  125         RETURN
  126      END IF
  127
  128      IF( np.LT.2 )
  129     $   RETURN
  130
  131      mydist2 = mydist
  132      rmssg = myrow
  133      cmssg = mycol
  134      i = 1
  135
  136   10 CONTINUE
  137
  138         IF( mod( mydist, 2 ).NE.0 ) THEN
  139
  140
  141
  142            dist = i * ( mydist - mod( mydist, 2 ) )
  143
  144
  145
  146            IF( rscope ) THEN
  147               cmssg = mod( tcdest + dist, np )
  148            ELSE IF( cscope ) THEN
  149               rmssg = mod( trdest + dist, np )
  150            ELSE
  151               cmssg = mod( dest + dist, np )
  152               rmssg = cmssg / npcol
  153               cmssg = mod( cmssg, npcol )
  154            END IF
  155
  156            CALL dgesd2d( ictxt, n, 1, mine, n, rmssg, cmssg )
  157
  158            GO TO 20
  159
  160         ELSE
  161
  162
  163
  164
  165            dist = mydist2 + i
  166            IF( rscope ) THEN
  167               cmssg = mod( tcdest + dist, np )
  168               hisdist = mod( np + cmssg - tcdest, np )
  169            ELSE IF( cscope ) THEN
  170               rmssg = mod( trdest + dist, np )
  171               hisdist = mod( np + rmssg - trdest, np )
  172            ELSE
  173               cmssg = mod( dest + dist, np )
  174               rmssg = cmssg / npcol
  175               cmssg = mod( cmssg, npcol )
  176               hisdist = mod( np + rmssg*npcol+cmssg - dest, np )
  177            END IF
  178
  179            IF( mydist2.LT.hisdist ) THEN
  180
  181
  182
  183               CALL dgerv2d( ictxt, n, 1, his, n, rmssg, cmssg )
  184               CALL subptr( mine, his )
  185
  186            END IF
  187            mydist = mydist / 2
  188
  189         END IF
  190         i = i * 2
  191
  192      IF( i.LT.np )
  193     $   GO TO 10
  194
  195   20 CONTINUE
  196
  197      IF( bcast ) THEN
  198         IF( mydist2.EQ.0 ) THEN
  199            CALL dgebs2d( ictxt, scope, ' ', n, 1, mine, n )
  200         ELSE
  201            CALL dgebr2d( ictxt, scope, ' ', n, 1, mine, n,
  202     $                    trdest, tcdest )
  203         END IF
  204      END IF
  205
  206      RETURN
  207
  208
  209